mumukit-login 1.0.0 → 1.2.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: e9469b5574895337bee449aca6ffb6a5be57ee70
4
- data.tar.gz: f2bc55e4e42e7c7d0b8925400b8ceb16387acd1b
3
+ metadata.gz: 3678ef51cc61d88246d5a1818182167602ae3c25
4
+ data.tar.gz: fc66ab10f742d4b78e3c1722c311d55d79c2cc17
5
5
  SHA512:
6
- metadata.gz: cc7eaf5d94e79e2bb5a1f76659507e9e43bcb44c9b35536e1c1ae340a6503d025b267b3023168b1273a05c92b3d83ff434052d1b6d364203e97236c207808c59
7
- data.tar.gz: 8e7c0fdb09272ddff505c397fc37b65ebffa1e1d45d390970a88a88ca21f9f66c0f8ac3e5c752cf67c32cb87e4184e09631e4d364afa22fe49301f01b8169ddf
6
+ metadata.gz: d0713e822bd8489d7bc867bc59bcbebe54c89b78a7c2ae908b23fbfa9e300e43e41e85c208d947e8da023e07a389d21048b4f77e7639872ed4a1bfd699a655d9
7
+ data.tar.gz: bfc5368cf2f9a2019d789cddc63ac199f4dcce260d1acfecf906a1a4cace493d8d97f8e3edc13fc054ce18b20736d297541b92258a15540c499470090de7a4aa
data/lib/mumukit/login.rb CHANGED
@@ -6,6 +6,7 @@ require 'omniauth-auth0'
6
6
  require 'omniauth-saml'
7
7
 
8
8
  require 'mumukit/core'
9
+ require 'mumukit/auth'
9
10
 
10
11
  module Mumukit::Login
11
12
  def self.configure
@@ -15,6 +16,11 @@ module Mumukit::Login
15
16
 
16
17
  def self.defaults
17
18
  struct.tap do |config|
19
+ config.mucookie_domain = ENV['MUMUKI_COOKIES_DOMAIN'] || ENV['MUMUKI_MUCOOKIE_DOMAIN']
20
+ config.mucookie_secret_key = ENV['SECRET_KEY_BASE'] || ENV['MUMUKI_MUCOOKIE_SECRET_KEY']
21
+ config.mucookie_secret_salt = ENV['MUMUKI_MUCOOKIE_SECRET_SALT'] || 'mucookie secret salt'
22
+ config.mucookie_sign_salt = ENV['MUMUKI_MUCOOKIE_SIGN_KEY'] || 'mucookie sign salt'
23
+
18
24
  config.provider = Mumukit::Login::Provider.from_env
19
25
  config.saml = struct base_url: ENV['MUMUKI_SAML_BASE_URL'],
20
26
  idp_sso_target_url: ENV['MUMUKI_SAML_IDP_SSO_TARGET_URL'],
@@ -34,9 +40,10 @@ module Mumukit::Login
34
40
  end
35
41
 
36
42
  require_relative './login/controller'
37
- require_relative './login/current_user_store'
43
+ require_relative './login/shared_session'
38
44
  require_relative './login/form'
39
45
  require_relative './login/framework'
46
+ require_relative './login/mucookie'
40
47
  require_relative './login/origin_redirector'
41
48
  require_relative './login/profile'
42
49
  require_relative './login/provider'
@@ -82,3 +89,8 @@ module Mumukit::Login
82
89
  Mumukit::Login.config.provider
83
90
  end
84
91
  end
92
+
93
+ Mumukit::Auth.configure do |config|
94
+ config.clients.mucookie = {id: ENV['MUMUKI_MUCOOKIE_CLIENT_ID'],
95
+ secret: ENV['MUMUKI_MUCOOKIE_SECRET']}
96
+ end
@@ -4,14 +4,30 @@ class Mumukit::Login::Controller
4
4
  @native = native
5
5
  end
6
6
 
7
- def current_user_store
7
+ def shared_session
8
8
  if env['HTTP_AUTHORIZATION']
