class OmniAuth::Globalid::Vault
Attributes
openid_token[RW]
private_key[RW]
Public Class Methods
new(openid_token: nil, token_url: nil, client_id: nil, client_secret: nil, redirect_uri: nil, private_key: nil, private_key_pass: nil, acrc_id: nil)
click to toggle source
# File lib/omniauth/globalid/vault.rb, line 6 def initialize(openid_token: nil, token_url: nil, client_id: nil, client_secret: nil, redirect_uri: nil, private_key: nil, private_key_pass: nil, acrc_id: nil) @openid_token = openid_token # TODO: Figure out a cleaner way to implement this! @token_url = token_url || "https://api.global.id/v1/auth/token" @client_id = client_id || ENV["GLOBALID_CLIENT_ID"] @client_secret = client_secret || ENV["GLOBALID_CLIENT_SECRET"] @redirect_uri = redirect_uri || ENV["GLOBALID_REDIRECT_URL"] @acrc_id = acrc_id || ENV["ACRC_ID"] # Clean up the private key in case environmental variables were extra escaped private_key ||= ENV["GLOBALID_PRIVATE_KEY"].gsub("\\n", "\n").gsub("\"", "") private_key_pass ||= ENV["GLOBALID_PRIVATE_KEY_PASS"] @private_key = OpenSSL::PKey::RSA.new(private_key, private_key_pass) end
Public Instance Methods
client_credentials_access_token()
click to toggle source
# File lib/omniauth/globalid/vault.rb, line 59 def client_credentials_access_token # TODO: figure out how to configure these without having to specify via environmental variables client_credentials_token_params = { client_id: @client_id, client_secret: @client_secret, redirect_uri: @redirect_uri, grant_type: "client_credentials", acrc_id: @acrc_id } client_credentials_response = Faraday.new(url: @token_url).post do |req| req.headers["Content-Type"] = "application/json" req.body = client_credentials_token_params.to_json end JSON.parse(client_credentials_response.body)["access_token"] # this is the only part of the client_credentials_response we use end
decrypted_pii()
click to toggle source
# File lib/omniauth/globalid/vault.rb, line 23 def decrypted_pii vault_response.map do |vault_data| # Decrypt the password for the vault data decrypted_data_password = private_key.private_decrypt(Base64.decode64(vault_data["encrypted_data_password"]), OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING) # The Initialization Vector is the first 32 bytes of the encrypted data iv = vault_data["encrypted_data"][0, 32] # The actual encrypted data is everything after the first 32 bytes encrypted_data = vault_data["encrypted_data"][32, vault_data["encrypted_data"].length] # Create a cipher that can decrypt the data that was encrypted in the vault cipher = OpenSSL::Cipher::Cipher.new("aes-256-cbc") cipher.decrypt # Tell the cipher instance that we are going to decrypt with it # The password and the IV are hex encoded cipher.key = Array(decrypted_data_password).pack("H*") # Encode the password in hex (base16) cipher.iv = Array(iv).pack("H*") # the initialization vector (iv) is first 32 chars of the encoded_data, hex encoded # Decode the base64 encoded data, and decrypt it! decrypted_pii = cipher.update(Base64.decode64(encrypted_data)) + cipher.final JSON.parse(decrypted_pii) end end
decrypted_tokens()
click to toggle source
# File lib/omniauth/globalid/vault.rb, line 51 def decrypted_tokens # Get the tokens to make requests to the vault, which is how you access the PII, by decrypting the encrypted_data_tokens encrypted_data_tokens.map do |claim_token| # The claim_tokens are base64 encoded private_key.private_decrypt(Base64.decode64(claim_token), OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING) end end
encrypted_data_tokens()
click to toggle source
# File lib/omniauth/globalid/vault.rb, line 43 def encrypted_data_tokens # Parsing this is a paid because the keys are dynamic # And we need the inside of the nested structure :( @openid_token.select { |k, v| k.match?("/claims/") } .reject { |k, v| k.match?("/claims/null") } .values.map(&:values).flatten end
vault_response()
click to toggle source
# File lib/omniauth/globalid/vault.rb, line 75 def vault_response result = Faraday.new(url: "https://api.global.id/v1/vault/get-encrypted-data").post do |req| req.headers["Authorization"] = "Bearer #{client_credentials_access_token}" req.headers["Content-Type"] = "application/json" req.body = { private_data_tokens: decrypted_tokens }.to_json end JSON.parse(result.body) end