module Keycloak::Client

Constants

KEYCLOACK_CONTROLLER_DEFAULT

Attributes

auth_server_url[RW]
client_id[R]
configuration[R]
public_key[R]
realm[RW]
secret[R]

Public Class Methods

decoded_access_token(access_token = '') click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 341
def self.decoded_access_token(access_token = '')
  access_token = self.token["access_token"] if access_token.empty?
  JWT.decode access_token, @public_key, false, { :algorithm => 'RS256' }
end
decoded_refresh_token(refresh_token = '') click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 346
def self.decoded_refresh_token(refresh_token = '')
  refresh_token = self.token["access_token"] if refresh_token.empty?
  JWT.decode refresh_token, @public_key, false, { :algorithm => 'RS256' }
end
external_attributes() click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 333
def self.external_attributes
  if !Keycloak.proc_external_attributes.nil?
    Keycloak.proc_external_attributes.call
  else
    raise Keycloak::ProcExternalAttributesNotDefined
  end
end
get_attribute(attributeName, access_token = '') click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 318
def self.get_attribute(attributeName, access_token = '')
  verify_setup

  attr = decoded_access_token(access_token)[0]
  attr[attributeName]
end
get_token(user, password, client_id = '', secret = '', scope = nil) click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 46
def self.get_token(user, password, client_id = '', secret = '', scope = nil)
  setup_module

  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,
              "grant_type" => "password" }

  payload = fill_scope(payload, scope)

  mount_request_token(payload)
end
get_token_by_client_credentials(client_id = '', secret = '') click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 140
def self.get_token_by_client_credentials(client_id = '', secret = '')
  setup_module

  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' }

  mount_request_token(payload)
end
get_token_by_code(code, redirect_uri, client_id = '', secret = '', scope = nil) click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 63
def self.get_token_by_code(code, redirect_uri, client_id = '', secret = '', scope = nil)
  verify_setup

  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',
              'redirect_uri' => redirect_uri }

  payload = fill_scope(payload, scope)

  mount_request_token(payload)
end
get_token_by_exchange(issuer, issuer_token, client_id = '', secret = '', token_endpoint = '') click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 80
def self.get_token_by_exchange(issuer, issuer_token, client_id = '', secret = '', token_endpoint = '')
  setup_module

  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' }

  if !@custom_host_header.nil?
    header['Host'] = @custom_host_header
  end

  _request = -> do
    RestClient.post(token_endpoint, payload, header){|response, request, result|
    # case response.code
    # when 200
    # response.body
    # else
    # response.return!
    # end
      response.body
    }
  end
  exec_request _request
end
get_token_by_refresh_token(refresh_token = '', client_id = '', secret = '') click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 125
def self.get_token_by_refresh_token(refresh_token = '', client_id = '', secret = '')
  verify_setup

  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' }

  mount_request_token(payload)
end
get_token_introspection(token = '', client_id = '', secret = '', token_introspection_endpoint = '') click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 153
def self.get_token_introspection(token = '', client_id = '', secret = '', token_introspection_endpoint = '')
  verify_setup

  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}"

  header = { 'Content-Type' => 'application/x-www-form-urlencoded',
             'authorization' => authorization }

  if !@custom_host_header.nil?
    header['Host'] = @custom_host_header
  end

  _request = -> do
    RestClient.post(token_introspection_endpoint, payload, header){|response, request, result|
      case response.code
      when 200..399
        response.body
      else
        response.return!
      end
    }
  end

  exec_request _request
end
get_userinfo(access_token = '', userinfo_endpoint = '') click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 247
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 isempty?(userinfo_endpoint)

  payload = { 'access_token' => access_token }

  header = { 'Content-Type' => 'application/x-www-form-urlencoded' }

  if !@custom_host_header.nil?
    header['Host'] = @custom_host_header
  end

  _request = -> do
    RestClient.post(userinfo_endpoint, payload, header){ |response, request, result|
      case response.code
      when 200
        response.body
      else
        response.return!
      end
    }
  end

  exec_request _request
end
get_userinfo_issuer(access_token = '', userinfo_endpoint = '') click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 108
def self.get_userinfo_issuer(access_token = '', userinfo_endpoint = '')
  verify_setup

  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
    RestClient.post(userinfo_endpoint, payload, header){ |response, request, result|
      response.body
    }
  end

  exec_request _request
