anoubis_sso_server 0.1.1 → 1.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bd3afcb17bb8237f6f7604fa63f75d13f7caa5e2c106941293785b65c5e24b3f
4
- data.tar.gz: e303e294bffa7706560274fa186fba47b17e80944a699254efad0f2410cf2b20
3
+ metadata.gz: 99a948f147bd85dbac2a05e1776cb9d782df8270d8c952231954891b5aefbe90
4
+ data.tar.gz: 30f5032129b1b8e43665842c528e6a6f0e4a8f3bb1e843a4012b78b326918a67
5
5
  SHA512:
6
- metadata.gz: c5aa132b85b183c6adfb7f8792ca7d0344ef7eeda50da33931b361bb71b4f79c6c5d39e29ed2663d2335226f700d87d7458f6195182b1c12359f4882dc5a319e
7
- data.tar.gz: 9228457e5c5aa6b85fe6682cd407a1b1e7c076f2cb4f069ecff9dab9792e579b33079eb370ca7f1eb1d21d64de127429d1c0a745b7f1addabfc7f3cffc5a20bf
6
+ metadata.gz: 4058632c8ea913bd5456a3fc55485b1ad99644f93065a6e92a0192d28bf79c6de8cb221204007047f37a1e4186829dd670202f687b24c687c428092f6c2c027a
7
+ data.tar.gz: 26f2624db76c5bca8f94b923ae040554a7f41abf02fcfd4bf6065f9f0e4cd6173221c0e493f9ca998bbfec8fc7e830fe64fdb8eda33e2fc6a70a7f572f34fb6e
data/.env.sample ADDED
@@ -0,0 +1,3 @@
1
+ DATABASE_USER=
2
+ DATABASE_PASSWORD=
3
+ DATABASE_NAME=
data/.rspec CHANGED
@@ -1,3 +1,4 @@
1
- --format documentation
2
1
  --color
3
2
  --require spec_helper
3
+ --order rand
4
+ --format doc
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-2.7.1
1
+ ruby-3.0.0
data/CHANGELOG.md CHANGED
@@ -1,4 +1,7 @@
1
- ## [Unreleased]
1
+ ## [Released]
2
2
 
3
- ## [0.1.0] - 2022-01-28
3
+ ## [1.0.1] - 2022-02-27
4
+ - Library was released.
5
+
6
+ ## [1.0.0] - 2022-01-28
4
7
  - Library was created.
data/Gemfile CHANGED
@@ -5,10 +5,20 @@ source "https://rubygems.org"
5
5
  # Specify your gem's dependencies in anoubis_sso_server.gemspec
6
6
  gemspec
7
7
 
8
- gem "rake", "~> 13.0"
8
+ #gem "rake", "~> 13.0"
9
+ #gem "rspec", "~> 3.0"
10
+ #gem "rubocop", "~> 1.21"
11
+ gem 'redis'
12
+ gem 'jwt'
13
+ gem 'anoubis', git: 'https://github.com/RA-Company/anoubis.git', branch: 'main'
9
14
 
10
- gem "rspec", "~> 3.0"
15
+ #group :development, :test do
16
+ # gem "rspec-rails"
17
+ #gem "factory_bot_rails"
18
+ #end
11
19
 
