Class: SignIn::AssertionValidator
- Inherits:
-
Object
- Object
- SignIn::AssertionValidator
- Defined in:
- app/services/sign_in/assertion_validator.rb
Instance Attribute Summary collapse
-
#assertion ⇒ Object
readonly
Returns the value of attribute assertion.
Instance Method Summary collapse
- #assertion_audience ⇒ Object private
- #audience ⇒ Object private
- #create_new_access_token ⇒ Object private
- #decoded_assertion ⇒ Object private
- #decoded_assertion_scopes_are_defined_in_config? ⇒ Boolean private
- #decoded_assertion_without_validation ⇒ Object private
- #expiration ⇒ Object private
- #hostname ⇒ Object private
-
#initialize(assertion:) ⇒ AssertionValidator
constructor
A new instance of AssertionValidator.
- #issued_at_time ⇒ Object private
- #issuer ⇒ Object private
- #jwt_decode(with_validation: true) ⇒ Object private
- #localhost_hostname ⇒ Object private
- #perform ⇒ Object
- #scopes ⇒ Object private
- #service_account_config ⇒ Object private
- #service_account_id ⇒ Object private
- #token_route ⇒ Object private
- #user_attributes ⇒ Object private
- #user_identifier ⇒ Object private
- #validate_audience ⇒ Object private
- #validate_expiration ⇒ Object private
- #validate_issued_at_time ⇒ Object private
- #validate_issuer ⇒ Object private
- #validate_scopes ⇒ Object private
- #validate_service_account_config ⇒ Object private
- #validate_subject ⇒ Object private
- #validate_user_attributes ⇒ Object private
Constructor Details
#initialize(assertion:) ⇒ AssertionValidator
Returns a new instance of AssertionValidator.
7 8 9 |
# File 'app/services/sign_in/assertion_validator.rb', line 7 def initialize(assertion:) @assertion = assertion end |
Instance Attribute Details
#assertion ⇒ Object (readonly)
Returns the value of attribute assertion.
5 6 7 |
# File 'app/services/sign_in/assertion_validator.rb', line 5 def assertion @assertion end |
Instance Method Details
#assertion_audience ⇒ Object (private)
125 126 127 |
# File 'app/services/sign_in/assertion_validator.rb', line 125 def assertion_audience @assertion_audience ||= Array(decoded_assertion.aud) end |
#audience ⇒ Object (private)
129 130 131 |
# File 'app/services/sign_in/assertion_validator.rb', line 129 def audience @audience ||= service_account_config.access_token_audience end |
#create_new_access_token ⇒ Object (private)
73 74 75 76 77 78 79 |
# File 'app/services/sign_in/assertion_validator.rb', line 73 def create_new_access_token ServiceAccountAccessToken.new(service_account_id:, audience:, scopes:, user_attributes:, user_identifier:) end |
#decoded_assertion ⇒ Object (private)
97 98 99 |
# File 'app/services/sign_in/assertion_validator.rb', line 97 def decoded_assertion @decoded_assertion ||= jwt_decode end |
#decoded_assertion_scopes_are_defined_in_config? ⇒ Boolean (private)
81 82 83 84 85 |
# File 'app/services/sign_in/assertion_validator.rb', line 81 def decoded_assertion_scopes_are_defined_in_config? return service_account_config.scopes.blank? if scopes.blank? (scopes - service_account_config.scopes).empty? end |
#decoded_assertion_without_validation ⇒ Object (private)
101 102 103 |
# File 'app/services/sign_in/assertion_validator.rb', line 101 def decoded_assertion_without_validation @decoded_assertion_without_validation ||= jwt_decode(with_validation: false) end |
#expiration ⇒ Object (private)
137 138 139 |
# File 'app/services/sign_in/assertion_validator.rb', line 137 def expiration @expiration ||= decoded_assertion.exp end |
#hostname ⇒ Object (private)
91 92 93 94 95 |
# File 'app/services/sign_in/assertion_validator.rb', line 91 def hostname return localhost_hostname if Settings.vsp_environment == 'localhost' "https://#{Settings.hostname}" end |
#issued_at_time ⇒ Object (private)
133 134 135 |
# File 'app/services/sign_in/assertion_validator.rb', line 133 def issued_at_time @issued_at_time ||= decoded_assertion.iat end |
#issuer ⇒ Object (private)
121 122 123 |
# File 'app/services/sign_in/assertion_validator.rb', line 121 def issuer @issuer ||= decoded_assertion.iss end |
#jwt_decode(with_validation: true) ⇒ Object (private)
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'app/services/sign_in/assertion_validator.rb', line 145 def jwt_decode(with_validation: true) assertion_public_keys = with_validation ? service_account_config.assertion_public_keys : nil decoded_jwt = JWT.decode( assertion, assertion_public_keys, with_validation, { verify_expiration: with_validation, algorithm: Constants::Auth::ASSERTION_ENCODE_ALGORITHM } )&.first OpenStruct.new(decoded_jwt) rescue JWT::VerificationError raise Errors::AssertionSignatureMismatchError.new message: 'Assertion body does not match signature' rescue JWT::ExpiredSignature raise Errors::AssertionExpiredError.new message: 'Assertion has expired' rescue JWT::DecodeError raise Errors::AssertionMalformedJWTError.new message: 'Assertion is malformed' end |
#localhost_hostname ⇒ Object (private)
162 163 164 165 166 |
# File 'app/services/sign_in/assertion_validator.rb', line 162 def localhost_hostname port = URI.parse("http://#{Settings.hostname}").port "http://localhost:#{port}" end |
#perform ⇒ Object
11 12 13 14 15 16 17 18 19 20 21 |
# File 'app/services/sign_in/assertion_validator.rb', line 11 def perform validate_service_account_config validate_issuer validate_audience validate_scopes validate_user_attributes validate_subject validate_issued_at_time validate_expiration create_new_access_token end |
#scopes ⇒ Object (private)
109 110 111 |
# File 'app/services/sign_in/assertion_validator.rb', line 109 def scopes @scopes ||= Array(decoded_assertion.scopes) end |
#service_account_config ⇒ Object (private)
141 142 143 |
# File 'app/services/sign_in/assertion_validator.rb', line 141 def service_account_config @service_account_config ||= ServiceAccountConfig.find_by(service_account_id:) end |
#service_account_id ⇒ Object (private)
105 106 107 |
# File 'app/services/sign_in/assertion_validator.rb', line 105 def service_account_id @service_account_id ||= decoded_assertion_without_validation.service_account_id end |
#token_route ⇒ Object (private)
87 88 89 |
# File 'app/services/sign_in/assertion_validator.rb', line 87 def token_route "#{hostname}#{Constants::Auth::TOKEN_ROUTE_PATH}" end |
#user_attributes ⇒ Object (private)
113 114 115 |
# File 'app/services/sign_in/assertion_validator.rb', line 113 def user_attributes @user_attributes = decoded_assertion.user_attributes || {} end |
#user_identifier ⇒ Object (private)
117 118 119 |
# File 'app/services/sign_in/assertion_validator.rb', line 117 def user_identifier @user_identifier ||= decoded_assertion.sub end |
#validate_audience ⇒ Object (private)
37 38 39 40 41 |
# File 'app/services/sign_in/assertion_validator.rb', line 37 def validate_audience unless assertion_audience.include?(token_route) raise Errors::ServiceAccountAssertionAttributesError.new message: 'Assertion audience is not valid' end end |
#validate_expiration ⇒ Object (private)
67 68 69 70 71 |
# File 'app/services/sign_in/assertion_validator.rb', line 67 def validate_expiration if expiration.blank? raise Errors::ServiceAccountAssertionAttributesError.new message: 'Assertion expiration timestamp is not valid' end end |
#validate_issued_at_time ⇒ Object (private)
61 62 63 64 65 |
# File 'app/services/sign_in/assertion_validator.rb', line 61 def validate_issued_at_time if issued_at_time.blank? || issued_at_time > Time.now.to_i raise Errors::ServiceAccountAssertionAttributesError.new message: 'Assertion issuance timestamp is not valid' end end |
#validate_issuer ⇒ Object (private)
31 32 33 34 35 |
# File 'app/services/sign_in/assertion_validator.rb', line 31 def validate_issuer if issuer != audience raise Errors::ServiceAccountAssertionAttributesError.new message: 'Assertion issuer is not valid' end end |
#validate_scopes ⇒ Object (private)
43 44 45 46 47 |
# File 'app/services/sign_in/assertion_validator.rb', line 43 def validate_scopes unless decoded_assertion_scopes_are_defined_in_config? raise Errors::ServiceAccountAssertionAttributesError.new message: 'Assertion scopes are not valid' end end |
#validate_service_account_config ⇒ Object (private)
25 26 27 28 29 |
# File 'app/services/sign_in/assertion_validator.rb', line 25 def validate_service_account_config if service_account_config.blank? raise Errors::ServiceAccountConfigNotFound.new message: 'Service account config not found' end end |
#validate_subject ⇒ Object (private)
55 56 57 58 59 |
# File 'app/services/sign_in/assertion_validator.rb', line 55 def validate_subject if user_identifier.blank? raise Errors::ServiceAccountAssertionAttributesError.new message: 'Assertion subject is not valid' end end |
#validate_user_attributes ⇒ Object (private)
49 50 51 52 53 |
# File 'app/services/sign_in/assertion_validator.rb', line 49 def validate_user_attributes if (user_attributes.keys.map(&:to_s) - service_account_config.access_token_user_attributes).any? raise Errors::ServiceAccountAssertionAttributesError.new message: 'Assertion user attributes are not valid' end end |