9
- Mumukit::Login::JWTCurrentUserStore.new self
9
+ Mumukit::Login::TokenSharedSession.new env
10
10
  else
11
- Mumukit::Login::SessionCurrentUserStore.new self
11
+ Mumukit::Login::MucookieSharedSession.new mucookie
12
12
  end
13
13
  end
14
14
 
15
+ def mucookie
16
+ @mucookie ||= Mumukit::Login::Mucookie.new self
17
+ end
18
+
19
+ def url_for(path)
20
+ URI.join(request.base_url, path).to_s
21
+ end
22
+
23
+ def request
24
+ Rack::Request.new(env)
25
+ end
26
+
27
+ def session
28
+ request.session
29
+ end
30
+
15
31
  def env
16
32
  @framework.env @native
17
33
  end
@@ -24,15 +40,15 @@ class Mumukit::Login::Controller
24
40
  @framework.render_html!(html, @native)
25
41
  end
26
42
 
27
- def url_for(path)
28
- URI.join(request.base_url, path).to_s
43
+ def write_cookie!(key, value)
44
+ @framework.write_cookie! key, value, @native
29
45
  end
30
46
 
31
- def request
32
- Rack::Request.new(env)
47
+ def read_cookie(key)
48
+ @framework.read_cookie key, @native
33
49
  end
34
50
 
35
- def session
36
- request.session
51
+ def delete_cookie!(key, domain)
52
+ @framework.delete_cookie! key, domain, @native
37
53
  end
38
- end
54
+ end
@@ -1,9 +1,26 @@
1
1
  module Mumukit::Login::Framework::Rails
2
-
3
2
  def self.env(rails_controller)
4
3
  rails_controller.request.env
5
4
  end
6
5
 
6
+ def self.write_cookie!(key, value, rails_controller)
7
+ rails_controller.instance_eval do
8
+ cookies[key] = value
9
+ end
10
+ end
11
+
12
+ def self.delete_cookie!(key, domain, rails_controller)
13
+ rails_controller.instance_eval do
14
+ cookies.delete key, domain: domain
15
+ end
16
+ end
17
+
18
+ def self.read_cookie(key, rails_controller)
19
+ rails_controller.instance_eval do
20
+ cookies[key]
21
+ end
22
+ end
23
+
7
24
  def self.redirect!(path, rails_controller)
8
25
  rails_controller.redirect_to path
9
26
  end
@@ -1,9 +1,20 @@
1
1
  module Mumukit::Login::Framework::Sinatra
2
-
3
2
  def self.env(sinatra_handler)
4
3
  sinatra_handler.request.env
5
4
  end
6
5
 
6
+ def self.write_cookie!(key, value, sinatra_handler)
7
+ sinatra_handler.response.set_cookie key, value
8
+ end
9
+
10
+ def self.delete_cookie!(key, domain, sinatra_handler)
11
+ sinatra_handler.response.delete_cookie key, domain: domain
12
+ end
13
+
14
+ def self.read_cookie(key, sinatra_handler)
15
+ sinatra_handler.request.cookies[key]
16
+ end
17
+
7
18
  def self.redirect!(path, sinatra_handler)
8
19
  sinatra_handler.redirect path
9
20
  end
@@ -16,7 +16,7 @@ module Mumukit::Login::AuthenticationHelpers
16
16
 
17
17
  # default
18
18
  def current_user_uid
19
- mumukit_controller.current_user_store.get_uid
19
+ mumukit_controller.shared_session.uid
20
20
  end
21
21
 
22
22
  # default
@@ -1,9 +1,9 @@
1
1
  module Mumukit::Login::LoginControllerHelpers
2
2
 
3
3
  def login_current_user!
4
- origin_redirector.save_location!
4
+ origin_redirector.save_after_login_location!
5
5
  if current_user?
6
- origin_redirector.redirect!
6
+ origin_redirector.redirect_after_login!
7
7
  else
