sinatra-portier 1.5.2 → 2.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: cbb567b7fdc34ac49a53113b97b08a27b52c2fd1e85552c2ea44eb7cabfc9666
4
- data.tar.gz: 3528e61f4a6fdc75ed3d2aee2bb80235a139860ca079b63d6ee3cfac487adbf3
3
+ metadata.gz: 31afe71da2eac370eaa964127e62202abf4917c535e7309d317e8e089476a834
4
+ data.tar.gz: b9bbcb6d954ba8e0653bf277d52df97333b25ac26ea5e5e64608b70067c2b97e
5
5
  SHA512:
6
- metadata.gz: ce0b199ca249d27d1cefc7db7c25f6bb5595165d7076843a190c448e61b596fcd2b0e3c362ddaf155ca6f7fb3002a73511b0ba4a8f111a5ffc1f5b1bc7b8e15c
7
- data.tar.gz: 5c6e1b3cc2890c87f32bda865530accd31ff97df69c5977d1c1de5009337cda8f38447756da9ca202cfae8d34859c8f9d98a6a606efc4d76120ec5587dedceba
6
+ metadata.gz: 30d0daa34b639d24fb2b0cc6dc71bf693bd6a702ddab6d811e8742116edd13e6470f3c2814c84b41dda9515cb0459224a9268b9bc920a84bfee42c1b5d5c0918
7
+ data.tar.gz: a90b89b5e2263fe61507ea7f055962218d5f24821ac7b1af96caa8e2f504cf0fddb19720bc0104584531670362d37ec07ce469e39aad733e988df1d21bf5c8fd
@@ -61,9 +61,14 @@ module Sinatra
61
61
  redirect_url ||= request.url
62
62
  session['redirect_url'] = redirect_url
63
63
 
64
- nonce = session[:nonce]
65
- unless nonce
66
- session[:nonce] = nonce = SecureRandom.base64
64
+ if session[:nonce]
65
+ nonce = session[:nonce]
66
+ # Try to limit how many nonces are stored by keeping the session nonce alive
67
+ Cachy.delete_key(nonce)
68
+ Cachy.cache(nonce, expires_in: 600) { true }
69
+ else
70
+ session[:nonce] = nonce = SecureRandom.base64
71
+ Cachy.cache(nonce, expires_in: 600) { true }
67
72
  end
68
73
 
69
74
  template = ERB.new(Templates::LOGIN_BUTTON)
@@ -10,11 +10,21 @@ require "sinatra/base"
10
10
  require 'sinatra/browserid/helpers'
11
11
  require 'sinatra/browserid/template'
12
12
  require 'addressable/uri'
13
+ require 'cachy'
14
+ require 'moneta'
15
+
13
16
 
14
17
  # This module provides an interface to verify a users email address
15
18
  # with browserid.org.
16
19
  module Sinatra
17
20
  module BrowserID
21
+
22
+ # Init an in-memory cache via the cachy gem. We use this
23
+ # instead of the session because of dropped sessions
24
+ # after redirects, see https://github.com/sinatra/sinatra/issues/1742.
25
+ Cachy.cache_store = Moneta.new(:Memory, expires: 600) # 10 minutes
26
+ # We need to set a global :expires here because of https://github.com/grosser/cachy/issues/7
27
+
18
28
  def self.registered(app)
19
29
  app.helpers BrowserID::Helpers
20
30
 
@@ -25,24 +35,27 @@ module Sinatra
25
35
  app.set :browserid_button_text, "Log in"
26
36
 
27
37
  app.get '/_browserid_login' do
28
- # TODO(petef): render a page that initiates login without
29
- # waiting for a user click.
30
38
  render_login_button
31
39
  end
32
40
 
33
41
  app.post '/_browserid_assert' do
34
42
  begin
35
- # 3. Server checks signature
36
- # for that, fetch the public key from the LA instance (TODO: Do that beforehand for trusted instances, and generally cache the key)
43
+ # Server checks signature
44
+ # For that, fetch the public key from the LA instance (TODO: Do that beforehand for trusted instances, and generally cache the key)
37
45
  public_key_jwks_uri = Addressable::URI.parse(settings.browserid_url + '/keys.json')
38
46
  public_key_jwks = ::JSON.parse(URI.parse(public_key_jwks_uri).read)
