oauth_im 0.1.0.beta

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: 27cef13d10be77f61bfff0a4faeabea5695f0707dc8edceb2cb47363f1aa4b58
4
+ data.tar.gz: e429efcb445b1243d4954801abc053bf80b4f6f9543a962d668e4728bb25c65b
5
+ SHA512:
6
+ metadata.gz: d8a956deb04217dd73f4bf2bd35d6e9390b542e1ce786784088c05593eb607ac0bc19df739052af1dfcc0c820ad59bc18b1fad107ca3e05eaafb7480cd9ce19b
7
+ data.tar.gz: 5fb848b54191d4c12052786bbfd959069ece2c1b0dda8aab7481a7fe1b262b389e79c76af4108a453aa71b28492d20fdfdff41bed5edd390a7afb668c38ef451
data/LICENSE ADDED
@@ -0,0 +1,8 @@
1
+ Copyright (c) 2018, Illustrative Mathematics and Open Up Resources
2
+ All rights reserved.
3
+
4
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
5
+ 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6
+ 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
7
+ 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
8
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # OauthIm
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem 'oauth_im'
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install oauth_im
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,18 @@
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'
9
+
10
+ require 'rake/testtask'
11
+
12
+ Rake::TestTask.new(:test) do |t|
13
+ t.libs << 'test'
14
+ t.pattern = 'test/**/*_test.rb'
15
+ t.verbose = false
16
+ end
17
+
18
+ task default: :test
@@ -0,0 +1 @@
1
+ //= link_directory ../stylesheets/oauth_im .css
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,54 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OauthIm
4
+ module Authenticable
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ before_action :auth_uid
9
+ helper_method :authenticated?
10
+ helper_method :email
11
+ end
12
+
13
+ private
14
+
15
+ def authenticated?
16
+ AppContext.kh_iiab? && logged_in?
17
+ end
18
+
19
+ def email
20
+ @email ||= jwt_token['email']
21
+ end
22
+
23
+ def auth_uid
24
+ gon.user_id = session[:user_jwt]['value'].first['jti'] if authenticated?
25
+ end
26
+
27
+ def user_jwt
28
+ @user_jwt ||= session[:user_jwt] || {}
29
+ end
30
+
31
+ def jwt_token
32
+ @jwt_token ||= user_jwt['value']&.first || {}
33
+ end
34
+
35
+ def email_verified?
36
+ jwt_token.present? && jwt_token['email_verified'].present?
37
+ end
38
+
39
+ def current_user
40
+ @current_user ||=
41
+ if user_jwt.present?
42
+ if email_verified?
43
+ email
44
+ else
45
+ head :forbidden
46
+ end
47
+ end
48
+ end
49
+
50
+ def logged_in?
51
+ current_user.present?
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OauthIm
4
+ class ApplicationController < ActionController::Base; end
5
+ end
@@ -0,0 +1,76 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'oauth2'
4
+
5
+ module OauthIm
6
+ class ClientController < OauthIm::ApplicationController
7
+ def callback
8
+ session[:user_jwt] = { value: decoded_token, httponly: true }
9
+ redirect_to main_app.root_path
10
+ rescue StandardError
11
+ head :forbidden
12
+ end
13
+
14
+ def login
15
+ redirect_to oauth_client.auth_code.authorize_url
16
+ end
17
+
18
+ def logout
19
+ reset_session
20
+ redirect_to logout_uri
21
+ end
22
+
23
+ def local_login
24
+ raise 'Disallowed' unless Rails.env.development?
25
+
26
+ session[:userinfo] = { info: { email: 'local_login@example.com' } }
27
+ redirect_back(fallback_location: main_app.root_path)
28
+ end
29
+
30
+ def local_logout
31
+ reset_session
32
+ redirect_back(fallback_location: main_app.root_path)
33
+ end
34
+
35
+ private
36
+
37
+ def logout_uri
38
+ @logout_uri ||= "#{configuration.domain}/oauth2/logout" \
39
+ "?post_logout_redirect_uri=#{post_logout_redirect_uri}" \
40
+ "&client_id=#{configuration.client_id}"
41
+ end
42
+
43
+ def post_logout_redirect_uri
44
+ @post_logout_redirect_uri ||= params[:return_to]
45
+ end
46
+
47
+ def decoded_token
48
+ @decoded_token ||= TokenDecoder.new(access_token, oauth_client.id).decode
49
+ end
50
+
51
+ def access_token
52
+ @access_token ||= response_hash[:access_token]
53
+ end
54
+
55
+ def response_hash
56
+ @response_hash ||= auth_code.get_token(params[:code]).to_hash
57
+ end
58
+
59
+ def auth_code
60
+ @auth_code ||= oauth_client.auth_code
61
+ end
62
+
63
+ def oauth_client
64
+ @oauth_client = ::OAuth2::Client.new configuration.client_id,
65
+ configuration.client_secret,
66
+ authorize_url: configuration.authorize_url,
67
+ site: configuration.domain,
68
+ token_url: configuration.token_url,
69
+ redirect_uri: callback_url
70
+ end
71
+
72
+ def configuration
73
+ OauthIm.configuration
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,4 @@
1
+ module OauthIm
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'jwt'
4
+
5
+ module OauthIm
6
+ class TokenDecoder
7
+ attr_reader :token, :aud
8
+
9
+ DECODE_ALGORITHM = 'HS256'
10
+
11
+ def initialize(token, aud)
12
+ @token = token
13
+ @aud = aud
14
+ end
15
+
16
+ def decode
17
+ decoded_token
18
+ end
19
+
20
+ private
21
+
22
+ def configuration
23
+ @configuration ||= OauthIm.configuration
24
+ end
25
+
26
+ def decoded_token
27
+ @decoded_token ||= JWT.decode token, configuration.hmac, true, decode_params
28
+ end
29
+
30
+ def decode_params
31
+ @decode_params ||= { verify_iss: true,
32
+ iss: configuration.iss_domain,
33
+ verify_aud: true,
34
+ aud: aud,
35
+ algorithm: DECODE_ALGORITHM }.freeze
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,15 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Oauth im</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= stylesheet_link_tag "oauth_im/application", media: "all" %>
9
+ </head>
10
+ <body>
11
+
12
+ <%= yield %>
13
+
14
+ </body>
15
+ </html>
data/config/routes.rb ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ OauthIm::Engine.routes.draw do
4
+ get OauthIm.callback_path, to: 'client#callback'
5
+ get 'login', to: 'client#login'
6
+ get 'logout', to: 'client#logout'
7
+
8
+ unless Rails.env.production?
9
+ get 'local_login', to: 'client#local_login'
10
+ get 'local_logout', to: 'client#local_logout'
11
+ end
12
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OauthIm
4
+ CONFIGURABLE_FIELDS =
5
+ %i[api_key
6
+ authorize_url
7
+ callback_path
8
+ client_id
9
+ client_secret
10
+ domain
11
+ hmac
12
+ iss_domain
13
+ tenant_id
14
+ token_url].freeze
15
+
16
+ class Configuration
17
+ attr_reader(* CONFIGURABLE_FIELDS)
18
+
19
+ def initialize(config_proxy)
20
+ CONFIGURABLE_FIELDS.each do |field|
21
+ instance_variable_set "@#{field}", config_proxy.send(field)
22
+ end
23
+ end
24
+ end
25
+
26
+ class ConfigurationProxy
27
+ attr_accessor(*CONFIGURABLE_FIELDS)
28
+ end
29
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OauthIm
4
+ class Engine < ::Rails::Engine
5
+ isolate_namespace OauthIm
6
+
7
+ # edc: see https://www.hocnest.com/blog/testing-an-engine-with-rspec/
8
+ config.generators do |g|
9
+ g.test_framework :rspec
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module OauthIm
4
+ VERSION = '0.1.0.beta'
5
+ end
data/lib/oauth_im.rb ADDED
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'oauth_im/version'
4
+ require 'oauth_im/engine'
5
+ require 'oauth_im/configuration'
6
+
7
+ module OauthIm
8
+ DEFAULT_AUTHORIZE_URL = '/oauth2/authorize'
9
+ DEFAULT_TOKEN_URL = '/oauth2/token'
10
+ DEFAULT_CALLBACK_PATH = 'callback'
11
+
12
+ class << self
13
+ attr_reader :configuration
14
+ end
15
+
16
+ def self.configure
17
+ raise 'Already configured!' if configuration.present?
18
+
19
+ ConfigurationProxy.new.then do |proxy|
20
+ yield proxy
21
+ @configuration = Configuration.new proxy
22
+ end
23
+ end
24
+
25
+ def self.callback_path
26
+ configuration&.callback_path || DEFAULT_CALLBACK_PATH
27
+ end
28
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :oauth_im do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oauth_im
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.beta
5
+ platform: ruby
6
+ authors:
7
+ - Eric Connally
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-02-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: jwt
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: oauth2
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 5.pre.2.pre.stable
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 5.pre.2.pre.stable
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '3.0'
69
+ description: Include this gem in Gemfile, add an initializer, and you are good to
70
+ go.
71
+ email:
72
+ - eric@illustrativemathematics.org
73
+ executables: []
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - LICENSE
78
+ - README.md
79
+ - Rakefile
80
+ - app/assets/config/oauth_im_manifest.js
81
+ - app/assets/stylesheets/oauth_im/application.css
82
+ - app/controllers/concerns/oauth_im/authenticable.rb
83
+ - app/controllers/oauth_im/application_controller.rb
84
+ - app/controllers/oauth_im/client_controller.rb
85
+ - app/helpers/oauth_im/application_helper.rb
86
+ - app/services/oauth_im/token_decoder.rb
87
+ - app/views/layouts/oauth_im/application.html.erb
88
+ - config/routes.rb
89
+ - lib/oauth_im.rb
90
+ - lib/oauth_im/configuration.rb
91
+ - lib/oauth_im/engine.rb
92
+ - lib/oauth_im/version.rb
93
+ - lib/tasks/oauth_im_tasks.rake
94
+ homepage: https://github.com/illustrativemathematics/oauth_im
95
+ licenses:
96
+ - BSD-3-Clause
97
+ metadata:
98
+ homepage_uri: https://github.com/illustrativemathematics/oauth_im
99
+ source_code_uri: https://github.com/illustrativemathematics/oauth_im
100
+ changelog_uri: https://github.com/illustrativemathematics/oauth_im
101
+ post_install_message:
102
+ rdoc_options: []
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: 2.6.6
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">"
113
+ - !ruby/object:Gem::Version
114
+ version: 1.3.1
115
+ requirements: []
116
+ rubygems_version: 3.0.3
117
+ signing_key:
118
+ specification_version: 4
119
+ summary: Provide oauth functionality for IM apps.
120
+ test_files: []