8
8
  login_provider.request_authentication! mumukit_controller, login_settings
9
9
  end
@@ -13,25 +13,28 @@ module Mumukit::Login::LoginControllerHelpers
13
13
  profile = Mumukit::Login::Profile.from_omniauth(mumukit_controller.env['omniauth.auth'])
14
14
  user = Mumukit::Login.config.user_class.for_profile profile
15
15
  save_current_user_session! user
16
- origin_redirector.redirect!
16
+ origin_redirector.redirect_after_login!
17
17
  end
18
18
 
19
19
  def logout_current_user!
20
20
  destroy_current_user_session!
21
- mumukit_controller.redirect! login_provider.logout_redirection_path
21
+ origin_redirector.redirect_after_logout!
22
22
  end
23
23
 
24
24
  private
25
25
 
26
26
  # default
27
27
  def destroy_current_user_session!
28
- mumukit_controller.current_user_store.clear!
28
+ mumukit_controller.session.clear
29
+ mumukit_controller.shared_session.clear!
29
30
  end
30
31
 
31
32
  # default
32
33
  def save_current_user_session!(user)
33
- mumukit_controller.current_user_store.set! user.uid,
34
- user_name: user.name,
35
- user_image_url: user.image_url
34
+ mumukit_controller.shared_session.tap do |it|
35
+ it.uid = user.uid
36
+ it.profile = {user_name: user.name,
37
+ user_image_url: user.image_url}
38
+ end
36
39
  end
37
40
  end
@@ -0,0 +1,80 @@
1
+ require 'active_support/key_generator'
2
+
3
+ class Mumukit::Login::Mucookie
4
+ def initialize(controller)
5
+ @controller = controller
6
+ end
7
+
8
+ def write!(key, value, options={})
9
+ @controller.write_cookie! cookie_name(key),
10
+ value: value.to_s,
11
+ path: '/',
12
+ domain: Mumukit::Login.config.mucookie_domain,
13
+ httponly: !!options[:httponly]
14
+ end
15
+
16
+ def encrypt_and_write!(key, value, options={})
17
+ write! key, Encryptor.encrypt(value), options
18
+ end
19
+
20
+ def encode_and_write!(key, value, options={})
21
+ write! key, Base64.encode64(value), options
22
+ end
23
+
24
+ def read(key)
25
+ @controller.read_cookie cookie_name(key)
26
+ end
27
+
28
+ def decrypt_and_read(key)
29
+ Encryptor.decrypt read(key)
30
+ end
31
+
32
+ def decode_and_read(key)
33
+ Base64.decode64 read(key)
34
+ end
35
+
36
+ def delete!(key)
37
+ @controller.delete_cookie! cookie_name(key), Mumukit::Login.config.mucookie_domain
38
+ end
39
+
40
+ private
41
+
42
+ def cookie_name(key)
43
+ "mucookie_#{key}"
44
+ end
45
+
46
+ module Encryptor
47
+ def self.key_generator
48
+ @key_generator ||= begin
49
+ secret_key = Mumukit::Login.config.mucookie_secret_key
50
+
51
+ raise 'missing Mumukit::Login.config.mucookie_secret_key' unless secret_key
52
+
53
+ ActiveSupport::CachingKeyGenerator.new(ActiveSupport::KeyGenerator.new(secret_key, iterations: 1000))
54
+ end
55
+ end
56
+
57
+ def self.encryptor
58
+ @encryptor ||= begin
59
+ mucookie_secret_salt = Mumukit::Login.config.mucookie_secret_salt
60
+ mucookie_sign_salt = Mumukit::Login.config.mucookie_sign_salt
61
+
62
+ raise 'missing Mumukit::Login.config.mucookie_secret_salt' unless mucookie_secret_salt
63
+ raise 'missing Mumukit::Login.config.mucookie_sign_salt' unless mucookie_sign_salt
64
+
65
+ secret = key_generator.generate_key(mucookie_secret_salt)
66
+ signature = key_generator.generate_key(mucookie_sign_salt)
67
+ ActiveSupport::MessageEncryptor.new(secret, signature)
68
+ end
69
+ end
70
+
71
+ def self.encrypt(value)
72
+ encryptor.encrypt_and_sign value
73
+ end
74
+
75
+ def self.decrypt(value)
76
+ value.try { |it| encryptor.decrypt_and_verify it }
77
+ end
78
+ end
79
+
80
+ end
@@ -3,19 +3,23 @@ class Mumukit::Login::OriginRedirector
3
3
  @controller = controller
