Class: KeycloakApiRails::Helper

Inherits:
Object
  • Object
show all
Defined in:
lib/keycloak-api-rails/helper.rb

Constant Summary collapse

CURRENT_USER_ID_KEY =
"keycloak:keycloak_id"
CURRENT_AUTHORIZED_PARTY_KEY =
"keycloak:authorized_party"
CURRENT_USER_EMAIL_KEY =
"keycloak:email"
CURRENT_USER_LOCALE_KEY =
"keycloak:locale"
CURRENT_USER_ATTRIBUTES =
"keycloak:attributes"
ROLES_KEY =
"keycloak:roles"
RESOURCE_ROLES_KEY =
"keycloak:resource_roles"
TOKEN_KEY =
"keycloak:token"
QUERY_STRING_TOKEN_KEY =
"authorizationToken"
BEARER_PREFIX =

RFC 7235 makes the authentication scheme case-insensitive.

/\ABearer[[:space:]]+/i.freeze

Class Method Summary collapse

Class Method Details

.assign_current_authorized_party(env, token) ⇒ Object



48
49
50
# File 'lib/keycloak-api-rails/helper.rb', line 48

def self.assign_current_authorized_party(env, token)
  env[CURRENT_AUTHORIZED_PARTY_KEY] = token["azp"]
end

.assign_current_user_custom_attributes(env, token, attribute_names) ⇒ Object



86
87
88
89
90
91
92
93
# File 'lib/keycloak-api-rails/helper.rb', line 86

def self.assign_current_user_custom_attributes(env, token, attribute_names)
  attributes = {}
  Array(attribute_names).each do |name|
    name_str = name.to_s
    attributes[name_str] = token[name_str] if token.key?(name_str)
  end
  env[CURRENT_USER_ATTRIBUTES] = attributes
end

.assign_current_user_email(env, token) ⇒ Object



56
57
58
# File 'lib/keycloak-api-rails/helper.rb', line 56

def self.assign_current_user_email(env, token)
  env[CURRENT_USER_EMAIL_KEY] = token["email"]
end

.assign_current_user_id(env, token) ⇒ Object



32
33
34
# File 'lib/keycloak-api-rails/helper.rb', line 32

def self.assign_current_user_id(env, token)
  env[CURRENT_USER_ID_KEY] = token["sub"]
end

.assign_current_user_locale(env, token) ⇒ Object



64
65
66
# File 'lib/keycloak-api-rails/helper.rb', line 64

def self.assign_current_user_locale(env, token)
  env[CURRENT_USER_LOCALE_KEY] = token["locale"]
end

.assign_keycloak_token(env, token) ⇒ Object



40
41
42
# File 'lib/keycloak-api-rails/helper.rb', line 40

def self.assign_keycloak_token(env, token)
  env[TOKEN_KEY] = token
end

.assign_realm_roles(env, token) ⇒ Object



72
73
74
# File 'lib/keycloak-api-rails/helper.rb', line 72

def self.assign_realm_roles(env, token)
  env[ROLES_KEY] = token.dig("realm_access", "roles")
end

.assign_resource_roles(env, token) ⇒ Object



80
81
82
83
84
# File 'lib/keycloak-api-rails/helper.rb', line 80

def self.assign_resource_roles(env, token)
  env[RESOURCE_ROLES_KEY] = token.fetch("resource_access", {}).each_with_object({}) do |(name, resource_attributes), resource_roles|
    resource_roles[name] = resource_attributes.fetch("roles", [])
  end
end

.assign_token(env, token, custom_attribute_names) ⇒ Object



17
18
19
20
21
22
23
24
25
26
# File 'lib/keycloak-api-rails/helper.rb', line 17

def self.assign_token(env, token, custom_attribute_names)
  assign_current_user_id(env, token)
  assign_current_authorized_party(env, token)
  assign_current_user_email(env, token)
  assign_current_user_locale(env, token)
  assign_current_user_custom_attributes(env, token, custom_attribute_names)
  assign_realm_roles(env, token)
  assign_resource_roles(env, token)
  assign_keycloak_token(env, token)
