atomic_admin 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +16 -0
- data/Rakefile +8 -0
- data/app/controllers/atomic_admin/application_controller.rb +23 -0
- data/app/controllers/atomic_admin/atomic_lti_install_controller.rb +36 -0
- data/app/controllers/atomic_admin/atomic_lti_platform_controller.rb +43 -0
- data/app/controllers/atomic_admin/atomic_tenant_client_id_strategy_controller.rb +54 -0
- data/app/controllers/atomic_admin/atomic_tenant_deployment_controller.rb +76 -0
- data/app/controllers/atomic_admin/atomic_tenant_platform_guid_strategy_controller.rb +54 -0
- data/app/jobs/atomic_admin/application_job.rb +4 -0
- data/app/mailers/atomic_admin/application_mailer.rb +6 -0
- data/app/models/atomic_admin/application_record.rb +5 -0
- data/config/routes.rb +13 -0
- data/lib/atomic_admin/engine.rb +6 -0
- data/lib/atomic_admin/jwt_token.rb +81 -0
- data/lib/atomic_admin/version.rb +3 -0
- data/lib/atomic_admin.rb +7 -0
- data/lib/tasks/atomic_admin_tasks.rake +4 -0
- metadata +78 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 8ed8016c6474ebe66207d09ec1c66e42da12989c862dd1b7cdab433f8556b717
|
4
|
+
data.tar.gz: f6e57e1aa7917a06ce6854c2edcf77310526a402f5f709d43462bd45936e2e6e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 106d1dd8d2682945e602ac85eb5eab431f8fff57f83f9849e36a99c50b0cd462e50607afef5e2eb9889683b8009eef30db0ce6dca61bada38edd7f83d20983d0
|
7
|
+
data.tar.gz: 8ddda300ce1e5d949349c8ac20802153236a3742bff41cff35ea31500fb5b5502606f0df544e2dfe006b766ba02e847d85fd2d74c845565cf135e3b32f890a82
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2022 Atomic Jolt
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# atomic_admin
|
2
|
+
Engine to provide apis that power the atomic jolt admin app
|
3
|
+
|
4
|
+
# Usage
|
5
|
+
|
6
|
+
Add the gem to your project:
|
7
|
+
gem 'atomic_admin', git: 'https://github.com/atomicjolt/atomic_admin.git', tag: '0.1.0'
|
8
|
+
|
9
|
+
Add the following to routes.rb:
|
10
|
+
```
|
11
|
+
namespace :api do
|
12
|
+
namespace :admin do
|
13
|
+
mount AtomicAdmin::Engine => "/"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module AtomicAdmin
|
2
|
+
class ApplicationController < ActionController::API
|
3
|
+
include AtomicAdmin::JwtToken
|
4
|
+
# before_action :authenticate_user! # Use validate_token instead for now
|
5
|
+
before_action :validate_admin_app_token
|
6
|
+
before_action :validate_token
|
7
|
+
before_action :only_admins!
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def only_admins!
|
12
|
+
return if @admin_app_validated
|
13
|
+
|
14
|
+
user_not_authorized unless current_user.admin?
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
def user_not_authorized(message = "Not Authorized")
|
19
|
+
render json: { message: message, }, status: 401
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module AtomicAdmin
|
2
|
+
class AtomicLtiInstallController < ApplicationController
|
3
|
+
def install_params
|
4
|
+
params.permit(:iss, :client_id)
|
5
|
+
end
|
6
|
+
|
7
|
+
def find_install
|
8
|
+
AtomicLti::Install.find_by(id: params[:id])
|
9
|
+
end
|
10
|
+
|
11
|
+
def index
|
12
|
+
render json: AtomicLti::Install.all.order(:id).paginate(page: params[:page], per_page: 30)
|
13
|
+
end
|
14
|
+
|
15
|
+
def create
|
16
|
+
AtomicLti::Install.create!(install_params)
|
17
|
+
end
|
18
|
+
|
19
|
+
def show
|
20
|
+
install = find_install
|
21
|
+
render json: install
|
22
|
+
end
|
23
|
+
|
24
|
+
def update
|
25
|
+
install = find_install
|
26
|
+
result = install.update!(install_params)
|
27
|
+
render json: result
|
28
|
+
end
|
29
|
+
|
30
|
+
def destroy
|
31
|
+
install = find_install
|
32
|
+
install.destroy
|
33
|
+
render json: install
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module AtomicAdmin
|
2
|
+
class AtomicLtiPlatformController < ApplicationController
|
3
|
+
def platform_params
|
4
|
+
params.permit(:iss, :jwks_url, :token_url, :oidc_url)
|
5
|
+
end
|
6
|
+
|
7
|
+
def find_platform
|
8
|
+
AtomicLti::Platform.find_by(id: params[:id])
|
9
|
+
end
|
10
|
+
|
11
|
+
def index
|
12
|
+
page = AtomicLti::Platform.all.order(:id).paginate(page: params[:page], per_page: 30)
|
13
|
+
|
14
|
+
render json: {
|
15
|
+
platforms: page,
|
16
|
+
page: params[:page],
|
17
|
+
total_pages: page.total_pages
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def create
|
22
|
+
platform = AtomicLti::Platform.create!(platform_params)
|
23
|
+
render json: { platform: platform }
|
24
|
+
end
|
25
|
+
|
26
|
+
def show
|
27
|
+
platform = find_platform
|
28
|
+
render json: platform
|
29
|
+
end
|
30
|
+
|
31
|
+
def update
|
32
|
+
platform = find_platform
|
33
|
+
platform.update!(platform_params)
|
34
|
+
render json: { platform: find_platform }
|
35
|
+
end
|
36
|
+
|
37
|
+
def destroy
|
38
|
+
platform = find_platform
|
39
|
+
platform.destroy
|
40
|
+
render json: platform
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module AtomicAdmin
|
2
|
+
class AtomicTenantClientIdStrategyController < ApplicationController
|
3
|
+
def pinned_client_id_params
|
4
|
+
params.permit(:iss, :client_id, :application_instance_id)
|
5
|
+
end
|
6
|
+
|
7
|
+
def find_pinned_client_id
|
8
|
+
AtomicTenant::PinnedClientId.find_by(id: params[:id])
|
9
|
+
end
|
10
|
+
|
11
|
+
def search
|
12
|
+
page = AtomicTenant::PinnedClientId
|
13
|
+
.where(application_instance_id: params[:application_instance_id])
|
14
|
+
.order(:id).paginate(page: params[:page], per_page: 30)
|
15
|
+
render json: {
|
16
|
+
pinned_client_ids: page,
|
17
|
+
page: params[:page],
|
18
|
+
total_pages: page.total_pages
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
# def index
|
23
|
+
# page = AtomicTenant::PinnedClientId.all.order(:id).paginate(page: params[:page], per_page: 30)
|
24
|
+
# render json: {
|
25
|
+
# pinned_client_ids: page,
|
26
|
+
# page: params[:page],
|
27
|
+
# total_pages: page.total_pages
|
28
|
+
# }
|
29
|
+
# end
|
30
|
+
|
31
|
+
def create
|
32
|
+
result = AtomicTenant::PinnedClientId.create!(pinned_client_id_params)
|
33
|
+
render json: { pinned_client_id: result }
|
34
|
+
end
|
35
|
+
|
36
|
+
def show
|
37
|
+
pinned_client_id = find_pinned_client_id
|
38
|
+
render json: {pinned_client_id: pinned_client_id}
|
39
|
+
end
|
40
|
+
|
41
|
+
# def update
|
42
|
+
# pinned_client_id = find_pinned_client_id
|
43
|
+
# pinned_client_id.update!(pinned_client_id_params)
|
44
|
+
|
45
|
+
# render json: {pinned_client_id: find_pinned_client_id}
|
46
|
+
# end
|
47
|
+
|
48
|
+
def destroy
|
49
|
+
pinned_client_id = find_pinned_client_id
|
50
|
+
pinned_client_id.destroy
|
51
|
+
render json: { pinned_client_id: pinned_client_id }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module AtomicAdmin
|
2
|
+
class AtomicTenantDeploymentController < ApplicationController
|
3
|
+
def deployment_params
|
4
|
+
params.permit(:iss, :deployment_id, :application_instance_id)
|
5
|
+
end
|
6
|
+
|
7
|
+
def find_deployment
|
8
|
+
AtomicTenant::LtiDeployment.find_by(id: params[:id])
|
9
|
+
end
|
10
|
+
|
11
|
+
def search
|
12
|
+
tenant_deployments = AtomicTenant::LtiDeployment
|
13
|
+
.where(application_instance_id: params[:application_instance_id])
|
14
|
+
.order(:id)
|
15
|
+
.paginate(page: params[:page], per_page: 30)
|
16
|
+
|
17
|
+
page_ids = tenant_deployments.pluck(:iss, :deployment_id)
|
18
|
+
|
19
|
+
pairs = page_ids.reduce({}) do |acc, c|
|
20
|
+
iss = c[0]
|
21
|
+
deployment_id = c[1]
|
22
|
+
|
23
|
+
acc[iss] = [] if acc[iss].nil?
|
24
|
+
|
25
|
+
acc[iss].push(deployment_id)
|
26
|
+
acc
|
27
|
+
end
|
28
|
+
|
29
|
+
page = pairs.reduce([]) do |acc, pair|
|
30
|
+
iss = pair[0]
|
31
|
+
deployment_ids = pair[1]
|
32
|
+
|
33
|
+
deployments = AtomicLti.get_deployments(iss: iss, deployment_ids: deployment_ids)
|
34
|
+
acc.concat(deployments)
|
35
|
+
end
|
36
|
+
|
37
|
+
render json: {
|
38
|
+
deployments: page,
|
39
|
+
page: params[:page],
|
40
|
+
total_pages: tenant_deployments.total_pages
|
41
|
+
}
|
42
|
+
end
|
43
|
+
|
44
|
+
# def index
|
45
|
+
# page = AtomicTenant::LtiDeployment.all.order(:id).paginate(page: params[:page], per_page: 30)
|
46
|
+
# render json: {
|
47
|
+
# deployments: page,
|
48
|
+
# page: params[:page],
|
49
|
+
# total_pages: page.total_pages
|
50
|
+
# }
|
51
|
+
# end
|
52
|
+
|
53
|
+
def create
|
54
|
+
result = AtomicTenant::LtiDeployment.create!(deployment_params)
|
55
|
+
render json: { deployment: result }
|
56
|
+
end
|
57
|
+
|
58
|
+
def show
|
59
|
+
deployment = find_deployment
|
60
|
+
render json: { deployment: deployment }
|
61
|
+
end
|
62
|
+
|
63
|
+
# def update
|
64
|
+
# deployment = find_deployment
|
65
|
+
# deployment.update!(deployment_params)
|
66
|
+
|
67
|
+
# render json: {deployment: find_deployment}
|
68
|
+
# end
|
69
|
+
|
70
|
+
def destroy
|
71
|
+
deployment = find_deployment
|
72
|
+
deployment.destroy
|
73
|
+
render json: { deployment: deployment }
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module AtomicAdmin
|
2
|
+
class AtomicTenantPlatformGuidStrategyController < ApplicationController
|
3
|
+
def pinned_platform_guid_params
|
4
|
+
params.permit(:iss, :platform_guid, :application_id, :application_instance_id)
|
5
|
+
end
|
6
|
+
|
7
|
+
def find_pinned_platform_guid
|
8
|
+
AtomicTenant::PinnedPlatformGuid.find(params[:id])
|
9
|
+
end
|
10
|
+
|
11
|
+
def search
|
12
|
+
page = AtomicTenant::PinnedPlatformGuid
|
13
|
+
.where(application_instance_id: params[:application_instance_id])
|
14
|
+
.order(:id).paginate(page: params[:page], per_page: 30)
|
15
|
+
render json: {
|
16
|
+
pinned_platform_guids: page,
|
17
|
+
page: params[:page],
|
18
|
+
total_pages: page.total_pages
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
# def index
|
23
|
+
# page = AtomicTenant::PinnedPlatformGuid.all.order(:id).paginate(page: params[:page], per_page: 30)
|
24
|
+
# render json: {
|
25
|
+
# pinned_platform_guids: page,
|
26
|
+
# page: params[:page],
|
27
|
+
# total_pages: page.total_pages
|
28
|
+
# }
|
29
|
+
# end
|
30
|
+
|
31
|
+
def create
|
32
|
+
result = AtomicTenant::PinnedPlatformGuid.create!(pinned_platform_guid_params)
|
33
|
+
render json: { pinned_platform_guid: result }
|
34
|
+
end
|
35
|
+
|
36
|
+
def show
|
37
|
+
pinned_platform_guid = find_pinned_platform_guid
|
38
|
+
render json: {pinned_platform_guid: pinned_platform_guid}
|
39
|
+
end
|
40
|
+
|
41
|
+
def update
|
42
|
+
pinned_platform_guid = find_pinned_platform_guid
|
43
|
+
pinned_platform_guid.update!(pinned_platform_guid_params)
|
44
|
+
|
45
|
+
render json: {pinned_platform_guid: find_pinned_platform_guid}
|
46
|
+
end
|
47
|
+
|
48
|
+
def destroy
|
49
|
+
pinned_platform_guid = find_pinned_platform_guid
|
50
|
+
pinned_platform_guid.destroy
|
51
|
+
render json: { pinned_platform_guid: pinned_platform_guid }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/config/routes.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
AtomicAdmin::Engine.routes.draw do
|
2
|
+
# namespace :lti do
|
3
|
+
resources :atomic_lti_platform
|
4
|
+
resources :atomic_lti_install
|
5
|
+
resources :atomic_tenant_deployment
|
6
|
+
post '/atomic_tenant_deployment/search', to: 'atomic_tenant_deployment#search'
|
7
|
+
|
8
|
+
resources :atomic_tenant_platform_guid_strategy
|
9
|
+
post '/atomic_tenant_platform_guid_strategy/search', to: 'atomic_tenant_platform_guid_strategy#search'
|
10
|
+
post '/atomic_tenant_client_id_strategy/search', to: 'atomic_tenant_client_id_strategy#search'
|
11
|
+
|
12
|
+
resources :atomic_tenant_client_id_strategy
|
13
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
## Note: This code is basically copied out of the starter app to authenticate
|
2
|
+
## admin app api calls. Lives at /app/controllers/concerns/jwt_token.rb in
|
3
|
+
## starter app
|
4
|
+
module AtomicAdmin
|
5
|
+
module JwtToken
|
6
|
+
|
7
|
+
ALGORITHM = "HS512".freeze
|
8
|
+
|
9
|
+
class InvalidTokenError < StandardError; end
|
10
|
+
|
11
|
+
def self.valid?(token, secret = nil, algorithm = ALGORITHM)
|
12
|
+
decode(token, secret, true, algorithm)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.decode(token, secret = nil, validate = true, algorithm = ALGORITHM)
|
16
|
+
JWT.decode(
|
17
|
+
token,
|
18
|
+
secret || Rails.application.secrets.auth0_client_secret,
|
19
|
+
validate,
|
20
|
+
{ algorithm: algorithm },
|
21
|
+
)
|
22
|
+
end
|
23
|
+
|
24
|
+
def decoded_jwt_token(req, secret = nil)
|
25
|
+
token = AtomicAdmin::JwtToken.valid?(encoded_token(req), secret)
|
26
|
+
raise InvalidTokenError, "Unable to decode jwt token" if token.blank?
|
27
|
+
raise InvalidTokenError, "Invalid token payload" if token.empty?
|
28
|
+
|
29
|
+
token[0]
|
30
|
+
end
|
31
|
+
|
32
|
+
def validate_token
|
33
|
+
return if @admin_app_validated
|
34
|
+
|
35
|
+
token = decoded_jwt_token(request)
|
36
|
+
raise InvalidTokenError if Rails.application.secrets.auth0_client_id != token["aud"]
|
37
|
+
|
38
|
+
current_application_instance_id = request.env['atomic.validated.application_instance_id']
|
39
|
+
if current_application_instance_id && current_application_instance_id != token["application_instance_id"]
|
40
|
+
raise InvalidTokenError
|
41
|
+
end
|
42
|
+
|
43
|
+
@user_tenant = token["user_tenant"] if token["user_tenant"].present?
|
44
|
+
@user = User.find(token["user_id"])
|
45
|
+
|
46
|
+
sign_in(@user, event: :authentication, store: false)
|
47
|
+
rescue JWT::DecodeError, InvalidTokenError => e
|
48
|
+
Rails.logger.error "JWT Error occured #{e.inspect}"
|
49
|
+
begin
|
50
|
+
render json: { error: "Unauthorized: Invalid token." }, status: :unauthorized
|
51
|
+
rescue NoMethodError
|
52
|
+
raise GraphQL::ExecutionError, "Unauthorized: Invalid token."
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def validate_admin_app_token
|
57
|
+
_bearer, jwt = request.headers['Authorization'].split(' ')
|
58
|
+
@atomic_admin_params = AtomicAdmin::JwtToken.decode(jwt, Rails.application.secrets.atomic_admin_shared_key)
|
59
|
+
@admin_app_validated = true
|
60
|
+
rescue JWT::DecodeError, InvalidTokenError => e
|
61
|
+
# fall back to regular app jwt
|
62
|
+
Rails.logger.error "JWT Error occured with admin app token #{e.inspect}"
|
63
|
+
@admin_app_validated = false
|
64
|
+
end
|
65
|
+
|
66
|
+
protected
|
67
|
+
|
68
|
+
def encoded_token(req)
|
69
|
+
return req.params[:jwt] if req.params[:jwt]
|
70
|
+
|
71
|
+
header = req.headers["Authorization"] || req.headers[:authorization]
|
72
|
+
raise InvalidTokenError, "No authorization header found" if header.nil?
|
73
|
+
|
74
|
+
token = header.split(" ").last
|
75
|
+
raise InvalidTokenError, "Invalid authorization header string" if token.nil?
|
76
|
+
|
77
|
+
token
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
end
|
data/lib/atomic_admin.rb
ADDED
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: atomic_admin
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Nick Benoit
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2023-08-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '7.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '7.0'
|
27
|
+
description: Engine to provide apis that power the atomic jolt admin app
|
28
|
+
email:
|
29
|
+
- nick.benoit@atomicjolt.com
|
30
|
+
executables: []
|
31
|
+
extensions: []
|
32
|
+
extra_rdoc_files: []
|
33
|
+
files:
|
34
|
+
- MIT-LICENSE
|
35
|
+
- README.md
|
36
|
+
- Rakefile
|
37
|
+
- app/controllers/atomic_admin/application_controller.rb
|
38
|
+
- app/controllers/atomic_admin/atomic_lti_install_controller.rb
|
39
|
+
- app/controllers/atomic_admin/atomic_lti_platform_controller.rb
|
40
|
+
- app/controllers/atomic_admin/atomic_tenant_client_id_strategy_controller.rb
|
41
|
+
- app/controllers/atomic_admin/atomic_tenant_deployment_controller.rb
|
42
|
+
- app/controllers/atomic_admin/atomic_tenant_platform_guid_strategy_controller.rb
|
43
|
+
- app/jobs/atomic_admin/application_job.rb
|
44
|
+
- app/mailers/atomic_admin/application_mailer.rb
|
45
|
+
- app/models/atomic_admin/application_record.rb
|
46
|
+
- config/routes.rb
|
47
|
+
- lib/atomic_admin.rb
|
48
|
+
- lib/atomic_admin/engine.rb
|
49
|
+
- lib/atomic_admin/jwt_token.rb
|
50
|
+
- lib/atomic_admin/version.rb
|
51
|
+
- lib/tasks/atomic_admin_tasks.rake
|
52
|
+
homepage: https://github.com/atomicjolt/atomic_admin/
|
53
|
+
licenses:
|
54
|
+
- MIT
|
55
|
+
metadata:
|
56
|
+
homepage_uri: https://github.com/atomicjolt/atomic_admin/
|
57
|
+
source_code_uri: https://github.com/atomicjolt/atomic_admin/
|
58
|
+
changelog_uri: https://github.com/atomicjolt/atomic_admin/
|
59
|
+
post_install_message:
|
60
|
+
rdoc_options: []
|
61
|
+
require_paths:
|
62
|
+
- lib
|
63
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '0'
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: '0'
|
73
|
+
requirements: []
|
74
|
+
rubygems_version: 3.4.15
|
75
|
+
signing_key:
|
76
|
+
specification_version: 4
|
77
|
+
summary: Engine to provide apis that power the atomic jolt admin app
|
78
|
+
test_files: []
|