lib/keycloak.rb in keycloak-2.5.1 vs lib/keycloak.rb in keycloak-3.0.0

- old
+ new

@@ -3,13 +3,17 @@ require 'json' require 'jwt' require 'base64' require 'uri' +def isempty?(value) + value.respond_to?(:empty?) ? !!value.empty? : !value +end + module Keycloak - OLD_KEYCLOAK_JSON_FILE = 'keycloak.json' - KEYCLOAK_JSON_FILE = 'config/keycloak.json' + OLD_KEYCLOAK_JSON_FILE = 'keycloak.json'.freeze + KEYCLOAK_JSON_FILE = 'config/keycloak.json'.freeze class << self attr_accessor :proxy, :generate_request_exception, :keycloak_controller, :proc_cookie_token, :proc_external_attributes, :realm, :auth_server_url, :validate_token_when_call_has_role @@ -19,19 +23,19 @@ Keycloak.generate_request_exception = true if Keycloak.generate_request_exception.nil? Keycloak.generate_request_exception end def self.installation_file - if File.exists?(KEYCLOAK_JSON_FILE) - @installation_file ||= KEYCLOAK_JSON_FILE - else - @installation_file ||= OLD_KEYCLOAK_JSON_FILE - end + @installation_file ||= if File.exist?(KEYCLOAK_JSON_FILE) + KEYCLOAK_JSON_FILE + else + OLD_KEYCLOAK_JSON_FILE + end end def self.installation_file=(file = nil) - raise InstallationFileNotFound unless file.instance_of?(String) && File.exists?(file) + raise InstallationFileNotFound unless file.instance_of?(String) && File.exist?(file) @installation_file = file || KEYCLOAK_JSON_FILE end module Client class << self @@ -40,12 +44,12 @@ end def self.get_token(user, password, client_id = '', secret = '') setup_module - client_id = @client_id if client_id.blank? - secret = @secret if secret.blank? + client_id = @client_id if isempty?(client_id) + secret = @secret if isempty?(secret) payload = { 'client_id' => client_id, 'client_secret' => secret, 'username' => user, 'password' => password, @@ -55,12 +59,12 @@ end def self.get_token_by_code(code, redirect_uri, client_id = '', secret = '') verify_setup - client_id = @client_id if client_id.blank? - secret = @secret if secret.blank? + client_id = @client_id if isempty?(client_id) + secret = @secret if isempty?(secret) payload = { 'client_id' => client_id, 'client_secret' => secret, 'code' => code, 'grant_type' => 'authorization_code', @@ -70,13 +74,13 @@ end def self.get_token_by_exchange(issuer, issuer_token, client_id = '', secret = '', token_endpoint = '') setup_module - client_id = @client_id if client_id.blank? - secret = @secret if secret.blank? - token_endpoint = @configuration['token_endpoint'] if token_endpoint.blank? + client_id = @client_id if isempty?(client_id) + secret = @secret if isempty?(secret) + token_endpoint = @configuration['token_endpoint'] if isempty?(token_endpoint) payload = { 'client_id' => client_id, 'client_secret' => secret, 'audience' => client_id, 'grant_type' => 'urn:ietf:params:oauth:grant-type:token-exchange', 'subject_token_type' => 'urn:ietf:params:oauth:token-type:access_token', 'subject_issuer' => issuer, 'subject_token' => issuer_token } header = { 'Content-Type' => 'application/x-www-form-urlencoded' } _request = -> do RestClient.post(token_endpoint, payload, header){|response, request, result| @@ -93,11 +97,11 @@ end def self.get_userinfo_issuer(access_token = '', userinfo_endpoint = '') verify_setup - userinfo_endpoint = @configuration['userinfo_endpoint'] if userinfo_endpoint.blank? + userinfo_endpoint = @configuration['userinfo_endpoint'] if isempty?(userinfo_endpoint) access_token = self.token["access_token"] if access_token.empty? payload = { 'access_token' => access_token } header = { 'Content-Type' => 'application/x-www-form-urlencoded' } _request = -> do @@ -110,13 +114,13 @@ end def self.get_token_by_refresh_token(refresh_token = '', client_id = '', secret = '') verify_setup - client_id = @client_id if client_id.blank? - secret = @secret if secret.blank? - refresh_token = self.token['refresh_token'] if refresh_token.empty? + client_id = @client_id if isempty?(client_id) + secret = @secret if isempty?(secret) + refresh_token = token['refresh_token'] if refresh_token.empty? payload = { 'client_id' => client_id, 'client_secret' => secret, 'refresh_token' => refresh_token, 'grant_type' => 'refresh_token' } @@ -125,12 +129,12 @@ end def self.get_token_by_client_credentials(client_id = '', secret = '') setup_module - client_id = @client_id if client_id.blank? - secret = @secret if secret.blank? + client_id = @client_id if isempty?(client_id) + secret = @secret if isempty?(secret) payload = { 'client_id' => client_id, 'client_secret' => secret, 'grant_type' => 'client_credentials' } @@ -138,14 +142,14 @@ end def self.get_token_introspection(token = '', client_id = '', secret = '', token_introspection_endpoint = '') verify_setup - client_id = @client_id if client_id.blank? - secret = @secret if secret.blank? - token = self.token["access_token"] if token.blank? - token_introspection_endpoint = @configuration['token_introspection_endpoint'] if token_introspection_endpoint.blank? + client_id = @client_id if isempty?(client_id) + secret = @secret if isempty?(secret) + token = self.token['access_token'] if isempty?(token) + token_introspection_endpoint = @configuration['token_introspection_endpoint'] if isempty?(token_introspection_endpoint) payload = { 'token' => token } authorization = Base64.strict_encode64("#{client_id}:#{secret}") authorization = "Basic #{authorization}" @@ -168,38 +172,38 @@ end def self.url_login_redirect(redirect_uri, response_type = 'code', client_id = '', authorization_endpoint = '') verify_setup - client_id = @client_id if client_id.blank? - authorization_endpoint = @configuration['authorization_endpoint'] if authorization_endpoint.blank? + client_id = @client_id if isempty?(client_id) + authorization_endpoint = @configuration['authorization_endpoint'] if isempty?(authorization_endpoint) - p = URI.encode_www_form({ response_type: response_type, client_id: client_id, redirect_uri: redirect_uri }) + p = URI.encode_www_form(response_type: response_type, client_id: client_id, redirect_uri: redirect_uri) "#{authorization_endpoint}?#{p}" end def self.logout(redirect_uri = '', refresh_token = '', client_id = '', secret = '', end_session_endpoint = '') verify_setup if self.token || !refresh_token.empty? refresh_token = self.token['refresh_token'] if refresh_token.empty? - client_id = @client_id if client_id.blank? - secret = @secret if secret.blank? - end_session_endpoint = @configuration['end_session_endpoint'] if end_session_endpoint.blank? + client_id = @client_id if isempty?(client_id) + secret = @secret if isempty?(secret) + end_session_endpoint = @configuration['end_session_endpoint'] if isempty?(end_session_endpoint) payload = { 'client_id' => client_id, 'client_secret' => secret, 'refresh_token' => refresh_token } header = { 'Content-Type' => 'application/x-www-form-urlencoded' } - if redirect_uri.empty? - final_url = end_session_endpoint - else - final_url = "#{end_session_endpoint}?#{URI.encode_www_form({ redirect_uri: redirect_uri })}" - end + final_url = if redirect_uri.empty? + end_session_endpoint + else + "#{end_session_endpoint}?#{URI.encode_www_form(redirect_uri: redirect_uri)}" + end _request = -> do RestClient.post(final_url, payload, header){ |response, request, result| case response.code when 200..399 @@ -217,12 +221,12 @@ end def self.get_userinfo(access_token = '', userinfo_endpoint = '') verify_setup - access_token = self.token["access_token"] if access_token.empty? - userinfo_endpoint = @configuration['userinfo_endpoint'] if userinfo_endpoint.blank? + access_token = self.token['access_token'] if access_token.empty? + userinfo_endpoint = @configuration['userinfo_endpoint'] if isempty?(userinfo_endpoint) payload = { 'access_token' => access_token } header = { 'Content-Type' => 'application/x-www-form-urlencoded' } @@ -247,36 +251,32 @@ end def self.has_role?(user_role, access_token = '', client_id = '', secret = '', token_introspection_endpoint = '') verify_setup - client_id = @client_id if client_id.blank? - secret = @secret if secret.blank? - token_introspection_endpoint = @configuration['token_introspection_endpoint'] if token_introspection_endpoint.blank? + client_id = @client_id if isempty?(client_id) + secret = @secret if isempty?(secret) + token_introspection_endpoint = @configuration['token_introspection_endpoint'] if isempty?(token_introspection_endpoint) if !Keycloak.validate_token_when_call_has_role || user_signed_in?(access_token, client_id, secret, token_introspection_endpoint) dt = decoded_access_token(access_token)[0] - dt = dt["resource_access"][client_id] - if dt != nil - dt["roles"].each do |role| + dt = dt['resource_access'][client_id] + unless dt.nil? + dt['roles'].each do |role| return true if role.to_s == user_role.to_s end - false - else - false end - else - false end + false end def self.user_signed_in?(access_token = '', client_id = '', secret = '', token_introspection_endpoint = '') verify_setup - client_id = @client_id if client_id.blank? - secret = @secret if secret.blank? - token_introspection_endpoint = @configuration['token_introspection_endpoint'] if token_introspection_endpoint.blank? + client_id = @client_id if isempty?(client_id) + secret = @secret if isempty?(secret) + token_introspection_endpoint = @configuration['token_introspection_endpoint'] if isempty?(token_introspection_endpoint) begin JSON(get_token_introspection(access_token, client_id, secret, token_introspection_endpoint))['active'] === true rescue => e if e.class < Keycloak::KeycloakException @@ -320,30 +320,27 @@ JWT.decode refresh_token, @public_key, false, { :algorithm => 'RS256' } end private - KEYCLOACK_CONTROLLER_DEFAULT = 'session' + KEYCLOACK_CONTROLLER_DEFAULT = 'session'.freeze def self.get_installation if File.exists?(Keycloak.installation_file) installation = JSON File.read(Keycloak.installation_file) @realm = installation["realm"] @client_id = installation["resource"] @secret = installation["credentials"]["secret"] @public_key = installation["realm-public-key"] @auth_server_url = installation["auth-server-url"] - openid_configuration else - if Keycloak.realm.blank? || Keycloak.auth_server_url.blank? - raise "#{Keycloak.installation_file} and relm settings not found." - else - @realm = Keycloak.realm - @auth_server_url = Keycloak.auth_server_url - openid_configuration - end + raise "#{Keycloak.installation_file} and relm settings not found." if isempty?(Keycloak.realm) || isempty?(Keycloak.auth_server_url) + + @realm = Keycloak.realm + @auth_server_url = Keycloak.auth_server_url end + openid_configuration end def self.verify_setup get_installation if @configuration.nil? end @@ -366,11 +363,11 @@ end end end def self.openid_configuration - RestClient.proxy = Keycloak.proxy if Keycloak.proxy.present? + RestClient.proxy = Keycloak.proxy unless isempty?(Keycloak.proxy) config_url = "#{@auth_server_url}/realms/#{@realm}/.well-known/openid-configuration" _request = -> do RestClient.get config_url end response = exec_request _request @@ -436,17 +433,17 @@ def self.delete_user(id, access_token = nil) generic_delete("users/#{id}", nil, nil, access_token) end def self.revoke_consent_user(id, client_id = nil, access_token = nil) - client_id = Keycloak::Client.client_id if client_id.blank? + client_id = Keycloak::Client.client_id if isempty?(client_id) generic_delete("users/#{id}/consents/#{client_id}", nil, nil, access_token) end def self.update_account_email(id, actions, redirect_uri = '', client_id = nil, access_token = nil) - client_id = Keycloak::Client.client_id if client_id.blank? - generic_put("users/#{id}/execute-actions-email", {:redirect_uri => redirect_uri, :client_id => client_id}, actions, access_token) + client_id = Keycloak::Client.client_id if isempty?(client_id) + generic_put("users/#{id}/execute-actions-email", { redirect_uri: redirect_uri, client_id: client_id }, actions, access_token) end def self.get_role_mappings(id, access_token = nil) generic_get("users/#{id}/role-mappings", nil, access_token) end @@ -553,11 +550,11 @@ end private def self.effective_access_token(access_token) - if access_token.blank? + if isempty?(access_token) Keycloak::Client.token['access_token'] else access_token end end @@ -576,71 +573,71 @@ class << self end def self.get_users(query_parameters = nil, client_id = '', secret = '') - client_id = Keycloak::Client.client_id if client_id.blank? - secret = Keycloak::Client.secret if secret.blank? + client_id = Keycloak::Client.client_id if isempty?(client_id) + secret = Keycloak::Client.secret if isempty?(secret) proc = lambda {|token| - Keycloak::Admin.get_users(query_parameters, token["access_token"]) + Keycloak::Admin.get_users(query_parameters, token['access_token']) } default_call(proc, client_id, secret) end def self.get_groups(query_parameters = nil, client_id = '', secret = '') - client_id = Keycloak::Client.client_id if client_id.blank? - secret = Keycloak::Client.secret if secret.blank? + client_id = Keycloak::Client.client_id if isempty?(client_id) + secret = Keycloak::Client.secret if isempty?(secret) - proc = lambda {|token| - Keycloak::Admin.get_groups(query_parameters, token["access_token"]) + proc = lambda { |token| + Keycloak::Admin.get_groups(query_parameters, token['access_token']) } default_call(proc, client_id, secret) end def self.change_password(user_id, redirect_uri = '', client_id = '', secret = '') - client_id = Keycloak::Client.client_id if client_id.blank? - secret = Keycloak::Client.secret if secret.blank? + client_id = Keycloak::Client.client_id if isempty?(client_id) + secret = Keycloak::Client.secret if isempty?(secret) proc = lambda {|token| - Keycloak.generic_request(token["access_token"], + Keycloak.generic_request(token['access_token'], Keycloak::Admin.full_url("users/#{user_id}/execute-actions-email"), - {:redirect_uri => redirect_uri, :client_id => client_id}, + { redirect_uri: redirect_uri, client_id: client_id }, ['UPDATE_PASSWORD'], 'PUT') } default_call(proc, client_id, secret) end def self.forgot_password(user_login, redirect_uri = '', client_id = '', secret = '') - client_id = Keycloak::Client.client_id if client_id.blank? - secret = Keycloak::Client.secret if secret.blank? + client_id = Keycloak::Client.client_id if isempty?(client_id) + secret = Keycloak::Client.secret if isempty?(secret) user = get_user_info(user_login, true, client_id, secret) change_password(user['id'], redirect_uri, client_id, secret) end def self.get_logged_user_info(client_id = '', secret = '') - client_id = Keycloak::Client.client_id if client_id.blank? - secret = Keycloak::Client.secret if secret.blank? + client_id = Keycloak::Client.client_id if isempty?(client_id) + secret = Keycloak::Client.secret if isempty?(secret) proc = lambda {|token| userinfo = JSON Keycloak::Client.get_userinfo - Keycloak.generic_request(token["access_token"], + Keycloak.generic_request(token['access_token'], Keycloak::Admin.full_url("users/#{userinfo['sub']}"), nil, nil, 'GET') } default_call(proc, client_id, secret) end def self.get_user_info(user_login, whole_word = false, client_id = '', secret = '') - client_id = Keycloak::Client.client_id if client_id.blank? - secret = Keycloak::Client.secret if secret.blank? + client_id = Keycloak::Client.client_id if isempty?(client_id) + secret = Keycloak::Client.secret if isempty?(secret) proc = lambda { |token| if user_login.index('@').nil? search = {:username => user_login} else @@ -677,42 +674,42 @@ default_call(proc, client_id, secret) end def self.exists_name_or_email(value, user_id = '', client_id = '', secret = '') - client_id = Keycloak::Client.client_id if client_id.blank? - secret = Keycloak::Client.secret if secret.blank? + client_id = Keycloak::Client.client_id if isempty?(client_id) + secret = Keycloak::Client.secret if isempty?(secret) begin usuario = Keycloak::Internal.get_user_info(value, true, client_id, secret) if user_id.empty? || user_id != usuario['id'] - usuario.present? + !isempty?(usuario) else false end rescue StandardError false end end def self.logged_federation_user?(client_id = '', secret = '') - client_id = Keycloak::Client.client_id if client_id.blank? - secret = Keycloak::Client.secret if secret.blank? + client_id = Keycloak::Client.client_id if isempty?(client_id) + secret = Keycloak::Client.secret if isempty?(secret) info = get_logged_user_info(client_id, secret) info['federationLink'] != nil end def self.create_simple_user(username, password, email, first_name, last_name, realm_roles_names, client_roles_names, proc = nil, client_id = '', secret = '') - client_id = Keycloak::Client.client_id if client_id.blank? - secret = Keycloak::Client.secret if secret.blank? + client_id = Keycloak::Client.client_id if isempty?(client_id) + secret = Keycloak::Client.secret if isempty?(secret) begin username.downcase! user = get_user_info(username, true, client_id, secret) - newUser = false + new_user = false rescue Keycloak::UserLoginNotFound - newUser = true + new_user = true rescue raise end proc_default = lambda { |token| @@ -720,15 +717,15 @@ email: email, firstName: first_name, lastName: last_name, enabled: true } - if !newUser || Keycloak.generic_request(token["access_token"], + if !new_user || Keycloak.generic_request(token["access_token"], Keycloak::Admin.full_url("users/"), nil, user_representation, 'POST') - user = get_user_info(username, true, client_id, secret) if newUser + user = get_user_info(username, true, client_id, secret) if new_user credential_representation = { type: "password", temporary: false, value: password } @@ -741,11 +738,11 @@ { clientId: client_id }, nil, 'GET') if client_roles_names.count > 0 roles = [] client_roles_names.each do |r| - if r.present? + unless isempty?(r) role = JSON Keycloak.generic_request(token["access_token"], Keycloak::Admin.full_url("clients/#{client[0]['id']}/roles/#{r}"), nil, nil, 'GET') roles.push(role) end @@ -759,11 +756,11 @@ end if realm_roles_names.count > 0 roles = [] realm_roles_names.each do |r| - if r.present? + unless isempty?(r) role = JSON Keycloak.generic_request(token["access_token"], Keycloak::Admin.full_url("roles/#{r}"), nil, nil, 'GET') roles.push(role) end @@ -785,45 +782,45 @@ proc.call user unless proc.nil? end end def self.create_starter_user(username, password, email, client_roles_names, proc = nil, client_id = '', secret = '') - client_id = Keycloak::Client.client_id if client_id.blank? - secret = Keycloak::Client.secret if secret.blank? + client_id = Keycloak::Client.client_id if isempty?(client_id) + secret = Keycloak::Client.secret if isempty?(secret) Keycloak::Internal.create_simple_user(username, password, email, '', '', [], client_roles_names, proc, client_id, secret) end def self.get_client_roles(client_id = '', secret = '') - client_id = Keycloak::Client.client_id if client_id.blank? - secret = Keycloak::Client.secret if secret.blank? + client_id = Keycloak::Client.client_id if isempty?(client_id) + secret = Keycloak::Client.secret if isempty?(secret) proc = lambda {|token| - client = JSON Keycloak::Admin.get_clients({ clientId: client_id }, token["access_token"]) + client = JSON Keycloak::Admin.get_clients({ clientId: client_id }, token['access_token']) - Keycloak.generic_request(token["access_token"], + Keycloak.generic_request(token['access_token'], Keycloak::Admin.full_url("clients/#{client[0]['id']}/roles"), nil, nil, 'GET') } default_call(proc, client_id, secret) end def self.get_client_user_roles(user_id, client_id = '', secret = '') - client_id = Keycloak::Client.client_id if client_id.blank? - secret = Keycloak::Client.secret if secret.blank? + client_id = Keycloak::Client.client_id if isempty?(client_id) + secret = Keycloak::Client.secret if isempty?(secret) proc = lambda {|token| client = JSON Keycloak::Admin.get_clients({ clientId: client_id }, token["access_token"]) Keycloak::Admin.get_effective_client_level_role_composite_user(user_id, client[0]['id'], token["access_token"]) } default_call(proc, client_id, secret) end def self.has_role?(user_id, user_role, client_id = '', secret = '') - client_id = Keycloak::Client.client_id if client_id.blank? - secret = Keycloak::Client.secret if secret.blank? + client_id = Keycloak::Client.client_id if isempty?(client_id) + secret = Keycloak::Client.secret if isempty?(secret) roles = JSON get_client_user_roles(user_id, client_id, secret) if !roles.nil? roles.each do |role| return true if role['name'].to_s == user_role.to_s @@ -841,12 +838,12 @@ tk = nil resp = nil Keycloak::Client.get_installation - client_id = Keycloak::Client.client_id if client_id.blank? - secret = Keycloak::Client.secret if secret.blank? + client_id = Keycloak::Client.client_id if isempty?(client_id) + secret = Keycloak::Client.secret if isempty?(secret) payload = { 'client_id' => client_id, 'client_secret' => secret, 'grant_type' => 'client_credentials' } @@ -884,11 +881,10 @@ end Keycloak::Client.exec_request _request end end end - end private def self.generic_request(access_token, uri, query_parameters, body_parameter, method) @@ -943,11 +939,10 @@ else raise end _request.call - end def self.rescue_response(response) case response.code when 200..399 @@ -955,15 +950,11 @@ true else response.body end when 400..499 - begin - response.return! - rescue RestClient::ExceptionWithResponse => err - raise ActionController::RoutingError.new(err.response) - end + response.return! else if Keycloak.explode_exception response.return! else begin @@ -976,6 +967,6 @@ end end end end -require 'keycloak/exceptions' \ No newline at end of file +require 'keycloak/exceptions'