Add PKCE support to remoteStorage OAuth
Implements the optional OAuth 2.0 Authorization Code grant with PKCE (RFC 7636) for remoteStorage, as described in the remoteStorage spec (section 10.1). - Advertise the authorization and token endpoints plus the supported code_challenge method (S256) in WebFinger, and bump the advertised spec version to draft-dejong-remotestorage-27 - Add RsAuthorizationCode: a short-lived (5 min), single-use authorization code stored only as a SHA256 digest - Add RsOauthManager services for issuing and exchanging codes, including S256 verification - Add a cross-origin POST /rs/oauth/token endpoint that exchanges a code (and code_verifier) for an access token, with CORS and no CSRF token - Consent dialog now carries response_type / code_challenge through the form and redirects with the code in the query string for the code flow - Remove the existing-token reuse shortcut so every authorization results in a distinct authorization (and token) Part of #254
This commit is contained in:
19 files changed
+827
-73
No files matched your search
@@ -0,0 +1,37 @@
|
||||
class RsAuthorizationCode < ApplicationRecord
|
||||
belongs_to :user
|
||||
|
||||
CODE_TTL = 5.minutes
|
||||
|
||||
serialize :permissions, coder: YAML
|
||||
|
||||
attr_accessor :code
|
||||
|
||||
before_validation :generate_code
|
||||
|
||||
scope :active, -> { where(expires_at: Time.current..) }
|
||||
|
||||
def self.find_by_code(raw_code)
|
||||
return nil if raw_code.blank?
|
||||
|
||||
find_by(code_digest: Digest::SHA256.hexdigest(raw_code))
|
||||
end
|
||||
|
||||
def expired?
|
||||
expires_at <= Time.current
|
||||
end
|
||||
|
||||
def consume!
|
||||
destroy!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def generate_code
|
||||
return if code_digest.present?
|
||||
|
||||
self.code = SecureRandom.urlsafe_base64(32)
|
||||
self.code_digest = Digest::SHA256.hexdigest(code)
|
||||
self.expires_at ||= CODE_TTL.from_now
|
||||
end
|
||||
end
|
||||
Reference in new issue
Block a user