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 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,8 @@
1
+ require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
6
+ load "rails/tasks/statistics.rake"
7
+
8
+ require "bundler/gem_tasks"
@@ -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
@@ -0,0 +1,4 @@
1
+ module AtomicAdmin
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module AtomicAdmin
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: "from@example.com"
4
+ layout "mailer"
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module AtomicAdmin
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ 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,6 @@
1
+ module AtomicAdmin
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace AtomicAdmin
4
+ config.generators.api_only = true
5
+ end
6
+ 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
@@ -0,0 +1,3 @@
1
+ module AtomicAdmin
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,7 @@
1
+ require "atomic_admin/version"
2
+ require "atomic_admin/engine"
3
+ require "atomic_admin/jwt_token"
4
+
5
+ module AtomicAdmin
6
+ # Your code goes here...
7
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :atomic_admin do
3
+ # # Task goes here
4
+ # end
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: []