12
- gem "rubocop", "~> 1.21"
13
-
14
- gem "anoubis", git: 'https://github.com/RA-Company/anoubis.git', branch: 'main'
20
+ group :test do
21
+ gem 'dotenv'
22
+ gem 'dotenv-rails'
23
+ gem 'tzinfo-data', platforms: %i[mingw mswin x64_mingw jruby]
24
+ end
data/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # AnoubisSsoServer
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/anoubis_sso_server`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
3
+ Gem for create simple SSO server, based on OAUTH2 authentication.
6
4
 
7
5
  ## Installation
8
6
 
@@ -20,9 +18,84 @@ Or install it yourself as:
20
18
 
21
19
  $ gem install anoubis_sso_server
22
20
 
21
+ After it please install default migrations:
22
+
23
+ $ rails anoubis_sso_server:install:migrations
24
+ $ bundle exec rake db:migrate
25
+
23
26
  ## Usage
24
27
 
25
- TODO: Write usage instructions here
28
+ By default system database isn't filled any data.
29
+
30
+ For adding data to database please add this to db/seed.rb of your application.
31
+
32
+ First of all add admin user to database:
33
+
34
+ ```ruby
35
+ user = AnoubisSsoServer::User.where(email: '<your_email>').first
36
+ unless user
37
+ user = AnoubisSsoServer::User.new
38
+ user.email = '<your_email>'
39
+ user.password = '<your_password>'
40
+ user.password_confirmation = '<your_password>'
41
+ user.name = '<your_name>'
42
+ user.surname = '<your_surname>'
43
+ user.save
44
+ end
45
+ ```
46
+
47
+ Please use strong password when create user login.
48
+
49
+ Then add systems to database.
50
+
51
+ ```ruby
52
+ system = AnoubisSsoServer::System.where(public: 'sso-system').first
53
+ unless system
54
+ system = AnoubisSsoServer::System.new
55
+ system.title = 'SSO'
56
+ system.public = 'sso-system'
57
+ system.state = 'hidden'
58
+ system.save
59
+ end
60
+
61
+ ext_system = AnoubisSsoServer::System.where(public: '<system_identifier>').first
62
+ unless ext_system
63
+ ext_system = AnoubisSsoServer::System.new
64
+ ext_system.title = '<system_name>'
65
+ ext_system.public = '<system_identifier>'
66
+ ext_system.request_uri = %w[https://<server_url>/silent-callback.html https://<server_url>/callback]
67
+ ext_system.save
68
+ end
69
+ ```
70
+
71
+ After this seed this data to database:
72
+
73
+ $ bundle exec rake db:seed
74
+
75
+ ## Configuration parameters
76
+
77
+ This configuration parameters can be placed at files config/application.rb for global configuration or config/environments/<environment>.rb for custom environment configuration.
78
+
79
+ ```ruby
80
+ config.anoubis_redis_prefix = '<sample-prefix>' # Redis prefix for store cache data (when many applications run in one physical server)
81
+ config.anoubis_sso_server = 'https://sso.example.com/' # Full URL of SSO server (*required)
82
+ config.anoubis_sso_system = 'sso-system' # Internal SSO system identifier (*required)
83
+ config.anoubis_sso_origin = /^https:\/\/.*\.example\.com$/ # Regexp for prevent CORS access from others domain (*required)
84
+ config.anoubis_sso_login_url = 'https://sso.example.com/login' # Full URL for login page. (By default calculate from config.anoubis_sso_server adding 'login') (*optional)
85
+ config.anoubis_sso_silent_url = 'https://sso.example.com/silent.html' # Full URL for silent refresh page. (By default calculate from config.anoubis_sso_server adding 'silent.html') (*optional)
86
+ config.anoubis_sso_user_model = 'AnoubisSsoServer::User'# Used user model. ()By default used AnoubisSsoServer::User model) (*optional)
87
+ ```
88
+
89
+ Also pay attention on this configuration parameters:
90
+
91
+ ```ruby
92
+ config.api_only = true # for API only application
93
+ config.middleware.use ActionDispatch::Cookies # for attach cookies into the API application
94
+
95
+ config.hosts.clear # for clearing allowed IP requests
96
+
97
+ config.action_dispatch.default_headers.clear # for clear default response headers
98
+ ```
26
99
 
27
100
  ## Development
28
101
 
@@ -30,6 +103,20 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run
30
103
 
31
104
  To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
32
105
 
106
+ ## Testing
107
+
108
+ First of all create MySQL database and grant privileges to it.
109
+
110
+ After that copy file `.env.sample` to `.env` and fill required fields like `DATABASE_NAME`, `DATABASE_USER` and `DATABASE_PASSWORD`.
111
+
112
+ After it run migrate database to test environment:
113
+
114
+ $ bin/rails db:migrate RAILS_ENV=test DATABASE_USER=<user_name> DATABASE_PASSWORD=<user_password> DATABASE_NAME=<database_name>
115
+
116
+ After all of this preparation you can start tests:
117
+
118
+ $ bundle exec rspec
119
+
33
120
  ## Contributing
34
121
 
35
122
  Bug reports and pull requests are welcome on GitHub at https://github.com/RA-Company/anoubis_sso_server. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/RA-Company/anoubis_sso_server/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile CHANGED
@@ -10,3 +10,6 @@ require "rubocop/rake_task"
10
10
  RuboCop::RakeTask.new
11
11
 
12
12
  task default: %i[spec rubocop]
13
+
14
+ APP_RAKEFILE = File.expand_path("spec/dummy/Rakefile", __dir__)
15
+ load 'rails/tasks/engine.rake'
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "lib/anoubis_sso_server/version"
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "anoubis_sso_server"
7
+ spec.version = AnoubisSsoServer::VERSION
8
+ spec.authors = ["Andrey Ryabov"]
9
+ spec.email = ["andrey.ryabov@ra-company.kz"]
10
+
11
+ spec.summary = "Library for create basic SSO Server based on OAUTH authentication."
12
+ spec.description = "Library for create basic SSO Server based on OAUTH authentication."
13
+ spec.homepage = "https://github.com/RA-Company/"
14
+ spec.license = "MIT"
15
+ spec.required_ruby_version = ">= 2.7.1"
16
+
17
+ spec.metadata["homepage_uri"] = spec.homepage
18
+ spec.metadata["source_code_uri"] = "https://github.com/RA-Company/anoubis_sso_server"
19
+ spec.metadata["changelog_uri"] = "https://github.com/RA-Company/anoubis_sso_server/blob/main/CHANGELOG.md"
20
+
21
+ # Specify which files should be added to the gem when it is released.
22
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
23
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
24
+ `git ls-files -z`.split("\x0").reject do |f|
25
+ (f == __FILE__) || f.match(%r{\A(?:(?:bin|test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
26
+ end
27
+ end
28
+ spec.bindir = "exe"
29
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
30
+ spec.require_paths = ["lib"]
31
+
32
+ spec.add_dependency "anoubis", ">= 1.0.0"
33
+ spec.add_dependency "rails", ">= 7.0.0"
34
+ spec.add_dependency "redis", ">= 4.5.1"
35
+ spec.add_dependency "bcrypt", ">= 3.1.16"
36
+ spec.add_dependency "rest-client", ">= 2.1.0"
37
+ spec.add_dependency "mysql2", ">= 0.5.3"
38
+ spec.add_dependency "jwt", ">= 2.3.0"
39
+
40
+ spec.add_development_dependency "rake", ">= 0.13"
41
+ spec.add_development_dependency "rspec", ">= 3.11.0"
42
+ spec.add_development_dependency "rspec-rails", ">= 5.1"
43
+ spec.add_development_dependency "factory_bot_rails", ">= 6.2.0"
44
+ spec.add_development_dependency "dotenv", '>= 2.7'
45
+ spec.add_development_dependency "simplecov", '>= 0.21'
46
+ spec.add_development_dependency "rubocop"
47
+
48
+ # For more information and examples about making a new gem, check out our
49
+ # guide at: https://bundler.io/guides/creating_gem.html
50
+ end
@@ -1,4 +1,5 @@
1
- ## Main application class inherited from {https://api.rubyonrails.org/v6.1.4/classes/ActionController/API.html ActionController::API}
1
+ ##
2
+ # Main application class inherited from {https://www.rubydoc.info/gems/anoubis/Anoubis/ApplicationController Anoubis::ApplicationController}
2
3
  class AnoubisSsoServer::ApplicationController < Anoubis::ApplicationController
3
4
  ## Selected SSO system
4
5
  attr_accessor :current_system
@@ -12,6 +13,104 @@ class AnoubisSsoServer::ApplicationController < Anoubis::ApplicationController
12
13
  ## Returns SSO silent url used for silent refresh token.
13
14
  attr_accessor :sso_silent_url
14
15
 
16
+ ## Returns used User model
17
+ attr_accessor :user_model
18
+
19
+ ## Used sso_origin
20
+ attr_accessor :sso_origin
21
+
22
+ ## Returns [Anoubis::Etc::Base] global system parameters
23
+ attr_accessor :etc
24
+
25
+ ##
26
+ # Current user
27
+ attr_accessor :current_user
28
+
29
+ ##
30
+ # Action fires before any other actions
31
+ def after_anoubis_initialization
32
+ if defined? params
33
+ self.etc = Anoubis::Etc::Base.new({ params: params })
34
+ else
35
+ self.etc = Anoubis::Etc::Base.new
36
+ end
37
+
38
+ if access_allowed?
39
+ options request.method.to_s.upcase
40
+ else
41
+ render_error_exit({ error: I18n.t('errors.access_not_allowed') })
42
+ return
43
+ end
44
+
45
+ if self.authenticate?
46
+ if self.authentication
47
+ if self.check_menu_access?
48
+ return if !self.menu_access params[:controller]
49
+ end
50
+ end
51
+ end
52
+
53
+ #puts etc.inspect
54
+ end
55
+
56
+ ##
57
+ # Check for site access. By default return true.
58
+ def access_allowed?
59
+ true
60
+ end
61
+
62
+ ##
63
+ # Checks if needed user authentication.
64
+ # @return [Boolean] if true, then user must be authenticated. By default application do not need authorization.
65
+ def authenticate?
66
+ false
67
+ end
68
+
69
+
70
+ ##
71
+ # Procedure authenticates user in the system
72
+ def authentication
73
+ session = get_oauth_session
74
+
75
+ unless session
76
+ render_error_exit code: -2, error: I18n.t('anoubis.errors.session_expired')
77
+ return
78
+ end
79
+
80
+ self.current_user = get_user_by_uuid session[:uuid]
81
+
82
+ unless current_user
83
+ self.redis.del("#{redis_prefix}session:#{cookies[:oauth_session]}")
84
+ cookies[:oauth_session] = nil
85
+ render_error_exit code: -3, error: I18n.t('anoubis.errors.incorrect_user')
86
+ return
87
+ end
88
+ end
89
+
90
+ ##
91
+ # Gracefully terminate script execution with code 422 (Unprocessable entity). And JSON data
92
+ # @param data [Hash] Resulting data
93
+ # @option data [Integer] :code resulting error code
94
+ # @option data [String] :error resulting error message
95
+ def render_error_exit(data = {})
96
+ result = {
97
+ result: -1,
98
+ message: I18n.t('anoubis.error')
99
+ }
100
+
101
+ result[:result] = data[:code] if data.has_key? :code
102
+ result[:message] = data[:error] if data.has_key? :error
103
+
104
+
105
+ render json: result, status: :unprocessable_entity
106
+
107
+ begin
108
+ exit
109
+ rescue SystemExit => e
110
+ puts result[:message]
111
+ end
112
+ end
113
+
15
114
  ##
16
115
  # Returns main SSO server URL. Link should be defined in Rails.configuration.anoubis.sso_server configuration parameter
17
116
  # @return [String] link to SSO server
@@ -30,6 +129,23 @@ class AnoubisSsoServer::ApplicationController < Anoubis::ApplicationController
30
129
  value
31
130
  end
32
131
 
132
+ ##
133
+ # Returns SSO origin. Variable should be defined in Rails.configuration.anoubis.sso_origin configuration parameter
134
+ # @return [Regexp] regexp for check site origin
135
+ def sso_origin
136
+ @sso_origin ||= get_sso_origin
137
+ end
138
+
139
+ private def get_sso_origin
140
+ begin
141
+ value = Rails.configuration.anoubis_sso_origin
142
+ rescue StandardError
143
+ value = /^.*$/
144
+ end
145
+
146
+ value
147
+ end
148
+
33
149
  ##
34
150
  # Returns SSO Login URL used for redirect when user isn't logged in.
35
151
  # Link can be redefined in Rails.configuration.anoubis_sso_login_url configuration parameter. If this variable isn't defined
@@ -68,11 +184,47 @@ class AnoubisSsoServer::ApplicationController < Anoubis::ApplicationController
68
184
  value
69
185
  end
70
186
 
187
+ ##
188
+ # Returns SSO User model.
189
+ # Can be redefined in Rails.application configuration_anoubis_sso_user_model configuration parameter.
190
+ # By default returns {AnoubisSsoServer::User} model class
191
+ # @return [Class] User model class
192
+ def user_model
193
+ @user_model ||= get_user_model
194
+ end
195
+
196
+ private def get_user_model
197
+ begin
198
+ value = Object.const_get Rails.configuration.anoubis_sso_user_model
199
+ rescue
200
+ value = AnoubisSsoServer::User
201
+ end
202
+
203
+ value
204
+ end
205
+
206
+ ##
207
+ # Returns current SSO system data
208
+ # @param system_title [String] - System public UUID parameter. By default load from Rails.application configuration_anoubis_sso_system configuration parameter.
209
+ # @return [AnoubisSsoServer::System] current SSO system
210
+ def get_current_system(system_title = nil)
211
+ begin
212
+ system_title = Rails.configuration.anoubis_sso_system unless system_title
213
+ system = AnoubisSsoServer::System.new(JSON.parse(redis.get("#{redis_prefix}system:#{system_title}"),{ symbolize_names: true }))
214
+ rescue
215
+ system = nil
216
+ end
217
+
218
+ system
219
+ end
220
+
71
221
  ##
72
222
  # Check current origin of header by Regexp defined in Rails.configuration.anoubis_sso_origin configuration parameter
73
223
  # @return [Boolean] request host origin validation
74
224
  def check_origin
75
- request.headers['origin'].match(Rails.configuration.anoubis_sso_origin)
225
+ return true unless request.origin
226
+
227
+ request.origin.match(sso_origin)
76
228
  end
77
229
 
78
230
  ##
@@ -93,10 +245,31 @@ class AnoubisSsoServer::ApplicationController < Anoubis::ApplicationController
93
245
  session[:ttl] = Time.now.utc.to_i + session[:timeout]
94
246
  redis.del("#{redis_prefix}session:#{cookies[:oauth_session]}")
95
247
  cookies[:oauth_session] = session_name
96
- redis.set("#{redis_prefix}session:#{session_name}", session.to_json, { ex: 86400 })
248
+ redis.set("#{redis_prefix}session:#{session_name}", session.to_json, ex: 86400)
97
249
  end
98
250
  end
99
251
 
100
252
  session
101
253
  end
254
+
255
+ ##
256
+ # Returns user by UUID from the Redis cache or from database. If User isn't present in cache than User is loaded from database and placed to cache.
257
+ # @param uuid [String] UUID of user
258
+ # @return [Class] Returns user class
259
+ def get_user_by_uuid(uuid)
260
+ begin
261
+ user = user_model.new JSON.parse(redis.get("#{redis_prefix}user:#{uuid}"),{ symbolize_names: true })
262
+ rescue
263
+ user = nil
264
+ end
265
+
266
+ return user if user
267
+
268
+ user = user_model.where(uuid: uuid).first
269
+ return nil unless user
270
+
271
+ redis.set("#{redis_prefix}user:#{uuid}", user.to_json(except: :password_digest))
272
+
273
+ user
274
+ end
102
275
  end
@@ -0,0 +1,5 @@
1
+ ##
2
+ # Data controller class. Defines authorized actions.
3
+ class AnoubisSsoServer::DataController < AnoubisSsoServer::ApplicationController
4
+
5
+ end
@@ -0,0 +1,50 @@
1
+ ##
2
+ # Index controller class. Output system actions
3
+ class AnoubisSsoServer::IndexController < AnoubisSsoServer::ApplicationController
4
+
5
+ ##
6
+ # Default dashboard action
7
+ def dashboard
8
+ result = {
9
+ result: 0,
10
+ message: I18n.t('anoubis.success'),
11
+ data: {
12
+ name: current_user.name,
13
+ surname: current_user.surname,
14
+ email: current_user.email,
15
+ id: current_user.public
16
+ }
17
+ }
18
+
19
+ render json: result
20
+ end
21
+
22
+ ##
23
+ # Output allowed menu items
24
+ def menu
25
+ result = {
26
+ result: 0,
27
+ message: I18n.t('anoubis.success'),
28
+ menu: [
29
+ {
30
+ mode: 'dashboard',
31
+ title: I18n.t('anoubis.install.menu.dashboard.title'),
32
+ page_title: I18n.t('anoubis.install.menu.dashboard.page_title'),
33
+ short_title: I18n.t('anoubis.install.menu.dashboard.short_title'),
34
+ position: 0,
35
+ tab: 0,
36
+ action: 'data',
37
+ access: 'write',
38
+ state: 'show',
39
+ parent: nil
40
+ }
41
+ ]
42
+ }
43
+
44
+ render json: result
45
+ end
46
+
47
+ def authenticate?
48
+ true
49
+ end
50
+ end
@@ -0,0 +1,84 @@
1
+ ##
2
+ # Main controller class. Defines basic internal SSO actions.
3
+ class AnoubisSsoServer::MainController < AnoubisSsoServer::ApplicationController
4
+ ##
5
+ # Login action for SSO server.
6
+ #
7
+ # <b>API request:</b>
8
+ # GET /api/<version>/login
9
+ #
10
+ # <b>Parameters:</b>
11
+ # - <b>login</b> (String) --- user email address <i>(required field)</i>
12
+ # - <b>password</b> (String) --- user password <i>(required field)</i>
13
+ # - <b>locale</b> (String) --- the output language locale <i>(optional value)</i>
14
+ # - <b>code</b> (String) --- login code for redirect <i>(optional value, default: 0)</i>
15
+ #
16
+ # <b>Request example:</b>
17
+ # curl --header "Content-Type: application/json" http://<server>:<port>/api/<api-version>/login=admin@example.com&password=password&locale=en
18
+ #
19
+ # <b>Results:</b>
20
+ #
21
+ # Resulting data returns as redirect to silent URL with login result.
22
+
23
+ def login
24
+ redirect_url = sso_silent_url
25
+ redirect_url += redirect_url.index('?') ? '&' : '?'
26
+
27
+ unless params[:login]
28
+ redirect_to redirect_url + 'error=' + ERB::Util.url_encode(I18n.t('anoubis.errors.fields.login')), { allow_other_host: true }
29
+ return
30
+ end
31
+
32
+ unless params[:password]
33
+ redirect_to redirect_url + 'error=' + ERB::Util.url_encode(I18n.t('anoubis.errors.fields.password')), { allow_other_host: true }
34
+ return
35
+ end
36
+
37
+ usr = user_model.where(email: params[:login]).first
38
+
39
+ unless usr
40
+ redirect_to redirect_url + 'error=' + ERB::Util.url_encode(I18n.t('anoubis.errors.incorrect_login')), { allow_other_host: true }
41
+ return
42
+ end
43
+
44
+ unless usr.authenticate(params[:password])
45
+ redirect_to redirect_url + 'error=' + ERB::Util.url_encode(I18n.t('anoubis.errors.incorrect_login')), { allow_other_host: true }
46
+ return
47
+ end
48
+
49
+ self.current_system = get_current_system
50
+
51
+ unless current_system
52
+ redirect_to redirect_url + 'error=' + ERB::Util.url_encode(I18n.t('anoubis.errors.system_not_defined')), { allow_other_host: true }
53
+ return
54
+ end
55
+
56
+ code = nil
57
+ if params[:code]
58
+ begin
59
+ code = JSON.parse(self.redis.get("#{self.redis_prefix}login_code:#{params[:code]}"),{ symbolize_names: true })
60
+ rescue
61
+
62
+ end
63
+ end
64
+
65
+ session_name = SecureRandom.uuid
66
+ session = {
67
+ id: usr.id,
68
+ uuid: usr.uuid,
69
+ ttl: Time.now.utc.to_i + current_system[:ttl],
70
+ timeout: current_system[:ttl]
71
+ }
72
+
73
+ cookies[:oauth_session] = session_name
74
+ redis.set("#{redis_prefix}session:#{session_name}", session.to_json, ex: 86400)
75
+
76
+ unless code
77
+ redirect_to redirect_url + "code=0", { allow_other_host: true }
78
+ else
79
+ auth_code = SecureRandom.uuid
80
+ redis.set("#{redis_prefix}auth_code:#{auth_code}", params[:code], ex: 600)
81
+ redirect_to redirect_url + "code=#{auth_code}", { allow_other_host: true }
82
+ end
83
+ end
84
+ end