Skip to content

Commit 72fc753

Browse files
committed
Changing OX3APIClient to Client
1 parent 6e88438 commit 72fc753

2 files changed

Lines changed: 207 additions & 211 deletions

File tree

ox3apiclient/__init__.py

Lines changed: 207 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,211 @@
11
# -*- coding: utf-8 -*-
22

3-
from ox3apiclient import *
3+
import cookielib
4+
import json
5+
import oauth2 as oauth
6+
import urllib
7+
import urllib2
8+
import urlparse
49

510
__version__ = '0.1.0'
11+
12+
REQUEST_TOKEN_URL = 'https://sso.openx.com/api/index/initiate'
13+
ACCESS_TOKEN_URL = 'https://sso.openx.com/api/index/token'
14+
AUTHORIZATION_URL = 'https://sso.openx.com/login/process'
15+
API_PATH = '/ox/3.0'
16+
HTTP_METHOD_OVERRIDES = ['DELETE', 'PUT']
17+
18+
class Client(object):
19+
20+
def __init__(self, domain, realm, consumer_key, consumer_secret,
21+
callback_url='oob',
22+
scheme='http',
23+
request_token_url=REQUEST_TOKEN_URL,
24+
access_token_url=ACCESS_TOKEN_URL,
25+
authorization_url=AUTHORIZATION_URL,
26+
api_path=API_PATH):
27+
"""
28+
29+
domain -- Your UI domain. The API is accessed off this domain.
30+
realm -- Your sso realm. While not necessary for all OAuth
31+
implementations, it is a requirement for OpenX Enterprise
32+
consumer_key -- Your consumer key.
33+
consumer_secret -- Your consumer secret.
34+
callback_url -- Callback URL to redirect to on successful authorization.
35+
We default to 'oob' for headless login.
36+
request_token -- Only override for debugging.
37+
access_token -- Only override for debugging.
38+
authorization_url -- Only override for debugging.
39+
api_path -- Only override for debugging.
40+
"""
41+
self.domain = domain
42+
self.realm = realm
43+
self.consumer_key = consumer_key
44+
self.consumer_secret = consumer_secret
45+
self.callback_url = callback_url
46+
self.scheme=scheme
47+
self.request_token_url = request_token_url
48+
self.access_token_url = access_token_url
49+
self.authorization_url = authorization_url
50+
self.api_path = api_path
51+
52+
# You shouldn't need to access the oauth2 consumer and token objects
53+
# directly so we'll keep them "private".
54+
self._consumer = oauth.Consumer(self.consumer_key, self.consumer_secret)
55+
self._token = None
56+
57+
# Similarly you probably won't need to access the cookie jar directly,
58+
# so it is private as well.
59+
self._cookie_jar = cookielib.LWPCookieJar()
60+
opener = \
61+
urllib2.build_opener(urllib2.HTTPCookieProcessor(self._cookie_jar))
62+
63+
urllib2.install_opener(opener)
64+
65+
def _sign_request(self, req):
66+
"""Utility method to sign a request."""
67+
parameters = {'oauth_callback': self.callback_url}
68+
headers = req.headers
69+
data = req.data
70+
71+
# Add any (POST) data to the parameters to be signed in the OAuth
72+
# request.
73+
if data:
74+
parameters.update(data)
75+
76+
# Create a temporary oauth2 Request object and sign it so we can steal
77+
# the Authorization header.
78+
oauth_req = oauth.Request.from_consumer_and_token(
79+
consumer=self._consumer,
80+
token=self._token,
81+
http_method=req.get_method(),
82+
http_url=req.get_full_url(),
83+
parameters=parameters,
84+
is_form_encoded=True)
85+
86+
oauth_req.sign_request(
87+
oauth.SignatureMethod_HMAC_SHA1(),
88+
self._consumer,
89+
self._token)
90+
91+
# Update our original requests headers to include the OAuth Authorization
92+
# header and return it.
93+
req.headers.update(oauth_req.to_header(realm=self.realm))
94+
return \
95+
urllib2.Request(req.get_full_url(), headers=req.headers, data=data)
96+
97+
def request(self, url, method='GET', headers={}, data=None, sign=False):
98+
"""Helper method to make a (optionally OAuth signed) HTTP request."""
99+
100+
# Since we are using a urllib2.Request object we need to assign a value
101+
# other than None to "data" in order to make the request a POST request,
102+
# even if there is no data to post.
103+
if method == 'POST':
104+
data = data if data else ''
105+
106+
req = urllib2.Request(url, headers=headers, data=data)
107+
108+
# We need to set the request's get_method function to return a HTTP
109+
# method for any values other than GET or POST.
110+
if method in HTTP_METHOD_OVERRIDES:
111+
req.get_method = lambda: method
112+
113+
if sign:
114+
req = self._sign_request(req)
115+
116+
# Stringify data.
117+
if data:
118+
req.add_data(urllib.urlencode(req.get_data()))
119+
120+
return urllib2.urlopen(req)
121+
122+
def fetch_request_token(self):
123+
"""Helper method to fetch and set request token.
124+
125+
Returns token string.
126+
"""
127+
res = self.request(url=self.request_token_url, method='POST', sign=True)
128+
self._token = oauth.Token.from_string(res.read())
129+
return self._token
130+
131+
def authorize_token(self, email, password):
132+
"""Helper method to authorize."""
133+
data = {
134+
'email': email,
135+
'password': password,
136+
'oauth_token': self._token.key}
137+
138+
res = self.request(
139+
url=self.authorization_url,
140+
method='POST',
141+
data=data,
142+
sign=True)
143+
144+
verifier = urlparse.parse_qs(res.read())['oauth_verifier'][0]
145+
self._token.set_verifier(verifier)
146+
147+
def fetch_access_token(self):
148+
"""Helper method to fetch and set access token.
149+
150+
Returns token string.
151+
"""
152+
res = self.request(url=self.access_token_url, method='POST', sign=True)
153+
self._token = oauth.Token.from_string(res.read())
154+
return self._token
155+
156+
def validate_session(self):
157+
"""Validate an API session."""
158+
159+
# We need to store our access token as the openx3_access_token cookie.
160+
# This cookie will be passed to all future API requests.
161+
cookie = cookielib.Cookie(
162+
version=0,
163+
name='openx3_access_token',
164+
value=self._token.key,
165+
port=None,
166+
port_specified=False,
167+
domain=self.domain,
168+
domain_specified=True,
169+
domain_initial_dot=False,
170+
path='/',
171+
path_specified=True,
172+
secure=False,
173+
expires=None,
174+
discard=False,
175+
comment=None,
176+
comment_url=None,
177+
rest={})
178+
179+
self._cookie_jar.set_cookie(cookie)
180+
181+
url = '%s://%s%s/a/session/validate' % (self.scheme,
182+
self.domain,
183+
self.api_path)
184+
185+
res = self.request(url=url, method='PUT')
186+
return res.read()
187+
188+
def _resolve_url(self, url):
189+
""""""
190+
parse_res = urlparse.urlparse(url)
191+
if not parse_res.scheme:
192+
url ='%s://%s%s%s' % (self.scheme, self.domain, self.api_path,
193+
parse_res.path)
194+
url = url + '?' + parse_res.query if parse_res.query else url
195+
196+
return url
197+
198+
def get(self, url):
199+
""""""
200+
res = self.request(self._resolve_url(url), method='GET')
201+
return json.loads(res.read())
202+
203+
def post(self, url, data=None):
204+
""""""
205+
res = self.request(self._resolve_url(url), method='POST', data=data)
206+
return json.loads(res.read())
207+
208+
def delete(self, url):
209+
""""""
210+
res = self.request(self._resolve_url(url), method='DELETE')
211+
return json.loads(res.read())

0 commit comments

Comments
 (0)