end
has_role?(user_role, access_token = '', client_id = '', secret = '', token_introspection_endpoint = '') click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 281
def self.has_role?(user_role, access_token = '', client_id = '', secret = '', token_introspection_endpoint = '')
  verify_setup

  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]
    unless dt.nil?
      dt['roles'].each do |role|
        return true if role.to_s == user_role.to_s
      end
    end
  end
  false
end
logout(redirect_uri = '', refresh_token = '', client_id = '', secret = '', end_session_endpoint = '') click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 204
def self.logout(redirect_uri = '', refresh_token = '', client_id = '', secret = '', end_session_endpoint = '')
  verify_setup

  if !refresh_token.empty? || self.token

    refresh_token = self.token['refresh_token'] if refresh_token.empty?
    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 !@custom_host_header.nil?
      header['Host'] = @custom_host_header
    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
          true
        else
          response.return!
        end
      }
    end

    exec_request _request
  else
    true
  end
end
token() click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 325
def self.token
  if !Keycloak.proc_cookie_token.nil?
    JSON Keycloak.proc_cookie_token.call
  else
    raise Keycloak::ProcCookieTokenNotDefined
  end
end
url_login_redirect(redirect_uri, response_type = 'code', client_id = '', authorization_endpoint = '', scope = nil) click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 187
def self.url_login_redirect(redirect_uri, response_type = 'code', client_id = '', authorization_endpoint = '', scope = nil)
  verify_setup

  client_id = @client_id if isempty?(client_id)
  authorization_endpoint = @configuration['authorization_endpoint'] if isempty?(authorization_endpoint)

  payload = {
    "response_type" => response_type,
    "client_id" => client_id,
    "redirect_uri" => redirect_uri
  }
  payload = fill_scope(payload, scope)

  p = URI.encode_www_form(payload)
  "#{authorization_endpoint}?#{p}"
end
url_user_account() click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 275
def self.url_user_account
  verify_setup

  "#{@auth_server_url}/realms/#{@realm}/account"
end
user_signed_in?(access_token = '', client_id = '', secret = '', token_introspection_endpoint = '') click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 300
def self.user_signed_in?(access_token = '', client_id = '', secret = '', token_introspection_endpoint = '')
  verify_setup

  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
      raise
    else
      false
    end
  end
end

Private Class Methods

decoded_id_token(idToken = '') click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 436
def self.decoded_id_token(idToken = '')
  tk = self.token
  idToken = tk["id_token"] if idToken.empty?
  if idToken
    @decoded_id_token = JWT.decode idToken, @public_key, false, { :algorithm => 'RS256' }
  end
end
exec_request(proc_request) click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 389
def self.exec_request(proc_request)
  if Keycloak.explode_exception
    proc_request.call
  else
    begin
      proc_request.call
    rescue RestClient::ExceptionWithResponse => err
      err.response
    end
  end
end
fill_scope(payload, scope) click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 384
def self.fill_scope(payload, scope)
  payload["scope"] = scope.join(" ") unless scope.nil? or scope.empty?
  payload
end
get_installation() click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 355
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"]
    @custom_host_header = installation["custom_host_header"]
  else
    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
mount_request_token(payload) click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 415
def self.mount_request_token(payload)
  header = {'Content-Type' => 'application/x-www-form-urlencoded'}

  if !@custom_host_header.nil?
    header['Host'] = @custom_host_header
  end

  _request = -> do
    RestClient.post(@configuration['token_endpoint'], payload, header){|response, request, result|
      case response.code
      when 200
        response.body
      else
        response.return!
      end
    }
  end

  exec_request _request
end
openid_configuration() click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 401
def self.openid_configuration
  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
  if response.code == 200
    @configuration = JSON response.body
  else
    response.return!
  end
end
setup_module() click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 377
def self.setup_module
  Keycloak.proxy ||= ''
  Keycloak.keycloak_controller ||= KEYCLOACK_CONTROLLER_DEFAULT
  Keycloak.validate_token_when_call_has_role ||= false
  get_installation
end
verify_setup() click to toggle source
# File lib/sqsc-keycloak-ruby.rb, line 373
def self.verify_setup
  get_installation if @configuration.nil?
end