4
4
  end
5
5
 
6
- def redirect!
6
+ def redirect_after_login!
7
7
  location = @controller.session[:redirect_after_login]
8
8
  @controller.session[:redirect_after_login] = nil
9
9
  @controller.redirect!(location || '/')
10
10
  end
11
11
 
12
- def save_location!
13
- @controller.session[:redirect_after_login] = Addressable::URI.heuristic_parse(origin).path
12
+ def redirect_after_logout!
13
+ @controller.redirect! origin
14
+ end
15
+
16
+ def save_after_login_location!
17
+ @controller.session[:redirect_after_login] = origin
14
18
  end
15
19
 
16
20
  private
17
21
 
18
22
  def origin
19
- @controller.request.params['origin'] || '/'
23
+ Addressable::URI.heuristic_parse(@controller.request.params['origin'] || '/').to_s
20
24
  end
21
25
  end
@@ -1,8 +1,6 @@
1
1
  module Mumukit::Login::Provider
2
2
  def self.from_env
3
- parse_login_provider(login_provider_string).tap do |provider|
4
- puts "[Mumukit::Login] Using #{provider} as login provider"
5
- end
3
+ parse_login_provider(login_provider_string)
6
4
  end
7
5
 
8
6
  def self.login_provider_string
@@ -0,0 +1,2 @@
1
+ require_relative './shared_session/mucookie_shared_session'
2
+ require_relative './shared_session/token_shared_session'
@@ -0,0 +1,44 @@
1
+ require 'base64'
2
+
3
+ class Mumukit::Login::MucookieSharedSession
4
+
5
+ def initialize(mucookie)
6
+ @mucookie = mucookie
7
+ end
8
+
9
+ def uid
10
+ @mucookie.decrypt_and_read :session
11
+ end
12
+
13
+ def uid=(uid)
14
+ @mucookie.encrypt_and_write! :session, uid, httponly: true
15
+ end
16
+
17
+ def profile
18
+ JSON.parse @mucookie.decode_and_read(:profile)
19
+ end
20
+
21
+ def profile=(profile)
22
+ @mucookie.encode_and_write! :profile, profile.to_json
23
+ end
24
+
25
+ def current_organization_name=(organization_name)
26
+ @mucookie.write! :organization, organization_name
27
+ end
28
+
29
+ def clear!
30
+ @mucookie.delete! :profile
31
+ @mucookie.delete! :organization
32
+ @mucookie.delete! :session
33
+ end
34
+
35
+ private
36
+
37
+ def decode_session(uid)
38
+ end
39
+
40
+ def decode_token(uid)
41
+ Mumukit::Auth::Token.encode uid, {exp: Mumukit::Login.config.session_duration.days.from_now}, encoding_client
42
+ end
43
+
44
+ end
@@ -0,0 +1,23 @@
1
+ class Mumukit::Login::TokenSharedSession
2
+ def initialize(env)
3
+ @env = env
4
+ end
5
+
6
+ def uid
7
+ token.uid
8
+ end
9
+
10
+ %w(uid= profile= current_organization_name= clear!).each do |it|
11
+ define_method it do
12
+ raise 'JWT tokens are read-only'
13
+ end
14
+ end
15
+
16
+ def token
17
+ @token ||= Mumukit::Auth::Token.decode_header(authorization_header).tap(&:verify_client!)
18
+ end
19
+
20
+ def authorization_header
21
+ @env['HTTP_AUTHORIZATION']
22
+ end
23
+ end
@@ -1,5 +1,5 @@
1
1
  module Mumukit
