mumukit-login 1.0.0 → 1.2.0

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
  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