mailjet / mailjet-gem

[API v3] Mailjet official Ruby GEM
https://dev.mailjet.com
Other
130 stars 72 forks source link

Not all resources support api_key and secret_key options #140

Closed todorus closed 3 years ago

todorus commented 6 years ago

Current behavior

options = {
    api_key: "1234567890",
    secret_key: "0987654321"
}
templates = Mailjet::Template.all(options: options)

The Mailjet gem generates the following request

url: https://api.mailjet.com/v3.1/REST/template?Options[api_key]=0987654321&Options[secret_key]=1234567890
headers: {
  'Accept'=>'application/json', 
  'Accept-Encoding'=>'deflate', 
  'Content-Type'=>'application/json', 
  'Host'=>'api.mailjet.com', 
  'User-Agent'=>'mailjet-api-v3-ruby/1.5.4'
}

Expected behavior It would expect it to filter out the api_key and secret_key options to generate the authorization header.

url: https://api.mailjet.com/v3.1/REST/template
headers:  {
   'Accept'=>'application/json', 
   'Accept-Encoding'=>'deflate', 
   'Content-Type'=>'application/json', 
   'Authorization'=>'Basic some-hash', 
   'Host'=>'api.mailjet.com', 
   'User-Agent'=>'mailjet-api-v3-ruby/1.5.4'
 }

Looking through the code it gives the impression that every resource should support these authorization options. I have only tested this with the send and template resource and support for it is inconsistent. Send supports it, Template does not.

Motivation I'm building a multi-tenant application, which will support Mailjet as a mailing solution. This means I cannot use the configuration option, as this will configure at a module level and can leak into other users requests.

I was happy to see that the Mailjet::Send.create method supports the injection of the keys, like so

options = {
    api_key: "1234567890",
    secret_key: "0987654321"
}
Mailjet::Send.create(
  {
    messages: [
      {
        From: {
          Email: sender_email,
          Name: sender_name
        },
        To: [
          {
            Email: member.email,
            Name: member.full_name
          }
        ],
        TemplateID: template_id,
        TemplateLanguage: true,
        Subject: subject,
        Variables: variables
      }
    ]
  },
  options
)

For now I'll use the workaround mentioned in #125

xab3r commented 3 years ago

@todorus I know this is an old thread. But if it's still an issue, here is what you can do. Usually resource's methods accept two arguments. First one is search parameters, like resource ID, limits etc. And the second argument is the options you are looking for - connection options, like public and private key to auth, server URL, API version etc:

def first(params = {}, options = {})
def all(params = {}, options = {})
def count(options = {})
def find(id, job_id = nil, options = {})
def create(attributes = {}, options = {})
def delete(id, options = {})
def save(options = {})
def update_attributes(attribute_hash = {}, options = {})

In your case, the correct method call should be

options = {
    api_key: "1234567890",
    secret_key: "0987654321"
}
templates  = Mailjet::Template.all({}, options)

This will generate the correct request with auth token in headers rather than in url:

HTTP GET https://api.mailjet.com/v3/REST/template
Accept: application/json
Authorization: <TOKEN>
...
xab3r commented 3 years ago

Resolved