Class: SignIn::StatePayloadJwtEncoder

Inherits:
Object
  • Object
show all
Defined in:
app/services/sign_in/state_payload_jwt_encoder.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(code_challenge:, code_challenge_method:, acr:, client_config:, type:, scope: nil, client_state: nil) ⇒ StatePayloadJwtEncoder

rubocop:disable Metrics/ParameterLists



8
9
10
11
12
13
14
15
16
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 8

def initialize(code_challenge:, code_challenge_method:, acr:, client_config:, type:, scope: nil, client_state: nil)
  @acr = acr
  @client_config = client_config
  @type = type
  @code_challenge = code_challenge
  @code_challenge_method = code_challenge_method
  @client_state = client_state
  @scope = scope
end

Instance Attribute Details

#acrObject (readonly)

Returns the value of attribute acr.



5
6
7
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 5

def acr
  @acr
end

#client_configObject (readonly)

Returns the value of attribute client_config.



5
6
7
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 5

def client_config
  @client_config
end

#client_stateObject (readonly)

Returns the value of attribute client_state.



5
6
7
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 5

def client_state
  @client_state
end

#code_challengeObject (readonly)

Returns the value of attribute code_challenge.



5
6
7
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 5

def code_challenge
  @code_challenge
end

#code_challenge_methodObject (readonly)

Returns the value of attribute code_challenge_method.



5
6
7
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 5

def code_challenge_method
  @code_challenge_method
end

#scopeObject (readonly)

Returns the value of attribute scope.



5
6
7
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 5

def scope
  @scope
end

#typeObject (readonly)

Returns the value of attribute type.



5
6
7
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 5

def type
  @type
end

Instance Method Details

#jwt_encode_state_payloadObject (private)



54
55
56
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 54

def jwt_encode_state_payload
  JWT.encode(jwt_payload, private_key, Constants::Auth::JWT_ENCODE_ALGORITHM)
end

#jwt_payloadObject (private)



62
63
64
65
66
67
68
69
70
71
72
73
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 62

def jwt_payload
  {
    acr: state_payload.acr,
    type: state_payload.type,
    client_id: state_payload.client_id,
    code_challenge: state_payload.code_challenge,
    client_state: state_payload.client_state,
    code: state_payload.code,
    created_at: state_payload.created_at,
    scope: state_payload.scope
  }
end

#performObject

rubocop:enable Metrics/ParameterLists



19
20
21
22
23
24
25
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 19

def perform
  validate_pkce_params! if client_config.pkce?
  validate_scope!
  validate_state_payload!
  save_state_code
  jwt_encode_state_payload
end

#private_keyObject (private)



101
102
103
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 101

def private_key
  OpenSSL::PKey::RSA.new(File.read(Settings..jwt_encode_key))
end

#remove_base64_padding(data) ⇒ Object (private)



93
94
95
96
97
98
99
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 93

def remove_base64_padding(data)
  return unless client_config.pkce? && data

  Base64.urlsafe_encode64(Base64.urlsafe_decode64(data.to_s), padding: false)
rescue ArgumentError
  raise Errors::CodeChallengeMalformedError.new message: 'Code Challenge is not valid'
end

#save_state_codeObject (private)



58
59
60
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 58

def save_state_code
  StateCode.new(code: state_code).save!
end

#sso_not_enabled_for_device_sso_scope?Boolean (private)

Returns:

  • (Boolean)


89
90
91
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 89

def sso_not_enabled_for_device_sso_scope?
  scope == Constants::Auth::DEVICE_SSO && !client_config.device_sso_enabled?
end

#state_codeObject (private)



85
86
87
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 85

def state_code
  @state_code ||= SecureRandom.hex
end

#state_payloadObject (private)



75
76
77
78
79
80
81
82
83
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 75

def state_payload
  @state_payload ||= StatePayload.new(acr:,
                                      type:,
                                      client_id: client_config.client_id,
                                      code_challenge: remove_base64_padding(code_challenge),
                                      code: state_code,
                                      client_state:,
                                      scope:)
end

#validate_code_challenge!Object (private)



44
45
46
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 44

def validate_code_challenge!
  raise Errors::CodeChallengeMalformedError.new message: 'Code Challenge is not valid' if code_challenge.blank?
end

#validate_code_challenge_method!Object (private)



38
39
40
41
42
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 38

def validate_code_challenge_method!
  if code_challenge_method != Constants::Auth::CODE_CHALLENGE_METHOD
    raise Errors::CodeChallengeMethodMismatchError.new message: 'Code Challenge Method is not valid'
  end
end

#validate_pkce_params!Object (private)



29
30
31
32
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 29

def validate_pkce_params!
  validate_code_challenge_method!
  validate_code_challenge!
end

#validate_scope!Object (private)



34
35
36
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 34

def validate_scope!
  raise Errors::InvalidScope.new message: 'Scope is not valid for Client' if sso_not_enabled_for_device_sso_scope?
end

#validate_state_payload!Object (private)



48
49
50
51
52
# File 'app/services/sign_in/state_payload_jwt_encoder.rb', line 48

def validate_state_payload!
  state_payload
rescue ActiveModel::ValidationError
  raise Errors::StatePayloadError.new message: 'Attributes are not valid'
end