end

.create_url_with_token(uri, token) ⇒ Object



123
124
125
126
127
128
129
# File 'lib/keycloak-api-rails/helper.rb', line 123

def self.create_url_with_token(uri, token)
  uri       = URI(uri)
  params    = URI.decode_www_form(uri.query || "").reject { |query_string| query_string.first == QUERY_STRING_TOKEN_KEY }
  params    << [QUERY_STRING_TOKEN_KEY, token]
  uri.query = URI.encode_www_form(params)
  uri.to_s
end

.current_authorized_party(env) ⇒ Object



44
45
46
# File 'lib/keycloak-api-rails/helper.rb', line 44

def self.current_authorized_party(env)
  env[CURRENT_AUTHORIZED_PARTY_KEY]
end

.current_resource_roles(env) ⇒ Object



76
77
78
# File 'lib/keycloak-api-rails/helper.rb', line 76

def self.current_resource_roles(env)
  env[RESOURCE_ROLES_KEY]
end

.current_user_custom_attributes(env) ⇒ Object



95
96
97
# File 'lib/keycloak-api-rails/helper.rb', line 95

def self.current_user_custom_attributes(env)
  env[CURRENT_USER_ATTRIBUTES]
end

.current_user_email(env) ⇒ Object



52
53
54
# File 'lib/keycloak-api-rails/helper.rb', line 52

def self.current_user_email(env)
  env[CURRENT_USER_EMAIL_KEY]
end

.current_user_id(env) ⇒ Object



28
29
30
# File 'lib/keycloak-api-rails/helper.rb', line 28

def self.current_user_id(env)
  env[CURRENT_USER_ID_KEY]
end

.current_user_locale(env) ⇒ Object



60
61
62
# File 'lib/keycloak-api-rails/helper.rb', line 60

def self.current_user_locale(env)
  env[CURRENT_USER_LOCALE_KEY]
end

.current_user_roles(env) ⇒ Object



68
69
70
# File 'lib/keycloak-api-rails/helper.rb', line 68

def self.current_user_roles(env)
  env[ROLES_KEY]
end

.keycloak_token(env) ⇒ Object



36
37
38
# File 'lib/keycloak-api-rails/helper.rb', line 36

def self.keycloak_token(env)
  env[TOKEN_KEY]
end

.read_token_from_headers(headers) ⇒ Object



131
132
133
134
135
136
137
138
# File 'lib/keycloak-api-rails/helper.rb', line 131

def self.read_token_from_headers(headers)
  authorization = headers["HTTP_AUTHORIZATION"]
  if authorization.nil?
    ""
  else
    authorization.sub(BEARER_PREFIX, "")
  end
end

.read_token_from_query_string(uri) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/keycloak-api-rails/helper.rb', line 110

def self.read_token_from_query_string(uri)
  if uri && !uri.strip.empty?
    parsed_uri         = URI.parse(uri)
    query              = URI.decode_www_form(parsed_uri.query || "")
    query_string_token = query.detect { |param| param.first == QUERY_STRING_TOKEN_KEY }
    query_string_token&.at(1)
  else
    ""
  end
rescue URI::InvalidURIError, ArgumentError
  nil
end

.request_uri(env) ⇒ Object



99
100
101
102
103
104
105
106
107
108
# File 'lib/keycloak-api-rails/helper.rb', line 99

def self.request_uri(env)
  # 'REQUEST_URI' is not part of the Rack spec: Puma and Unicorn do set it
  if env["REQUEST_URI"].nil?
    query_string = env["QUERY_STRING"]
    path         = env["PATH_INFO"].to_s
    query_string.nil? || query_string.empty? ? path : "#{path}?#{query_string}"
  else
    env["REQUEST_URI"]
  end
end