0

I'm converting some python code to ruby. It's going ok so far, except I'm running into some issues with parameters. The python code is:

def sign_policy(policy):
  signed_policy = base64.b64encode(policy)
  signature = base64.b64encode(hmac.new(
    app.config.get('AWS_CLIENT_SECRET_KEY'), signed_policy, hashlib.sha1).
    digest())
  return { 'policy': signed_policy, 'signature': signature }

def sign_headers(headers):
  headers = bytearray(headers, 'utf-8')  # hmac doesn't want unicode
  return {
    'signature': base64.b64encode(hmac.new(
        app.config.get('AWS_CLIENT_SECRET_KEY'), headers, hashlib.sha1).
        digest())
  }

def s3_signature():
  request_payload = request.get_json()
  if request_payload.get('headers'):
      response_data = sign_headers(request_payload['headers']) 
  else:
      response_data = sign_policy(request.data)
  return jsonify(response_data)

My ruby version so far is:

def create
  puts params[:headers]
  if params[:headers].present?
    response_data = sign_headers(params[:headers]) 
  else
    response_data = sign_policy(params)
  end
  render json: response_data
end

private

def sign_policy(policy)
  signed_policy = Base64.encode64(policy).gsub("\n","")

  signature = Base64.encode64(
    OpenSSL::HMAC.digest(
      OpenSSL::Digest.new('sha1'), 
      AWS_SECRET_KEY, signed_policy)
  ).gsub("\n","")

  return { 'policy': signed_policy, 'signature': signature }
end

def sign_headers(headers)
  #headers = bytearray(headers, 'utf-8')
  return {
    'signature':  Base64.encode64(
    OpenSSL::HMAC.digest(   
      AWS_SECRET_KEY, headers, OpenSSL::Digest.new('sha1')
    ))
  }
end

I'm running into the following issue: no implicit conversion of ActionController::Parameters into String, which makes it obvious whats wrong (Params is a hash and it needs to be a string)..However, what is being passed in the python code? I'm missing what I should be passing?

5
  • Yeah the ruby code is happening inside a rails controller Commented Jul 22, 2017 at 3:47
  • @SebastiánPalma, Wouldn't `Base64.encode64(params[:policy]) just lead to the same error? Currently I'm just passing it in as a variable. Commented Jul 22, 2017 at 3:50
  • It is, however, in the create method of my controller, I'm grabbing the params and passing it to the sign_policy function. The variable policy in my sign_policy function should be a hash of all the request parameters I believe. Commented Jul 22, 2017 at 3:58
  • @SebastiánPalma, that's what I'm a little confused about. In the python code, doesn't it seem like it's passing the entire parameter request? The params I'm receiving don't have a key for "policy". Commented Jul 22, 2017 at 4:10
  • I actually just figured it out. request.data in flask returns a string. In ruby, I just had to convert the params to a string. Since you led me down the problem solving track, if you add an answer I'll accept it @SebastiánPalma Commented Jul 22, 2017 at 4:17

1 Answer 1

1

Most probably you need to pass a single value, String or any other, it depends on the data type you need to pass to use Base64.encode64(policy).

As you're passing params[:headers] in the sign_headers method call, in the case of the sign_policy call, you're passing params which is the whole ActionController::Parameters, try debugging the values you sent on params to send the needed value.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.