atomic_admin 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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: []