Skip to content

Instantly share code, notes, and snippets.

@dusk0r
Created April 21, 2017 11:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dusk0r/f5a2982b2c253d26caa5246608323b46 to your computer and use it in GitHub Desktop.
Save dusk0r/f5a2982b2c253d26caa5246608323b46 to your computer and use it in GitHub Desktop.
RavenDB Auth in Ruby
require 'restclient'
require 'digest/sha1'
require 'base64'
require 'securerandom'
require 'json'
class RavenCheck
@server_url
@api_key_name
@api_key_secret
def initialize(server_url, api_key_name, api_key_secret)
throw 'Invalid ServerUrl' unless server_url =~ URI::regexp
throw 'api_key_name empty' unless !api_key_name.to_s.empty?
throw 'api_key_secret empty' unless !api_key_secret.to_s.empty?
@server_url = server_url
@api_key_name = api_key_name
@api_key_secret = api_key_secret
end
def get_bearer_token
request = get_auth_request_hash
response = prepare_response(request['challenge'])
public_key = create_rsa_key(request['modulus'], request['exponent'])
data = "api key name=#{@api_key_name},challenge=#{request['challenge']},response=#{response}"
response_data = "exponent=#{request['exponent']},modulus=#{request['modulus']},data=#{encrypt(public_key, data)}"
get_auth_token(response_data)
end
def get_warnings
res = RestClient.get("#{@server_url}/docs?id=Raven%2FAlerts", headers={ Authorization: "Bearer #{get_bearer_token}"})
JSON.parse(res.body)
end
private
def get_auth_request_hash
res = RestClient.post("#{@server_url}/OAuth/API-Key", {}){|response,request,result| response }
wwwauth_header = res.headers[:www_authenticate]
wwwauth_header[7, wwwauth_header.length - 7] # Remove 'Raven '
.split(',')
.map{|str|
idx = str.index '='
[str[0, idx].strip.downcase, str[idx+1, str.length]]
}
.to_h
end
def get_auth_token (response_data)
res = RestClient.post("#{@server_url}/OAuth/API-Key", response_data, headers={ grant_type: 'client_credentials'})
res.body.to_s
end
def prepare_response (challenge)
input = challenge + ";" + @api_key_secret
Digest::SHA1.base64digest input
end
def create_rsa_key (modulus_base64, exponent_base64)
key = OpenSSL::PKey::RSA.new
exponent = OpenSSL::BN.new(Base64.decode64(exponent_base64).unpack("H*").first, 16)
modulus = OpenSSL::BN.new(Base64.decode64(modulus_base64).unpack("H*").first, 16)
key.e = exponent
key.n = modulus
key
end
def encrypt(public_key, data)
key = SecureRandom.random_bytes(32)
iv = SecureRandom.random_bytes(16)
key_and_iv_encrypted = public_key.public_encrypt(key + iv, OpenSSL::PKey::RSA::PKCS1_OAEP_PADDING)
cipher = OpenSSL::Cipher::AES256.new(:CBC)
cipher.encrypt
cipher.key = key
cipher.iv = iv
encrypted = cipher.update(data) + cipher.final
Base64.encode64 (key_and_iv_encrypted + encrypted)
end
end
# RavenDB API-Key: name/abcdefg
check = RavenCheck.new('http://ravenserver:8080', 'name', 'abcdefg')
p check.get_warnings
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment