anoubis_sso_server 0.1.1 → 1.0.5

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: 756380520fc961ba7aaa7b12dc87efc34f4a598413677ea465392ebb355b9e70
4
+ data.tar.gz: eac01982f78ac39f0777d6579174c83eb0005a19fc9716f4f706ac006a0a9aa4
5
5
  SHA512:
6
- metadata.gz: c5aa132b85b183c6adfb7f8792ca7d0344ef7eeda50da33931b361bb71b4f79c6c5d39e29ed2663d2335226f700d87d7458f6195182b1c12359f4882dc5a319e
7
- data.tar.gz: 9228457e5c5aa6b85fe6682cd407a1b1e7c076f2cb4f069ecff9dab9792e579b33079eb370ca7f1eb1d21d64de127429d1c0a745b7f1addabfc7f3cffc5a20bf
6
+ metadata.gz: 1f64317d742c45171e135251f77d0207b9dae0434db471d0e4247be6c8f33a2b4ee526697c82756765063e16224d94e611aa356730e3f48c3cd952ada4014f73
7
+ data.tar.gz: 70728997ed2c5bed827e84751ecff752b8264c5a5629c6b9e2832c3e0e1203ab1f35ec01a1b43a29d52e1c66fd6b215539dc7222d6af8f008d256f5d04a44ba8
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,10 @@
1
- ## [Unreleased]
1
+ ## [Released]
2
2
 
3
- ## [0.1.0] - 2022-01-28
3
+ ## [1.0.2] - 2022-02-28
4
+ - Action /api/1/auth was added.
5
+
6
+ ## [1.0.1] - 2022-02-27
7
+ - Library was released.
8
+
9
+ ## [1.0.0] - 2022-01-28
4
10
  - 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'
@@ -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,110 @@ 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('anoubis.errors.access_not_allowed') })
42
+ return
43
+ end
44
+
45
+ if authenticate?
46
+ if authentication
47
+ if check_menu_access?
48
+ return if !menu_access params[:controller]
49
+ end
50
+ end
51
+ end
52
+
53
+ after_sso_server_initialization
54
+ end
55
+
56
+ ##
57
+ # Procedure fires after initializes all basic parameters of {AnoubisSsoServer::ApplicationController}
58
+ def after_sso_server_initialization
59
+ #puts etc.inspect
60
+ end
61
+
62
+ ##
63
+ # Check for site access. By default return true.
64
+ def access_allowed?
65
+ true
66
+ end
67
+
68
+ ##
69
+ # Checks if needed user authentication.
70
+ # @return [Boolean] if true, then user must be authenticated. By default application do not need authorization.
71
+ def authenticate?
72
+ false
73
+ end
74
+
75
+
76
+ ##
77
+ # Procedure authenticates user in the system
78
+ def authentication
79
+ session = get_oauth_session
80
+
81
+ unless session
82
+ render_error_exit code: -2, error: I18n.t('anoubis.errors.session_expired')
83
+ return
84
+ end
85
+
86
+ self.current_user = get_user_by_uuid session[:uuid]
87
+
88
+ unless current_user
89
+ self.redis.del("#{redis_prefix}session:#{cookies[:oauth_session]}")
90
+ cookies[:oauth_session] = nil
91
+ render_error_exit code: -3, error: I18n.t('anoubis.errors.incorrect_user')
92
+ return
93
+ end
94
+ end
95
+
96
+ ##
97
+ # Gracefully terminate script execution with code 422 (Unprocessable entity). And JSON data
98
+ # @param data [Hash] Resulting data
99
+ # @option data [Integer] :code resulting error code
100
+ # @option data [String] :error resulting error message
101
+ def render_error_exit(data = {})
102
+ result = {
103
+ result: -1,
104
+ message: I18n.t('anoubis.error')
105
+ }
106
+
107
+ result[:result] = data[:code] if data.has_key? :code
108
+ result[:message] = data[:error] if data.has_key? :error
109
+
110
+
111
+ render json: result, status: :unprocessable_entity
112
+
113
+ begin
114
+ exit
115
+ rescue SystemExit => e
116
+ puts result[:message]
117
+ end
118
+ end
119
+
15
120
  ##
16
121
  # Returns main SSO server URL. Link should be defined in Rails.configuration.anoubis.sso_server configuration parameter
17
122
  # @return [String] link to SSO server
@@ -30,6 +135,23 @@ class AnoubisSsoServer::ApplicationController < Anoubis::ApplicationController
30
135
  value
31
136
  end
32
137
 
138
+ ##
139
+ # Returns SSO origin. Variable should be defined in Rails.configuration.anoubis.sso_origin configuration parameter
140
+ # @return [Regexp] regexp for check site origin
141
+ def sso_origin
142
+ @sso_origin ||= get_sso_origin
143
+ end
144
+
145
+ private def get_sso_origin
146
+ begin
147
+ value = Rails.configuration.anoubis_sso_origin
148
+ rescue StandardError
149
+ value = /^.*$/
150
+ end
151
+
152
+ value
153
+ end
154
+
33
155
  ##
34
156
  # Returns SSO Login URL used for redirect when user isn't logged in.
35
157
  # Link can be redefined in Rails.configuration.anoubis_sso_login_url configuration parameter. If this variable isn't defined
@@ -68,11 +190,47 @@ class AnoubisSsoServer::ApplicationController < Anoubis::ApplicationController
68
190
  value
69
191
  end
70
192
 
