anoubis_sso_server 0.1.0 → 1.0.2
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 +4 -4
- data/.env.sample +3 -0
- data/.rspec +2 -1
- data/.ruby-version +1 -1
- data/CHANGELOG.md +8 -2
- data/Gemfile +15 -3
- data/README.md +93 -6
- data/Rakefile +3 -0
- data/app/controllers/anoubis_sso_server/application_controller.rb +292 -0
- data/app/controllers/anoubis_sso_server/data_controller.rb +5 -0
- data/app/controllers/anoubis_sso_server/index_controller.rb +50 -0
- data/app/controllers/anoubis_sso_server/main_controller.rb +126 -0
- data/app/controllers/anoubis_sso_server/open_id_controller.rb +320 -0
- data/app/models/anoubis_sso_server/application_record.rb +5 -0
- data/app/models/anoubis_sso_server/system.rb +68 -0
- data/app/models/anoubis_sso_server/user.rb +112 -0
- data/config/locales/en.yml +14 -0
- data/config/locales/ru.yml +14 -0
- data/config/routes.rb +23 -0
- data/db/migrate/20220214112633_create_anoubis_sso_server_users.rb +19 -0
- data/db/migrate/20220214112748_create_anoubis_sso_server_systems.rb +17 -0
- data/lib/anoubis_sso_server/engine.rb +13 -0
- data/lib/anoubis_sso_server/version.rb +2 -1
- data/lib/anoubis_sso_server.rb +5 -4
- data/sig/anoubis_sso_server.rbs +6 -0
- metadata +216 -10
- data/.idea/.gitignore +0 -6
- data/.idea/anoubis_sso_server.iml +0 -17
- data/.idea/inspectionProfiles/Project_Default.xml +0 -6
- data/.idea/modules.xml +0 -8
- data/.idea/vcs.xml +0 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0148b84eeebcb0d63e3959c2bd2fe28baeae62a2f223d4e314b5fd3a9e4a9401'
|
4
|
+
data.tar.gz: 13ca48de82c3d0028bfe0e1954324a404f7a6db95ff7d2388d1c9772d8e4414a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bf848a61c3f01f4e1e5effa132c0d1a88a72a0f4f550fa00819aacb9482658d6ee2094b694849bb1742054c041eb37d0c1e6f9fe7b1798e26ae113907aed25e5
|
7
|
+
data.tar.gz: bedcc154d4636babacc398b3e86ac141bf7898013436104c8c27355cf30efd20c12726cae5f8812844d1bb7855e94dec425ad9fce2cc7257331a361296e8fc75
|
data/.env.sample
ADDED
data/.rspec
CHANGED
data/.ruby-version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
ruby-
|
1
|
+
ruby-3.0.0
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
@@ -5,8 +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
|
-
|
15
|
+
#group :development, :test do
|
16
|
+
# gem "rspec-rails"
|
17
|
+
#gem "factory_bot_rails"
|
18
|
+
#end
|
11
19
|
|
12
|
-
|
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
|
-
|
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
|
-
|
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,9 +103,23 @@ 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
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
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).
|
36
123
|
|
37
124
|
## License
|
38
125
|
|
@@ -40,4 +127,4 @@ The gem is available as open source under the terms of the [MIT License](https:/
|
|
40
127
|
|
41
128
|
## Code of Conduct
|
42
129
|
|
43
|
-
Everyone interacting in the AnoubisSsoServer project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/
|
130
|
+
Everyone interacting in the AnoubisSsoServer project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/RA-Company/anoubis_sso_server/blob/master/CODE_OF_CONDUCT.md).
|
data/Rakefile
CHANGED
@@ -0,0 +1,292 @@
|
|
1
|
+
##
|
2
|
+
# Main application class inherited from {https://www.rubydoc.info/gems/anoubis/Anoubis/ApplicationController Anoubis::ApplicationController}
|
3
|
+
class AnoubisSsoServer::ApplicationController < Anoubis::ApplicationController
|
4
|
+
## Selected SSO system
|
5
|
+
attr_accessor :current_system
|
6
|
+
|
7
|
+
## Returns main SSO server URL.
|
8
|
+
attr_accessor :sso_server
|
9
|
+
|
10
|
+
## Returns SSO Login URL used for redirect when user isn't logged in.
|
11
|
+
attr_accessor :sso_login_url
|
12
|
+
|
13
|
+
## Returns SSO silent url used for silent refresh token.
|
14
|
+
attr_accessor :sso_silent_url
|
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
|
+
|
114
|
+
##
|
115
|
+
# Returns main SSO server URL. Link should be defined in Rails.configuration.anoubis.sso_server configuration parameter
|
116
|
+
# @return [String] link to SSO server
|
117
|
+
def sso_server
|
118
|
+
@sso_server ||= get_sso_server
|
119
|
+
end
|
120
|
+
|
121
|
+
private def get_sso_server
|
122
|
+
begin
|
123
|
+
value = Rails.configuration.anoubis_sso_server
|
124
|
+
rescue StandardError
|
125
|
+
value = ''
|
126
|
+
render json: { error: 'Please setup Rails.configuration.anoubis_sso_server configuration variable' }
|
127
|
+
end
|
128
|
+
|
129
|
+
value
|
130
|
+
end
|
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
|
+
|
149
|
+
##
|
150
|
+
# Returns SSO Login URL used for redirect when user isn't logged in.
|
151
|
+
# Link can be redefined in Rails.configuration.anoubis_sso_login_url configuration parameter. If this variable isn't defined
|
152
|
+
# URL wil be defined as {sso_server}login
|
153
|
+
# @return [String] SSO login URL
|
154
|
+
def sso_login_url
|
155
|
+
@sso_login_url ||= get_sso_login_url
|
156
|
+
end
|
157
|
+
|
158
|
+
private def get_sso_login_url
|
159
|
+
begin
|
160
|
+
value = Rails.configuration.anoubis_sso_login_url
|
161
|
+
rescue
|
162
|
+
value = sso_server + 'login'
|
163
|
+
end
|
164
|
+
|
165
|
+
value
|
166
|
+
end
|
167
|
+
|
168
|
+
##
|
169
|
+
# Returns SSO silent url used for silent refresh token.
|
170
|
+
# Link can be redefined in Rails.configuration.anoubis_sso_silent_url configuration parameter. If this variable isn't defined
|
171
|
+
# URL wil be defined as {sso_server}silent.html
|
172
|
+
# @return [String] SSO login URL
|
173
|
+
def sso_silent_url
|
174
|
+
@sso_silent_url ||= get_sso_silent_url
|
175
|
+
end
|
176
|
+
|
177
|
+
private def get_sso_silent_url
|
178
|
+
begin
|
179
|
+
value = Rails.configuration.anoubis_sso_silent_url
|
180
|
+
rescue
|
181
|
+
value = sso_server + 'silent.html'
|
182
|
+
end
|
183
|
+
|
184
|
+
value
|
185
|
+
end
|
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
|
+
|
221
|
+
##
|
222
|
+
# Check current origin of header by Regexp defined in Rails.configuration.anoubis_sso_origin configuration parameter
|
223
|
+
# @return [Boolean] request host origin validation
|
224
|
+
def check_origin
|
225
|
+
return true unless request.origin
|
226
|
+
|
227
|
+
request.origin.match(sso_origin)
|
228
|
+
end
|
229
|
+
|
230
|
+
##
|
231
|
+
# Return OAUTH session for current request. Session name gets from cookies. If session present but it's timeout was expired, then session regenerated.
|
232
|
+
def get_oauth_session
|
233
|
+
if cookies.key? :oauth_session
|
234
|
+
begin
|
235
|
+
session = JSON.parse(self.redis.get("#{redis_prefix}session:#{cookies[:oauth_session]}"),{ symbolize_names: true })
|
236
|
+
rescue
|
237
|
+
cookies[:oauth_session] = nil
|
238
|
+
session = nil
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
if session
|
243
|
+
if session[:ttl] < Time.now.utc.to_i
|
244
|
+
session_name = SecureRandom.uuid
|
245
|
+
session[:ttl] = Time.now.utc.to_i + session[:timeout]
|
246
|
+
redis.del("#{redis_prefix}session:#{cookies[:oauth_session]}")
|
247
|
+
cookies[:oauth_session] = session_name
|
248
|
+
redis.set("#{redis_prefix}session:#{session_name}", session.to_json, ex: 86400)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
session
|
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
|
275
|
+
|
276
|
+
##
|
277
|
+
# Check parameters
|
278
|
+
# @param list [Array] Array of parameters to check
|
279
|
+
def check_listed_parameters(list)
|
280
|
+
list.each do |key|
|
281
|
+
return I18n.t('anoubis.errors.is_not_defined', title: key) unless params.key? key.to_sym
|
282
|
+
|
283
|
+
return I18n.t('anoubis.errors.is_not_correct', title: key) unless params[key.to_sym]
|
284
|
+
|
285
|
+
params[key.to_sym].strip!
|
286
|
+
|
287
|
+
return I18n.t('anoubis.errors.is_not_correct', title: key) if params[key.to_sym] == ''
|
288
|
+
end
|
289
|
+
|
290
|
+
nil
|
291
|
+
end
|
292
|
+
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
|