Skip to content

Commit

Permalink
Added authorize_url function and tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
jdennes committed Feb 11, 2013
1 parent 267cdab commit 0c63371
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 18 deletions.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,27 @@ The Campaign Monitor API supports authentication using either OAuth or an API ke

### Using OAuth

Depending on the environment you are developing in, you may wish to use a Python OAuth library to get access tokens for your users. If you use [Flask](http://flask.pocoo.org/), you may like to refer to this [example application](https://gist.github.com/jdennes/4754097), which uses the [Flask-OAuth](http://pythonhosted.org/Flask-OAuth/) package to authenticate.

If you don't use an OAuth library, you will need to manually get access tokens for your users by following the instructions included in the Campaign Monitor API [documentation](http://www.campaignmonitor.com/api/getting-started/#authenticating_with_oauth). This package provides functionality to help you do this, as described below.

You can retrieve the authorization URL for your application like so:

```python
from createsend import *

cs = CreateSend()
authorize_url = cs.authorize_url(
client_id='Client ID for your application',
client_secret='Client Secret for your application',
redirect_uri='Redirect URI for your application',
scope='The permission level your application requires',
state='Optional state data to be included'
)

# Your app would redirect your users to authorize_url
```

Once you have an access token and refresh token for your user, you authenticate using the `auth()` method like so:

```python
Expand Down
19 changes: 17 additions & 2 deletions createsend/createsend.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,20 @@ def reset_auth(self):
self.oauth = None
self.api_key = None

def authorize_url(self, client_id, client_secret, redirect_uri,
scope, state=None):
"""Get the authorization URL for your application, given the application's
client_id, client_secret, redirect_uri, scope, and optional state data."""
options = [
('client_id', client_id),
('client_secret', client_secret),
('redirect_uri', redirect_uri),
('scope', scope)
]
if state:
options.append(('state', state))
return "%s?%s" % (CreateSend.oauth_uri, urllib.urlencode(options))

def auth(self, auth):
"""Authenticate with the Campaign Monitor API using either OAuth or
an API key.
Expand Down Expand Up @@ -78,7 +92,7 @@ def stub_request(self, expected_url, filename, status=None, body=None):
self.fake_web = True
self.faker = get_faker(expected_url, filename, status, body)

def make_request(self, method, path, params={}, body="", username=None,
def make_request(self, method, path, params={}, body="", username=None,
password=None, base_uri=None, content_type=None, no_auth=None):
headers = {
'User-Agent': 'createsend-python-%s' % __version__,
Expand Down Expand Up @@ -182,7 +196,8 @@ def refresh_token(self, refresh_token=None):
class CreateSend(CreateSendBase):
"""Provides high level CreateSend functionality/data you'll probably need."""
base_uri = "https://api.createsend.com/api/v3"
oauth_token_uri = "https://api.createsend.com/oauth/token"
oauth_uri = "https://api.createsend.com/oauth"
oauth_token_uri = "%s/token" % oauth_uri

def apikey(self, site_url, username, password):
"""Gets your CreateSend API key, given your site url, username and password."""
Expand Down
67 changes: 51 additions & 16 deletions test/test_authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,39 @@ def setUp(self):
self.api_key = '123123123123123123123'
self.cs = CreateSend()

def test_deprecated_can_authenticate_by_setting_class_api_key(self):
"""The following line demonstrates the deprecated way in which
authentication should be handled."""
CreateSend.api_key = self.api_key
self.cs.stub_request("systemdate.json", "systemdate.json")
systemdate = self.cs.systemdate()
self.assertEquals(self.cs.headers['Authorization'], "Basic %s" % base64.b64encode("%s:x" % self.api_key))
self.assertEquals(systemdate, "2010-10-15 09:27:00")
def test_authorize_url_with_state(self):
client_id = 8998879
client_secret = 'iou0q9wud0q9wd0q9wid0q9iwd0q9wid0q9wdqwd'
redirect_uri = 'http://example.com/auth'
scope = 'ViewReports,CreateCampaigns,SendCampaigns'
state = 89879287

def test_deprecated_can_authenticate_by_setting_instance_api_key(self):
"""The following line demonstrates the deprecated way in which
authentication should be handled."""
self.cs.api_key = self.api_key
self.cs.stub_request("systemdate.json", "systemdate.json")
systemdate = self.cs.systemdate()
self.assertEquals(self.cs.headers['Authorization'], "Basic %s" % base64.b64encode("%s:x" % self.api_key))
self.assertEquals(systemdate, "2010-10-15 09:27:00")
self.cs.auth(self.oauth_credentials)
authorize_url = self.cs.authorize_url(
client_id=client_id,
client_secret=client_secret,
redirect_uri=redirect_uri,
scope=scope,
state=state)
self.assertEquals(authorize_url,
"https://api.createsend.com/oauth?client_id=8998879&client_secret=iou0q9wud0q9wd0q9wid0q9iwd0q9wid0q9wdqwd&redirect_uri=http%3A%2F%2Fexample.com%2Fauth&scope=ViewReports%2CCreateCampaigns%2CSendCampaigns&state=89879287"
)

def test_authorize_url_without_state(self):
client_id = 8998879
client_secret = 'iou0q9wud0q9wd0q9wid0q9iwd0q9wid0q9wdqwd'
redirect_uri = 'http://example.com/auth'
scope = 'ViewReports,CreateCampaigns,SendCampaigns'

self.cs.auth(self.oauth_credentials)
authorize_url = self.cs.authorize_url(
client_id=client_id,
client_secret=client_secret,
redirect_uri=redirect_uri,
scope=scope)
self.assertEquals(authorize_url,
"https://api.createsend.com/oauth?client_id=8998879&client_secret=iou0q9wud0q9wd0q9wid0q9iwd0q9wid0q9wdqwd&redirect_uri=http%3A%2F%2Fexample.com%2Fauth&scope=ViewReports%2CCreateCampaigns%2CSendCampaigns"
)

def test_can_authenticate_by_calling_auth_with_api_key(self):
self.cs.auth({'api_key': self.api_key})
Expand Down Expand Up @@ -60,3 +76,22 @@ def test_refresh_token(self):
self.assertEquals(new_refresh_token, "tGzv3JOkF0XG5Qx2TlKWIA")
self.assertEquals(self.cs.authentication,
{ 'access_token': new_access_token, 'refresh_token': new_refresh_token })

# Tests for the deprecated method of authenticating.
def test_deprecated_can_authenticate_by_setting_class_api_key(self):
"""The following line demonstrates the deprecated way in which
authentication should be handled."""
CreateSend.api_key = self.api_key
self.cs.stub_request("systemdate.json", "systemdate.json")
systemdate = self.cs.systemdate()
self.assertEquals(self.cs.headers['Authorization'], "Basic %s" % base64.b64encode("%s:x" % self.api_key))
self.assertEquals(systemdate, "2010-10-15 09:27:00")

def test_deprecated_can_authenticate_by_setting_instance_api_key(self):
"""The following line demonstrates the deprecated way in which
authentication should be handled."""
self.cs.api_key = self.api_key
self.cs.stub_request("systemdate.json", "systemdate.json")
systemdate = self.cs.systemdate()
self.assertEquals(self.cs.headers['Authorization'], "Basic %s" % base64.b64encode("%s:x" % self.api_key))
self.assertEquals(systemdate, "2010-10-15 09:27:00")

0 comments on commit 0c63371

Please sign in to comment.