2
2
  module Login
3
- VERSION = "1.0.0"
3
+ VERSION = "1.2.0"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mumukit-login
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Franco Leonardo Bulgarelli
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-02-09 00:00:00.000000000 Z
11
+ date: 2017-02-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -164,6 +164,20 @@ dependencies:
164
164
  - - "~>"
165
165
  - !ruby/object:Gem::Version
166
166
  version: '0.5'
167
+ - !ruby/object:Gem::Dependency
168
+ name: mumukit-auth
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - "~>"
172
+ - !ruby/object:Gem::Version
173
+ version: '6.1'
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - "~>"
179
+ - !ruby/object:Gem::Version
180
+ version: '6.1'
167
181
  description:
168
182
  email:
169
183
  - franco@mumuki.org
@@ -173,7 +187,6 @@ extra_rdoc_files: []
173
187
  files:
174
188
  - lib/mumukit/login.rb
175
189
  - lib/mumukit/login/controller.rb
176
- - lib/mumukit/login/current_user_store.rb
177
190
  - lib/mumukit/login/form.rb
178
191
  - lib/mumukit/login/framework.rb
179
192
  - lib/mumukit/login/framework/rails.rb
@@ -183,6 +196,7 @@ files:
183
196
  - lib/mumukit/login/helpers/authorization_helpers.rb
184
197
  - lib/mumukit/login/helpers/login_controller_helpers.rb
185
198
  - lib/mumukit/login/helpers/user_permissions_helpers.rb
199
+ - lib/mumukit/login/mucookie.rb
186
200
  - lib/mumukit/login/origin_redirector.rb
187
201
  - lib/mumukit/login/profile.rb
188
202
  - lib/mumukit/login/provider.rb
@@ -191,6 +205,9 @@ files:
191
205
  - lib/mumukit/login/provider/developer.rb
192
206
  - lib/mumukit/login/provider/saml.rb
193
207
  - lib/mumukit/login/settings.rb
208
+ - lib/mumukit/login/shared_session.rb
209
+ - lib/mumukit/login/shared_session/mucookie_shared_session.rb
210
+ - lib/mumukit/login/shared_session/token_shared_session.rb
194
211
  - lib/mumukit/login/version.rb
195
212
  homepage: http://github.com/mumuki/mumukit-login
196
213
  licenses:
@@ -212,7 +229,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
212
229
  version: '0'
213
230
  requirements: []
214
231
  rubyforge_project:
215
- rubygems_version: 2.5.1
232
+ rubygems_version: 2.4.5
216
233
  signing_key:
217
234
  specification_version: 4
218
235
  summary: Library for login mumuki requests
@@ -1,44 +0,0 @@
1
- class Mumukit::Login::SessionCurrentUserStore
2
- def initialize(controller)
3
- @controller = controller
4
- end
5
-
6
- def get_uid
7
- @controller.session[:user_uid]
8
- end
9
-
10
- def clear!
11
- @controller.session[:user_uid] = nil
12
- end
13
-
14
- def set!(uid, values)
15
- @controller.session[:user_uid] = uid
16
- values.each { |k, v| @controller.session[k] = v }
17
- end
18
- end
19
-
20
- class Mumukit::Login::JWTCurrentUserStore
21
- def initialize(controller)
22
- @controller = controller
23
- end
24
-
25
- def get_uid
26
- token.uid
27
- end
28
-
29
- def clear!
30
- raise 'JWT tokens are read-only'
31
- end
32
-
33
- def set!(*)
34
- raise 'JWT tokens are read-only'
35
- end
36
-
37
- def token
38
- @token ||= Mumukit::Auth::Token.decode_header(authorization_header).tap(&:verify_client!)
39
- end
40
-
41
- def authorization_header
42
- @controller.env['HTTP_AUTHORIZATION']
43
- end
44
- end