Class: UkrsibAPI::Authentication
- Inherits:
-
Object
- Object
- UkrsibAPI::Authentication
- Defined in:
- lib/ukrsib_api/authentication.rb
Constant Summary collapse
- BASE_URL =
"https://business.ukrsibbank.com/morpheus"- TOKEN_URL =
"#{BASE_URL}/token"
Instance Attribute Summary collapse
-
#client_params ⇒ Object
readonly
Returns the value of attribute client_params.
-
#private_key ⇒ Object
readonly
Returns the value of attribute private_key.
-
#tokens ⇒ Object
readonly
Returns the value of attribute tokens.
Instance Method Summary collapse
- #access_token ⇒ Object
-
#authorize(redirect_url: nil) ⇒ Hash
Initiates the OAuth2 authorization process.
-
#fetch_token(client_code: nil, code: nil) ⇒ Hash
Exchanges an authorization code or client code for an access token.
- #generate_signature(data_string) ⇒ Object
-
#initialize(private_key: nil, client_params: nil, tokens: nil) ⇒ Authentication
constructor
Initializes authentication using provided credentials or defaults from config.
- #refresh_access_token ⇒ Object
- #refresh_token_if_needed ⇒ Object
- #valid_token? ⇒ Boolean
Constructor Details
#initialize(private_key: nil, client_params: nil, tokens: nil) ⇒ Authentication
Initializes authentication using provided credentials or defaults from config.
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
# File 'lib/ukrsib_api/authentication.rb', line 33 def initialize(private_key: nil, client_params: nil, tokens: nil) @private_key = OpenSSL::PKey::RSA.new(private_key || UkrsibAPI.private_key) @client_params = { client_id: client_params&.dig(:client_id) || UkrsibAPI.client_id, client_secret: client_params&.dig(:client_secret) || UkrsibAPI.client_secret }.compact unless tokens UkrsibAPI.logger.warn "No tokens provided, authenticate first, or pass UkrsibAPI::Authentication with existing tokens to UkrsibAPI::Client" return end @tokens = tokens&.slice(:access_token, :refresh_token, :expires_at) return unless @tokens && !@tokens[:expires_at] raise ArgumentError, "Missing :expires_at in tokens, it should be a Time object, e.g. Time.now + expires_in" end |
Instance Attribute Details
#client_params ⇒ Object (readonly)
Returns the value of attribute client_params.
14 15 16 |
# File 'lib/ukrsib_api/authentication.rb', line 14 def client_params @client_params end |
#private_key ⇒ Object (readonly)
Returns the value of attribute private_key.
14 15 16 |
# File 'lib/ukrsib_api/authentication.rb', line 14 def private_key @private_key end |
#tokens ⇒ Object (readonly)
Returns the value of attribute tokens.
14 15 16 |
# File 'lib/ukrsib_api/authentication.rb', line 14 def tokens @tokens end |
Instance Method Details
#access_token ⇒ Object
51 52 53 54 55 56 57 |
# File 'lib/ukrsib_api/authentication.rb', line 51 def access_token unless valid_token? UkrsibAPI.logger.warn "Access token is invalid or expired. Refreshing..." refresh_access_token end @tokens[:access_token] end |
#authorize(redirect_url: nil) ⇒ Hash
Initiates the OAuth2 authorization process. This method should be called first to obtain an authorization URL to which the client should be redirected.
after the user has authorized the client, only then must the #fetch_token method be called.
76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/ukrsib_api/authentication.rb', line 76 def (redirect_url: nil) UkrsibAPI.logger.warn "Already authorized, redundant call to authorize" if tokens params = @client_params.clone params[:response_type] = "code" if redirect_url params[:redirect_uri] = redirect_url else params[:client_code] = SecureRandom.uuid end url_params = URI.encode_www_form(params) response = Faraday.get("#{BASE_URL}/authorize?#{url_params}") raise Error, "Authorization request failed with #{response.status}, #{response.body}" if response.status == 400 { client_code: params[:client_code], location: response.headers["location"] } end |
#fetch_token(client_code: nil, code: nil) ⇒ Hash
Exchanges an authorization code or client code for an access token.
It requires either a ‘client_code` (if no redirect URI was used) or an authorization `code` if the user was redirected back after authorization.
This method is called after the user has authorized the client via #authorize method with the browser. ‘code` is used when #authorize method was called with redirect_uri. It is found in the redirect to your server. `client_code` is used when no redirect_uri is provided for #authorize method. It is returned by #authorize method.
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/ukrsib_api/authentication.rb', line 121 def fetch_token(client_code: nil, code: nil) raise ArgumentError, "Either client_code or code must be provided" if client_code.nil? && code.nil? params = @client_params.clone if client_code params[:client_code] = client_code params[:grant_type] = "client_code" else params[:grant_type] = "authorization_code" params[:code] = code end response = Faraday.post(TOKEN_URL) do |req| req.headers["Content-Type"] = "application/x-www-form-urlencoded" req.body = URI.encode_www_form(params) end store_token(response) end |
#generate_signature(data_string) ⇒ Object
164 165 166 167 |
# File 'lib/ukrsib_api/authentication.rb', line 164 def generate_signature(data_string) signature = @private_key.sign(OpenSSL::Digest.new("SHA512"), data_string) Base64.strict_encode64(signature) end |
#refresh_access_token ⇒ Object
141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/ukrsib_api/authentication.rb', line 141 def refresh_access_token return NotAuthorizedError unless @tokens && @tokens[:refresh_token] params = client_params.clone.merge({ grant_type: "refresh_token", refresh_token: @tokens[:refresh_token] }) response = Faraday.post(TOKEN_URL) do |req| req.headers["Content-Type"] = "application/x-www-form-urlencoded" req.body = URI.encode_www_form(params) end store_token(response) end |
#refresh_token_if_needed ⇒ Object
157 158 159 160 161 162 |
# File 'lib/ukrsib_api/authentication.rb', line 157 def refresh_token_if_needed return if valid_token? UkrsibAPI.logger.info "Refreshing expired token..." refresh_access_token end |
#valid_token? ⇒ Boolean
153 154 155 |
# File 'lib/ukrsib_api/authentication.rb', line 153 def valid_token? @tokens && @tokens[:access_token] && @tokens[:expires_at] && Time.now - 3600 < @tokens[:expires_at] end |