39
47
  public_key = OpenSSL::PKey::RSA.new
40
48
  if public_key.respond_to? :set_key
41
- # set n and d via the new set_key function, as direct access to n and e is blocked for some ruby and openssl versions.
42
- # Note that we have no d, as this is a public key, which would be the third param
43
- public_key.set_key( (OpenSSL::BN.new UrlSafeBase64.decode64(public_key_jwks["keys"][0]["n"]), 2),
44
- (OpenSSL::BN.new UrlSafeBase64.decode64(public_key_jwks["keys"][0]["e"]), 2),
45
- nil)
49
+ # We initially set n and d via the then new set_key function, as direct access to n and e is blocked for some ruby and openssl versions.
50
+ # But with OpenSSL 3 this function throws an error, as keys are immutable now. Instead we have to generate the key directly with
51
+ # the right params, as in https://github.com/railslove/epics/issues/138
52
+ sequence = []
53
+ # modulus:
54
+ sequence << OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(UrlSafeBase64.decode64(public_key_jwks["keys"][0]["n"]), 2))
55
+ # exponent:
56
+ sequence << OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(UrlSafeBase64.decode64(public_key_jwks["keys"][0]["e"]), 2))
57
+
58
+ public_key = OpenSSL::PKey::RSA.new(OpenSSL::ASN1::Sequence(sequence).to_der)
46
59
  else
47
60
  public_key.e = OpenSSL::BN.new UrlSafeBase64.decode64(public_key_jwks["keys"][0]["e"]), 2
48
61
  public_key.n = OpenSSL::BN.new UrlSafeBase64.decode64(public_key_jwks["keys"][0]["n"]), 2
@@ -50,19 +63,25 @@ module Sinatra
50
63
 
51
64
  id_token = JWT.decode params[:id_token], public_key, true, { :algorithm => 'RS256' }
52
65
  id_token = id_token[0]
53
- # 4. Needs to make sure token is still valid
66
+ # Needs to make sure token is still valid
54
67
  if (id_token["iss"] == settings.browserid_url &&
55
68
  id_token["aud"] == request.base_url.chomp('/') &&
56
69
  id_token["exp"] > Time.now.to_i &&
57
70
  id_token["email_verified"] &&
58
- id_token["nonce"] == session[:nonce])
71
+ # nonce is really known to us
72
+ Cachy.get(id_token["nonce"]))
59
73
  session[:browserid_email] = id_token['email']
60
- session.delete(:nonce)
74
+ Cachy.delete_key(id_token["nonce"])
75
+ session.delete(:nonce) # it's possible the session persisted
61
76
  if session['redirect_url']
62
77
  redirect session['redirect_url']
63
78
  else
64
79
  redirect "/"
65
80
  end
81
+ else
82
+ # Even when the token check failed the nonce has to be invalidated
83
+ Cachy.delete_key(id_token["nonce"])
84
+ session.delete(:nonce)
66
85
  end
67
86
  rescue OpenURI::HTTPError => e
68
87
  puts "could not validate token: " + e.to_s
@@ -70,8 +89,8 @@ module Sinatra
70
89
  halt 403
71
90
 
72
91
  end
73
- end # def self.registered
74
- end # module BrowserID
92
+ end
93
+ end
75
94
  register BrowserID
76
- end # module Sinatra
95
+ end
77
96
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinatra-portier
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.2
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pete Fritchman
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-09-05 00:00:00.000000000 Z
12
+ date: 2023-11-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: sinatra
@@ -81,6 +81,34 @@ dependencies:
81
81
  - - ">="
82
82
  - !ruby/object:Gem::Version
83
83
  version: '2.8'
84
+ - !ruby/object:Gem::Dependency
85
+ name: cachy
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0.4'
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0.4'
98
+ - !ruby/object:Gem::Dependency
99
+ name: moneta
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '1.4'
105
+ type: :runtime
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '1.4'
84
112
  description:
85
113
  email:
86
114
  - malte@paskuda.biz
@@ -114,7 +142,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
114
142
  - !ruby/object:Gem::Version
115
143
  version: '0'
116
144
  requirements: []
117
- rubygems_version: 3.2.22
145
+ rubygems_version: 3.4.10
118
146
  signing_key:
119
147
  specification_version: 4
120
148
  summary: Sinatra extension for user authentication with portier