193
+ ##
194
+ # Returns SSO User model.
195
+ # Can be redefined in Rails.application configuration_anoubis_sso_user_model configuration parameter.
196
+ # By default returns {AnoubisSsoServer::User} model class
197
+ # @return [Class] User model class
198
+ def user_model
199
+ @user_model ||= get_user_model
200
+ end
201
+
202
+ private def get_user_model
203
+ begin
204
+ value = Object.const_get Rails.configuration.anoubis_sso_user_model
205
+ rescue
206
+ value = AnoubisSsoServer::User
207
+ end
208
+
209
+ value
210
+ end
211
+
212
+ ##
213
+ # Returns current SSO system data
214
+ # @param system_title [String] - System public UUID parameter. By default load from Rails.application configuration_anoubis_sso_system configuration parameter.
215
+ # @return [AnoubisSsoServer::System] current SSO system
216
+ def get_current_system(system_title = nil)
217
+ begin
218
+ system_title = Rails.configuration.anoubis_sso_system unless system_title
219
+ system = AnoubisSsoServer::System.new(JSON.parse(redis.get("#{redis_prefix}system:#{system_title}"),{ symbolize_names: true }))
220
+ rescue
221
+ system = nil
222
+ end
223
+
224
+ system
225
+ end
226
+
71
227
  ##
72
228
  # Check current origin of header by Regexp defined in Rails.configuration.anoubis_sso_origin configuration parameter
73
229
  # @return [Boolean] request host origin validation
74
230
  def check_origin
75
- request.headers['origin'].match(Rails.configuration.anoubis_sso_origin)
231
+ return true unless request.origin
232
+
233
+ request.origin.match(sso_origin)
76
234
  end
77
235
 
78
236
  ##
@@ -93,10 +251,48 @@ class AnoubisSsoServer::ApplicationController < Anoubis::ApplicationController
93
251
  session[:ttl] = Time.now.utc.to_i + session[:timeout]
94
252
  redis.del("#{redis_prefix}session:#{cookies[:oauth_session]}")
95
253
  cookies[:oauth_session] = session_name
96
- redis.set("#{redis_prefix}session:#{session_name}", session.to_json, { ex: 86400 })
254
+ redis.set("#{redis_prefix}session:#{session_name}", session.to_json, ex: 86400)
97
255
  end
98
256
  end
99
257
 
100
258
  session
101
259
  end
260
+
261
+ ##
262
+ # 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.
263
+ # @param uuid [String] UUID of user
264
+ # @return [Class] Returns user class
265
+ def get_user_by_uuid(uuid)
266
+ begin
267
+ user = user_model.new JSON.parse(redis.get("#{redis_prefix}user:#{uuid}"),{ symbolize_names: true })
268
+ rescue
269
+ user = nil
270
+ end
271
+
272
+ return user if user
273
+
274
+ user = user_model.where(uuid: uuid).first
275
+ return nil unless user
276
+
277
+ redis.set("#{redis_prefix}user:#{uuid}", user.to_json(except: :password_digest))
278
+
279
+ user
280
+ end
281
+
282
+ ##
283
+ # Check parameters
284
+ # @param list [Array] Array of parameters to check
285
+ def check_listed_parameters(list)
286
+ list.each do |key|
287
+ return I18n.t('anoubis.errors.is_not_defined', title: key) unless params.key? key.to_sym
288
+
289
+ return I18n.t('anoubis.errors.is_not_correct', title: key) unless params[key.to_sym]
290
+
291
+ params[key.to_sym].strip!
292
+
293
+ return I18n.t('anoubis.errors.is_not_correct', title: key) if params[key.to_sym] == ''
294
+ end
295
+
296
+ nil
297
+ end
102
298
  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,126 @@
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("#{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
+
85
+ ##
86
+ # Procedure check current login status of user and redirect to URL used for call /openid/oauth2/auth.
87
+ def auth
88
+ redirect_url = sso_silent_url
89
+ redirect_url += redirect_url.index('?') ? '&' : '?'
90
+
91
+ err = check_listed_parameters %w[code]
92
+
93
+ if err
94
+ redirect_to redirect_url + 'error=' + ERB::Util.url_encode(err), { allow_other_host: true }
95
+ return
96
+ end
97
+
98
+ begin
99
+ session = JSON.parse(redis.get("#{redis_prefix}session:#{cookies[:oauth_session]}"), { symbolize_names: true })
100
+ rescue StandardError
101
+ session = nil
102
+ cookies[:oauth_session] = nil
103
+ end
104
+
105
+ unless session
106
+ redirect_to redirect_url + 'error=' + ERB::Util.url_encode(I18n.t('anoubis.errors.session_expired')), { allow_other_host: true }
107
+ return
108
+ end
109
+
110
+ begin
111
+ auth_code = redis.get("#{redis_prefix}auth_code:#{params[:code]}")
112
+ code = JSON.parse(redis.get("#{redis_prefix}login_code:#{auth_code}"), { symbolize_names: true })
113
+ rescue StandardError
114
+ code = nil
115
+ end
116
+
117
+ unless code
118
+ redirect_to redirect_url + 'error=' + ERB::Util.url_encode(I18n.t('anoubis.errors.is_not_correct', title: 'code')), { allow_other_host: true }
119
+ return
120
+ end
121
+
122
+ self.redis.del("#{redis_prefix}auth_code:#{params[:code]}")
123
+ self.redis.del("#{redis_prefix}login_code:#{auth_code}")
124
+ redirect_to code[:original_url], { allow_other_host: true }
125
+ end
126
+ end