require "openssl" require "base64" module Authentication extend ActiveSupport::Concern included do before_action :current_user helper_method :current_user helper_method :decrypt_header end def authenticate_user! id_dict = { "labs_user_id" => decrypt_header(request.headers["X-Auth-Newseye-Token"]) } # id_dict = { "labs_user_id" => "42" } @user = User.find_by(labs_user_id: id_dict["labs_user_id"]) if @user if !session[:current_user_id] # puts "Logging in the user since current_user_id was not set" login @user end else @user = User.new(id_dict) if @user.save login @user end end end def login(user) reset_session session[:current_user_id] = user.id # puts "The user id taken from session is " + String(session[:current_user_id]) end private def current_user Current.user ||= User.find_by(labs_user_id: decrypt_header(request.headers["X-Auth-Newseye-Token"])) # Current.user ||= User.find_by(labs_user_id: "42") end def decrypt_header(token) # TODO: store private key somewhere private_key = "OFE_GQ8Ri8MX-0rH_T0e9ZFIhy-q0n2VxBWPoOyJ1I0=" unpacked_key = Base64.urlsafe_decode64(private_key) signing_key = unpacked_key[0..15] encryption_key = unpacked_key[16..32] begin unpacked_token = Base64.urlsafe_decode64(token) version = unpacked_token[0] timestamp = unpacked_token[1..8] iv = unpacked_token[9..24] ciphertext = unpacked_token[25..-33] hmac = unpacked_token[-32..-1] computed_hmac = OpenSSL::HMAC.digest("SHA256", signing_key, unpacked_token[0..-33]) if OpenSSL.fixed_length_secure_compare(version, "\x80") && (timestamp.unpack("Q>")[0] - Time.now.to_i).abs < 3600 && OpenSSL.fixed_length_secure_compare(hmac, computed_hmac) # all good # puts "Token authenticated" else # do something now raise "Invalid Token" end d = OpenSSL::Cipher.new("AES-128-CBC") d.decrypt d.key = encryption_key d.iv = iv plain = d.update(ciphertext) + d.final rescue => e # do something now puts e.message, e.backtrace raise "Invalid Token" end end end