diff --git a/helios_auth/auth_systems/facebookclient/__init__.py b/helios_auth/auth_systems/facebookclient/__init__.py deleted file mode 100644 index df8fe2233d47ba65e3d093a819b3cbb850f92eaa..0000000000000000000000000000000000000000 --- a/helios_auth/auth_systems/facebookclient/__init__.py +++ /dev/null @@ -1,1430 +0,0 @@ -#! /usr/bin/env python -# -# pyfacebook - Python bindings for the Facebook API -# -# Copyright (c) 2008, Samuel Cormier-Iijima -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of the author nor the names of its contributors may -# be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -""" -Python bindings for the Facebook API (pyfacebook - http://code.google.com/p/pyfacebook) - -PyFacebook is a client library that wraps the Facebook API. - -For more information, see - -Home Page: http://code.google.com/p/pyfacebook -Developer Wiki: http://wiki.developers.facebook.com/index.php/Python -Facebook IRC Channel: #facebook on irc.freenode.net - -PyFacebook can use simplejson if it is installed, which -is much faster than XML and also uses less bandwith. Go to -http://undefined.org/python/#simplejson to download it, or do -apt-get install python-simplejson on a Debian-like system. -""" - -import binascii -import hashlib -import http.client -import mimetypes -import struct -import time -import urllib.error -import urllib.parse -import urllib.request - -# try to use simplejson first, otherwise fallback to XML -RESPONSE_FORMAT = 'JSON' - -import json - -# try: -# import json as simplejson -# except ImportError: -# try: -# import simplejson -# except ImportError: -# try: -# from django.utils import simplejson -# except ImportError: -# try: -# import jsonlib as simplejson -# simplejson.loads -# except (ImportError, AttributeError): -# from xml.dom import minidom -# RESPONSE_FORMAT = 'XML' - -# support Google App Engine. GAE does not have a working urllib.urlopen. -try: - from google.appengine.api import urlfetch - - def urlread(url, data=None, headers=None): - if data is not None: - if headers is None: - headers = {"Content-type": "application/x-www-form-urlencoded"} - method = urlfetch.POST - else: - if headers is None: - headers = {} - method = urlfetch.GET - - result = urlfetch.fetch(url, method=method, - payload=data, headers=headers) - - if result.status_code == 200: - return result.content - else: - raise urllib.error.URLError("fetch error url=%s, code=%d" % (url, result.status_code)) - -except ImportError: - def urlread(url, data=None): - res = urllib.request.urlopen(url, data=data) - return res.read() - -__all__ = ['Facebook'] - -VERSION = '0.1' - -FACEBOOK_URL = 'http://api.facebook.com/restserver.php' -FACEBOOK_SECURE_URL = 'https://api.facebook.com/restserver.php' - -class json(object): pass - -# simple IDL for the Facebook API -METHODS = { - 'application': { - 'getPublicInfo': [ - ('application_id', int, ['optional']), - ('application_api_key', str, ['optional']), - ('application_canvas_name', str,['optional']), - ], - }, - - # admin methods - 'admin': { - 'getAllocation': [ - ('integration_point_name', str, []), - ], - }, - - # auth methods - 'auth': { - 'revokeAuthorization': [ - ('uid', int, ['optional']), - ], - }, - - # feed methods - 'feed': { - 'publishStoryToUser': [ - ('title', str, []), - ('body', str, ['optional']), - ('image_1', str, ['optional']), - ('image_1_link', str, ['optional']), - ('image_2', str, ['optional']), - ('image_2_link', str, ['optional']), - ('image_3', str, ['optional']), - ('image_3_link', str, ['optional']), - ('image_4', str, ['optional']), - ('image_4_link', str, ['optional']), - ('priority', int, ['optional']), - ], - - 'publishActionOfUser': [ - ('title', str, []), - ('body', str, ['optional']), - ('image_1', str, ['optional']), - ('image_1_link', str, ['optional']), - ('image_2', str, ['optional']), - ('image_2_link', str, ['optional']), - ('image_3', str, ['optional']), - ('image_3_link', str, ['optional']), - ('image_4', str, ['optional']), - ('image_4_link', str, ['optional']), - ('priority', int, ['optional']), - ], - - 'publishTemplatizedAction': [ - ('title_template', str, []), - ('page_actor_id', int, ['optional']), - ('title_data', json, ['optional']), - ('body_template', str, ['optional']), - ('body_data', json, ['optional']), - ('body_general', str, ['optional']), - ('image_1', str, ['optional']), - ('image_1_link', str, ['optional']), - ('image_2', str, ['optional']), - ('image_2_link', str, ['optional']), - ('image_3', str, ['optional']), - ('image_3_link', str, ['optional']), - ('image_4', str, ['optional']), - ('image_4_link', str, ['optional']), - ('target_ids', list, ['optional']), - ], - - 'registerTemplateBundle': [ - ('one_line_story_templates', json, []), - ('short_story_templates', json, ['optional']), - ('full_story_template', json, ['optional']), - ('action_links', json, ['optional']), - ], - - 'deactivateTemplateBundleByID': [ - ('template_bundle_id', int, []), - ], - - 'getRegisteredTemplateBundles': [], - - 'getRegisteredTemplateBundleByID': [ - ('template_bundle_id', str, []), - ], - - 'publishUserAction': [ - ('template_bundle_id', int, []), - ('template_data', json, ['optional']), - ('target_ids', list, ['optional']), - ('body_general', str, ['optional']), - ('story_size', int, ['optional']), - ], - }, - - # fql methods - 'fql': { - 'query': [ - ('query', str, []), - ], - }, - - # friends methods - 'friends': { - 'areFriends': [ - ('uids1', list, []), - ('uids2', list, []), - ], - - 'get': [ - ('flid', int, ['optional']), - ], - - 'getLists': [], - - 'getAppUsers': [], - }, - - # notifications methods - 'notifications': { - 'get': [], - - 'send': [ - ('to_ids', list, []), - ('notification', str, []), - ('email', str, ['optional']), - ('type', str, ['optional']), - ], - - 'sendRequest': [ - ('to_ids', list, []), - ('type', str, []), - ('content', str, []), - ('image', str, []), - ('invite', bool, []), - ], - - 'sendEmail': [ - ('recipients', list, []), - ('subject', str, []), - ('text', str, ['optional']), - ('fbml', str, ['optional']), - ] - }, - - # profile methods - 'profile': { - 'setFBML': [ - ('markup', str, ['optional']), - ('uid', int, ['optional']), - ('profile', str, ['optional']), - ('profile_action', str, ['optional']), - ('mobile_fbml', str, ['optional']), - ('profile_main', str, ['optional']), - ], - - 'getFBML': [ - ('uid', int, ['optional']), - ('type', int, ['optional']), - ], - - 'setInfo': [ - ('title', str, []), - ('type', int, []), - ('info_fields', json, []), - ('uid', int, []), - ], - - 'getInfo': [ - ('uid', int, []), - ], - - 'setInfoOptions': [ - ('field', str, []), - ('options', json, []), - ], - - 'getInfoOptions': [ - ('field', str, []), - ], - }, - - # users methods - 'users': { - 'getInfo': [ - ('uids', list, []), - ('fields', list, [('default', ['name'])]), - ], - - 'getStandardInfo': [ - ('uids', list, []), - ('fields', list, [('default', ['uid'])]), - ], - - 'getLoggedInUser': [], - - 'isAppAdded': [], - - 'hasAppPermission': [ - ('ext_perm', str, []), - ('uid', int, ['optional']), - ], - - 'setStatus': [ - ('status', str, []), - ('clear', bool, []), - ('status_includes_verb', bool, ['optional']), - ('uid', int, ['optional']), - ], - }, - - # events methods - 'events': { - 'get': [ - ('uid', int, ['optional']), - ('eids', list, ['optional']), - ('start_time', int, ['optional']), - ('end_time', int, ['optional']), - ('rsvp_status', str, ['optional']), - ], - - 'getMembers': [ - ('eid', int, []), - ], - - 'create': [ - ('event_info', json, []), - ], - }, - - # update methods - 'update': { - 'decodeIDs': [ - ('ids', list, []), - ], - }, - - # groups methods - 'groups': { - 'get': [ - ('uid', int, ['optional']), - ('gids', list, ['optional']), - ], - - 'getMembers': [ - ('gid', int, []), - ], - }, - - # marketplace methods - 'marketplace': { - 'createListing': [ - ('listing_id', int, []), - ('show_on_profile', bool, []), - ('listing_attrs', str, []), - ], - - 'getCategories': [], - - 'getListings': [ - ('listing_ids', list, []), - ('uids', list, []), - ], - - 'getSubCategories': [ - ('category', str, []), - ], - - 'removeListing': [ - ('listing_id', int, []), - ('status', str, []), - ], - - 'search': [ - ('category', str, ['optional']), - ('subcategory', str, ['optional']), - ('query', str, ['optional']), - ], - }, - - # pages methods - 'pages': { - 'getInfo': [ - ('fields', list, [('default', ['page_id', 'name'])]), - ('page_ids', list, ['optional']), - ('uid', int, ['optional']), - ], - - 'isAdmin': [ - ('page_id', int, []), - ], - - 'isAppAdded': [ - ('page_id', int, []), - ], - - 'isFan': [ - ('page_id', int, []), - ('uid', int, []), - ], - }, - - # photos methods - 'photos': { - 'addTag': [ - ('pid', int, []), - ('tag_uid', int, [('default', 0)]), - ('tag_text', str, [('default', '')]), - ('x', float, [('default', 50)]), - ('y', float, [('default', 50)]), - ('tags', str, ['optional']), - ], - - 'createAlbum': [ - ('name', str, []), - ('location', str, ['optional']), - ('description', str, ['optional']), - ], - - 'get': [ - ('subj_id', int, ['optional']), - ('aid', int, ['optional']), - ('pids', list, ['optional']), - ], - - 'getAlbums': [ - ('uid', int, ['optional']), - ('aids', list, ['optional']), - ], - - 'getTags': [ - ('pids', list, []), - ], - }, - - # status methods - 'status': { - 'get': [ - ('uid', int, ['optional']), - ('limit', int, ['optional']), - ], - 'set': [ - ('status', str, ['optional']), - ('uid', int, ['optional']), - ], - }, - - # fbml methods - 'fbml': { - 'refreshImgSrc': [ - ('url', str, []), - ], - - 'refreshRefUrl': [ - ('url', str, []), - ], - - 'setRefHandle': [ - ('handle', str, []), - ('fbml', str, []), - ], - }, - - # SMS Methods - 'sms' : { - 'canSend' : [ - ('uid', int, []), - ], - - 'send' : [ - ('uid', int, []), - ('message', str, []), - ('session_id', int, []), - ('req_session', bool, []), - ], - }, - - 'data': { - 'getCookies': [ - ('uid', int, []), - ('string', str, ['optional']), - ], - - 'setCookie': [ - ('uid', int, []), - ('name', str, []), - ('value', str, []), - ('expires', int, ['optional']), - ('path', str, ['optional']), - ], - }, - - # connect methods - 'connect': { - 'registerUsers': [ - ('accounts', json, []), - ], - - 'unregisterUsers': [ - ('email_hashes', json, []), - ], - - 'getUnconnectedFriendsCount': [ - ], - }, - - #stream methods (beta) - 'stream' : { - 'addComment' : [ - ('post_id', int, []), - ('comment', str, []), - ('uid', int, ['optional']), - ], - - 'addLike': [ - ('uid', int, ['optional']), - ('post_id', int, ['optional']), - ], - - 'get' : [ - ('viewer_id', int, ['optional']), - ('source_ids', list, ['optional']), - ('start_time', int, ['optional']), - ('end_time', int, ['optional']), - ('limit', int, ['optional']), - ('filter_key', str, ['optional']), - ], - - 'getComments' : [ - ('post_id', int, []), - ], - - 'getFilters' : [ - ('uid', int, ['optional']), - ], - - 'publish' : [ - ('message', str, ['optional']), - ('attachment', json, ['optional']), - ('action_links', json, ['optional']), - ('target_id', str, ['optional']), - ('uid', str, ['optional']), - ], - - 'remove' : [ - ('post_id', int, []), - ('uid', int, ['optional']), - ], - - 'removeComment' : [ - ('comment_id', int, []), - ('uid', int, ['optional']), - ], - - 'removeLike' : [ - ('uid', int, ['optional']), - ('post_id', int, ['optional']), - ], - } -} - -class Proxy(object): - """Represents a "namespace" of Facebook API calls.""" - - def __init__(self, client, name): - self._client = client - self._name = name - - def __call__(self, method=None, args=None, add_session_args=True): - # for Django templates - if method is None: - return self - - if add_session_args: - self._client._add_session_args(args) - - return self._client('%s.%s' % (self._name, method), args) - - -# generate the Facebook proxies -def __generate_proxies(): - for namespace in METHODS: - methods = {} - - for method in METHODS[namespace]: - params = ['self'] - body = ['args = {}'] - - for param_name, param_type, param_options in METHODS[namespace][method]: - param = param_name - - for option in param_options: - if isinstance(option, tuple) and option[0] == 'default': - if param_type == list: - param = '%s=None' % param_name - body.append('if %s is None: %s = %s' % (param_name, param_name, repr(option[1]))) - else: - param = '%s=%s' % (param_name, repr(option[1])) - - if param_type == json: - # we only jsonify the argument if it's a list or a dict, for compatibility - body.append('if isinstance(%s, list) or isinstance(%s, dict): %s = simplejson.dumps(%s)' % ((param_name,) * 4)) - - if 'optional' in param_options: - param = '%s=None' % param_name - body.append('if %s is not None: args[\'%s\'] = %s' % (param_name, param_name, param_name)) - else: - body.append('args[\'%s\'] = %s' % (param_name, param_name)) - - params.append(param) - - # simple docstring to refer them to Facebook API docs - body.insert(0, '"""Facebook API call. See http://developers.facebook.com/documentation.php?v=1.0&method=%s.%s"""' % (namespace, method)) - - body.insert(0, 'def %s(%s):' % (method, ', '.join(params))) - - body.append('return self(\'%s\', args)' % method) - - exec('\n '.join(body)) - - methods[method] = eval(method) - - proxy = type('%sProxy' % namespace.title(), (Proxy, ), methods) - - globals()[proxy.__name__] = proxy - - -__generate_proxies() - - -class FacebookError(Exception): - """Exception class for errors received from Facebook.""" - - def __init__(self, code, msg, args=None): - self.code = code - self.msg = msg - self.args = args - - def __str__(self): - return 'Error %s: %s' % (self.code, self.msg) - - -class AuthProxy(AuthProxy): - """Special proxy for facebook.auth.""" - - def getSession(self): - """Facebook API call. See http://developers.facebook.com/documentation.php?v=1.0&method=auth.getSession""" - args = {} - try: - args['auth_token'] = self._client.auth_token - except AttributeError: - raise RuntimeError('Client does not have auth_token set.') - result = self._client('%s.getSession' % self._name, args) - self._client.session_key = result['session_key'] - self._client.uid = result['uid'] - self._client.secret = result.get('secret') - self._client.session_key_expires = result['expires'] - return result - - def createToken(self): - """Facebook API call. See http://developers.facebook.com/documentation.php?v=1.0&method=auth.createToken""" - token = self._client('%s.createToken' % self._name) - self._client.auth_token = token - return token - - -class FriendsProxy(FriendsProxy): - """Special proxy for facebook.friends.""" - - def get(self, **kwargs): - """Facebook API call. See http://developers.facebook.com/documentation.php?v=1.0&method=friends.get""" - if not kwargs.get('flid') and self._client._friends: - return self._client._friends - return super(FriendsProxy, self).get(**kwargs) - - -class PhotosProxy(PhotosProxy): - """Special proxy for facebook.photos.""" - - def upload(self, image, aid=None, caption=None, size=(604, 1024), filename=None, callback=None): - """Facebook API call. See http://developers.facebook.com/documentation.php?v=1.0&method=photos.upload - - size -- an optional size (width, height) to resize the image to before uploading. Resizes by default - to Facebook's maximum display width of 604. - """ - args = {} - - if aid is not None: - args['aid'] = aid - - if caption is not None: - args['caption'] = caption - - args = self._client._build_post_args('facebook.photos.upload', self._client._add_session_args(args)) - - try: - import io as StringIO - except ImportError: - import io - - # check for a filename specified...if the user is passing binary data in - # image then a filename will be specified - if filename is None: - try: - import Image - except ImportError: - data = io.StringIO(open(image, 'rb').read()) - else: - img = Image.open(image) - if size: - img.thumbnail(size, Image.ANTIALIAS) - data = io.StringIO() - img.save(data, img.format) - else: - # there was a filename specified, which indicates that image was not - # the path to an image file but rather the binary data of a file - data = io.StringIO(image) - image = filename - - content_type, body = self.__encode_multipart_formdata(list(args.items()), [(image, data)]) - urlinfo = urllib.parse.urlsplit(self._client.facebook_url) - try: - content_length = len(body) - chunk_size = 4096 - - h = http.client.HTTPConnection(urlinfo[1]) - h.putrequest('POST', urlinfo[2]) - h.putheader('Content-Type', content_type) - h.putheader('Content-Length', str(content_length)) - h.putheader('MIME-Version', '1.0') - h.putheader('User-Agent', 'PyFacebook Client Library') - h.endheaders() - - if callback: - count = 0 - while len(body) > 0: - if len(body) < chunk_size: - data = body - body = '' - else: - data = body[0:chunk_size] - body = body[chunk_size:] - - h.send(data) - count += 1 - callback(count, chunk_size, content_length) - else: - h.send(body) - - response = h.getresponse() - - if response.status != 200: - raise Exception('Error uploading photo: Facebook returned HTTP %s (%s)' % (response.status, response.reason)) - response = response.read() - except: - # sending the photo failed, perhaps we are using GAE - try: - from google.appengine.api import urlfetch - - try: - response = urlread(url=self._client.facebook_url,data=body,headers={'POST':urlinfo[2],'Content-Type':content_type,'MIME-Version':'1.0'}) - except urllib.error.URLError: - raise Exception('Error uploading photo: Facebook returned %s' % (response)) - except ImportError: - # could not import from google.appengine.api, so we are not running in GAE - raise Exception('Error uploading photo.') - - return self._client._parse_response(response, 'facebook.photos.upload') - - - def __encode_multipart_formdata(self, fields, files): - """Encodes a multipart/form-data message to upload an image.""" - boundary = '-------tHISiStheMulTIFoRMbOUNDaRY' - crlf = '\r\n' - l = [] - - for (key, value) in fields: - l.append('--' + boundary) - l.append('Content-Disposition: form-data; name="%s"' % str(key)) - l.append('') - l.append(str(value)) - for (filename, value) in files: - l.append('--' + boundary) - l.append('Content-Disposition: form-data; filename="%s"' % (str(filename), )) - l.append('Content-Type: %s' % self.__get_content_type(filename)) - l.append('') - l.append(value.getvalue()) - l.append('--' + boundary + '--') - l.append('') - body = crlf.join(l) - content_type = 'multipart/form-data; boundary=%s' % boundary - return content_type, body - - - def __get_content_type(self, filename): - """Returns a guess at the MIME type of the file from the filename.""" - return str(mimetypes.guess_type(filename)[0]) or 'application/octet-stream' - - -class Facebook(object): - """ - Provides access to the Facebook API. - - Instance Variables: - - added - True if the user has added this application. - - api_key - Your API key, as set in the constructor. - - app_name - Your application's name, i.e. the APP_NAME in http://apps.facebook.com/APP_NAME/ if - this is for an internal web application. Optional, but useful for automatic redirects - to canvas pages. - - auth_token - The auth token that Facebook gives you, either with facebook.auth.createToken, - or through a GET parameter. - - callback_path - The path of the callback set in the Facebook app settings. If your callback is set - to http://www.example.com/facebook/callback/, this should be '/facebook/callback/'. - Optional, but useful for automatic redirects back to the same page after login. - - desktop - True if this is a desktop app, False otherwise. Used for determining how to - authenticate. - - ext_perms - Any extended permissions that the user has granted to your application. - This parameter is set only if the user has granted any. - - facebook_url - The url to use for Facebook requests. - - facebook_secure_url - The url to use for secure Facebook requests. - - in_canvas - True if the current request is for a canvas page. - - in_iframe - True if the current request is for an HTML page to embed in Facebook inside an iframe. - - is_session_from_cookie - True if the current request session comes from a session cookie. - - in_profile_tab - True if the current request is for a user's tab for your application. - - internal - True if this Facebook object is for an internal application (one that can be added on Facebook) - - locale - The user's locale. Default: 'en_US' - - page_id - Set to the page_id of the current page (if any) - - profile_update_time - The time when this user's profile was last updated. This is a UNIX timestamp. Default: None if unknown. - - secret - Secret that is used after getSession for desktop apps. - - secret_key - Your application's secret key, as set in the constructor. - - session_key - The current session key. Set automatically by auth.getSession, but can be set - manually for doing infinite sessions. - - session_key_expires - The UNIX time of when this session key expires, or 0 if it never expires. - - uid - After a session is created, you can get the user's UID with this variable. Set - automatically by auth.getSession. - - ---------------------------------------------------------------------- - - """ - - def __init__(self, api_key, secret_key, auth_token=None, app_name=None, callback_path=None, internal=None, proxy=None, facebook_url=None, facebook_secure_url=None): - """ - Initializes a new Facebook object which provides wrappers for the Facebook API. - - If this is a desktop application, the next couple of steps you might want to take are: - - facebook.auth.createToken() # create an auth token - facebook.login() # show a browser window - wait_login() # somehow wait for the user to log in - facebook.auth.getSession() # get a session key - - For web apps, if you are passed an auth_token from Facebook, pass that in as a named parameter. - Then call: - - facebook.auth.getSession() - - """ - self.api_key = api_key - self.secret_key = secret_key - self.session_key = None - self.session_key_expires = None - self.auth_token = auth_token - self.secret = None - self.uid = None - self.page_id = None - self.in_canvas = False - self.in_iframe = False - self.is_session_from_cookie = False - self.in_profile_tab = False - self.added = False - self.app_name = app_name - self.callback_path = callback_path - self.internal = internal - self._friends = None - self.locale = 'en_US' - self.profile_update_time = None - self.ext_perms = None - self.proxy = proxy - if facebook_url is None: - self.facebook_url = FACEBOOK_URL - else: - self.facebook_url = facebook_url - if facebook_secure_url is None: - self.facebook_secure_url = FACEBOOK_SECURE_URL - else: - self.facebook_secure_url = facebook_secure_url - - for namespace in METHODS: - self.__dict__[namespace] = eval('%sProxy(self, \'%s\')' % (namespace.title(), 'facebook.%s' % namespace)) - - - def _hash_args(self, args, secret=None): - """Hashes arguments by joining key=value pairs, appending a secret, and then taking the MD5 hex digest.""" - # @author: houyr - # fix for UnicodeEncodeError - hasher = hashlib.md5(''.join(['%s=%s' % (isinstance(x, str) and x.encode("utf-8") or x, isinstance(args[x], str) and args[x].encode("utf-8") or args[x]) for x in sorted(args.keys())])) - if secret: - hasher.update(secret) - elif self.secret: - hasher.update(self.secret) - else: - hasher.update(self.secret_key) - return hasher.hexdigest() - - - def _parse_response_item(self, node): - """Parses an XML response node from Facebook.""" - if node.nodeType == node.DOCUMENT_NODE and \ - node.childNodes[0].hasAttributes() and \ - node.childNodes[0].hasAttribute('list') and \ - node.childNodes[0].getAttribute('list') == "true": - return {node.childNodes[0].nodeName: self._parse_response_list(node.childNodes[0])} - elif node.nodeType == node.ELEMENT_NODE and \ - node.hasAttributes() and \ - node.hasAttribute('list') and \ - node.getAttribute('list')=="true": - return self._parse_response_list(node) - elif len([x for x in node.childNodes if x.nodeType == x.ELEMENT_NODE]) > 0: - return self._parse_response_dict(node) - else: - return ''.join(node.data for node in node.childNodes if node.nodeType == node.TEXT_NODE) - - - def _parse_response_dict(self, node): - """Parses an XML dictionary response node from Facebook.""" - result = {} - for item in [x for x in node.childNodes if x.nodeType == x.ELEMENT_NODE]: - result[item.nodeName] = self._parse_response_item(item) - if node.nodeType == node.ELEMENT_NODE and node.hasAttributes(): - if node.hasAttribute('id'): - result['id'] = node.getAttribute('id') - return result - - - def _parse_response_list(self, node): - """Parses an XML list response node from Facebook.""" - result = [] - for item in [x for x in node.childNodes if x.nodeType == x.ELEMENT_NODE]: - result.append(self._parse_response_item(item)) - return result - - - def _check_error(self, response): - """Checks if the given Facebook response is an error, and then raises the appropriate exception.""" - if isinstance(response, dict) and 'error_code' in response: - raise FacebookError(response['error_code'], response['error_msg'], response['request_args']) - - - def _build_post_args(self, method, args=None): - """Adds to args parameters that are necessary for every call to the API.""" - if args is None: - args = {} - - for arg in list(args.items()): - if isinstance(arg[1], list): - args[arg[0]] = ','.join(str(a) for a in arg[1]) - elif isinstance(arg[1], str): - args[arg[0]] = arg[1].encode("UTF-8") - elif isinstance(arg[1], bool): - args[arg[0]] = str(arg[1]).lower() - - args['method'] = method - args['api_key'] = self.api_key - args['v'] = '1.0' - args['format'] = RESPONSE_FORMAT - args['sig'] = self._hash_args(args) - - return args - - - def _add_session_args(self, args=None): - """Adds 'session_key' and 'call_id' to args, which are used for API calls that need sessions.""" - if args is None: - args = {} - - if not self.session_key: - return args - #some calls don't need a session anymore. this might be better done in the markup - #raise RuntimeError('Session key not set. Make sure auth.getSession has been called.') - - args['session_key'] = self.session_key - args['call_id'] = str(int(time.time() * 1000)) - - return args - - - def _parse_response(self, response, method, format=None): - """Parses the response according to the given (optional) format, which should be either 'JSON' or 'XML'.""" - if not format: - format = RESPONSE_FORMAT - - if format == 'JSON': - result = simplejson.loads(response) - - self._check_error(result) - elif format == 'XML': - dom = minidom.parseString(response) - result = self._parse_response_item(dom) - dom.unlink() - - if 'error_response' in result: - self._check_error(result['error_response']) - - result = result[method[9:].replace('.', '_') + '_response'] - else: - raise RuntimeError('Invalid format specified.') - - return result - - - def hash_email(self, email): - """ - Hash an email address in a format suitable for Facebook Connect. - - """ - email = email.lower().strip() - return "%s_%s" % ( - struct.unpack("I", struct.pack("i", binascii.crc32(email)))[0], - hashlib.md5(email).hexdigest(), - ) - - - def unicode_urlencode(self, params): - """ - @author: houyr - A unicode aware version of urllib.urlencode. - """ - if isinstance(params, dict): - params = list(params.items()) - return urllib.parse.urlencode([(k, isinstance(v, str) and v.encode('utf-8') or v) - for k, v in params]) - - - def __call__(self, method=None, args=None, secure=False): - """Make a call to Facebook's REST server.""" - # for Django templates, if this object is called without any arguments - # return the object itself - if method is None: - return self - - # __init__ hard-codes into en_US - if args is not None and 'locale' not in args: - args['locale'] = self.locale - - # @author: houyr - # fix for bug of UnicodeEncodeError - post_data = self.unicode_urlencode(self._build_post_args(method, args)) - - if self.proxy: - proxy_handler = urllib.request.ProxyHandler(self.proxy) - opener = urllib.request.build_opener(proxy_handler) - if secure: - response = opener.open(self.facebook_secure_url, post_data).read() - else: - response = opener.open(self.facebook_url, post_data).read() - else: - if secure: - response = urlread(self.facebook_secure_url, post_data) - else: - response = urlread(self.facebook_url, post_data) - - return self._parse_response(response, method) - - - # URL helpers - def get_url(self, page, **args): - """ - Returns one of the Facebook URLs (www.facebook.com/SOMEPAGE.php). - Named arguments are passed as GET query string parameters. - - """ - return 'http://www.facebook.com/%s.php?%s' % (page, urllib.parse.urlencode(args)) - - - def get_app_url(self, path=''): - """ - Returns the URL for this app's canvas page, according to app_name. - - """ - return 'http://apps.facebook.com/%s/%s' % (self.app_name, path) - - - def get_add_url(self, next=None): - """ - Returns the URL that the user should be redirected to in order to add the application. - - """ - args = {'api_key': self.api_key, 'v': '1.0'} - - if next is not None: - args['next'] = next - - return self.get_url('install', **args) - - - def get_authorize_url(self, next=None, next_cancel=None): - """ - Returns the URL that the user should be redirected to in order to - authorize certain actions for application. - - """ - args = {'api_key': self.api_key, 'v': '1.0'} - - if next is not None: - args['next'] = next - - if next_cancel is not None: - args['next_cancel'] = next_cancel - - return self.get_url('authorize', **args) - - - def get_login_url(self, next=None, popup=False, canvas=True): - """ - Returns the URL that the user should be redirected to in order to login. - - next -- the URL that Facebook should redirect to after login - - """ - args = {'api_key': self.api_key, 'v': '1.0'} - - if next is not None: - args['next'] = next - - if canvas is True: - args['canvas'] = 1 - - if popup is True: - args['popup'] = 1 - - if self.auth_token is not None: - args['auth_token'] = self.auth_token - - return self.get_url('login', **args) - - - def login(self, popup=False): - """Open a web browser telling the user to login to Facebook.""" - import webbrowser - webbrowser.open(self.get_login_url(popup=popup)) - - - def get_ext_perm_url(self, ext_perm, next=None, popup=False): - """ - Returns the URL that the user should be redirected to in order to grant an extended permission. - - ext_perm -- the name of the extended permission to request - next -- the URL that Facebook should redirect to after login - - """ - args = {'ext_perm': ext_perm, 'api_key': self.api_key, 'v': '1.0'} - - if next is not None: - args['next'] = next - - if popup is True: - args['popup'] = 1 - - return self.get_url('authorize', **args) - - - def request_extended_permission(self, ext_perm, popup=False): - """Open a web browser telling the user to grant an extended permission.""" - import webbrowser - webbrowser.open(self.get_ext_perm_url(ext_perm, popup=popup)) - - - def check_session(self, request): - """ - Checks the given Django HttpRequest for Facebook parameters such as - POST variables or an auth token. If the session is valid, returns True - and this object can now be used to access the Facebook API. Otherwise, - it returns False, and the application should take the appropriate action - (either log the user in or have him add the application). - - """ - self.in_canvas = (request.POST.get('fb_sig_in_canvas') == '1') - - if self.session_key and (self.uid or self.page_id): - return True - - - if request.method == 'POST': - params = self.validate_signature(request.POST) - else: - if 'installed' in request.GET: - self.added = True - - if 'fb_page_id' in request.GET: - self.page_id = request.GET['fb_page_id'] - - if 'auth_token' in request.GET: - self.auth_token = request.GET['auth_token'] - - try: - self.auth.getSession() - except FacebookError as e: - self.auth_token = None - return False - - return True - - params = self.validate_signature(request.GET) - - if not params: - # first check if we are in django - to check cookies - if hasattr(request, 'COOKIES'): - params = self.validate_cookie_signature(request.COOKIES) - self.is_session_from_cookie = True - else: - # if not, then we might be on GoogleAppEngine, check their request object cookies - if hasattr(request,'cookies'): - params = self.validate_cookie_signature(request.cookies) - self.is_session_from_cookie = True - - if not params: - return False - - if params.get('in_canvas') == '1': - self.in_canvas = True - - if params.get('in_iframe') == '1': - self.in_iframe = True - - if params.get('in_profile_tab') == '1': - self.in_profile_tab = True - - if params.get('added') == '1': - self.added = True - - if params.get('expires'): - self.session_key_expires = int(params['expires']) - - if 'locale' in params: - self.locale = params['locale'] - - if 'profile_update_time' in params: - try: - self.profile_update_time = int(params['profile_update_time']) - except ValueError: - pass - - if 'ext_perms' in params: - self.ext_perms = params['ext_perms'] - - if 'friends' in params: - if params['friends']: - self._friends = params['friends'].split(',') - else: - self._friends = [] - - if 'session_key' in params: - self.session_key = params['session_key'] - if 'user' in params: - self.uid = params['user'] - elif 'page_id' in params: - self.page_id = params['page_id'] - else: - return False - elif 'profile_session_key' in params: - self.session_key = params['profile_session_key'] - if 'profile_user' in params: - self.uid = params['profile_user'] - else: - return False - elif 'canvas_user' in params: - self.uid = params['canvas_user'] - elif 'uninstall' in params: - self.uid = params['user'] - else: - return False - - return True - - - def validate_signature(self, post, prefix='fb_sig', timeout=None): - """ - Validate parameters passed to an internal Facebook app from Facebook. - - """ - args = post.copy() - - if prefix not in args: - return None - - del args[prefix] - - if timeout and '%s_time' % prefix in post and time.time() - float(post['%s_time' % prefix]) > timeout: - return None - - args = dict([(key[len(prefix + '_'):], value) for key, value in list(args.items()) if key.startswith(prefix)]) - - hash = self._hash_args(args) - - if hash == post[prefix]: - return args - else: - return None - - def validate_cookie_signature(self, cookies): - """ - Validate parameters passed by cookies, namely facebookconnect or js api. - """ - - api_key = self.api_key - if api_key not in cookies: - return None - - prefix = api_key + "_" - - params = {} - vals = '' - for k in sorted(cookies): - if k.startswith(prefix): - key = k.replace(prefix,"") - value = cookies[k] - params[key] = value - vals += '%s=%s' % (key, value) - - hasher = hashlib.md5(vals) - - hasher.update(self.secret_key) - digest = hasher.hexdigest() - if digest == cookies[api_key]: - params['is_session_from_cookie'] = True - return params - else: - return False - - - - -if __name__ == '__main__': - # sample desktop application - - api_key = '' - secret_key = '' - - facebook = Facebook(api_key, secret_key) - - facebook.auth.createToken() - - # Show login window - # Set popup=True if you want login without navigational elements - facebook.login() - - # Login to the window, then press enter - print('After logging in, press enter...') - input() - - facebook.auth.getSession() - print('Session Key: ', facebook.session_key) - print('Your UID: ', facebook.uid) - - info = facebook.users.getInfo([facebook.uid], ['name', 'birthday', 'affiliations', 'sex'])[0] - - print('Your Name: ', info['name']) - print('Your Birthday: ', info['birthday']) - print('Your Gender: ', info['sex']) - - friends = facebook.friends.get() - friends = facebook.users.getInfo(friends[0:5], ['name', 'birthday', 'relationship_status']) - - for friend in friends: - print(friend['name'], 'has a birthday on', friend['birthday'], 'and is', friend['relationship_status']) - - arefriends = facebook.friends.areFriends([friends[0]['uid']], [friends[1]['uid']]) - - photos = facebook.photos.getAlbums(facebook.uid) - diff --git a/helios_auth/auth_systems/facebookclient/djangofb/__init__.py b/helios_auth/auth_systems/facebookclient/djangofb/__init__.py deleted file mode 100644 index 48f720be150401e5a063e7508aada478951fd514..0000000000000000000000000000000000000000 --- a/helios_auth/auth_systems/facebookclient/djangofb/__init__.py +++ /dev/null @@ -1,248 +0,0 @@ -import re -import datetime -import facebook - -from django.http import HttpResponse, HttpResponseRedirect -from django.core.exceptions import ImproperlyConfigured -from django.conf import settings -from datetime import datetime - -try: - from threading import local -except ImportError: - from django.utils._threading_local import local - -__all__ = ['Facebook', 'FacebookMiddleware', 'get_facebook_client', 'require_login', 'require_add'] - -_thread_locals = local() - -class Facebook(facebook.Facebook): - def redirect(self, url): - """ - Helper for Django which redirects to another page. If inside a - canvas page, writes a <fb:redirect> instead to achieve the same effect. - - """ - if self.in_canvas: - return HttpResponse('<fb:redirect url="%s" />' % (url, )) - elif re.search("^https?:\/\/([^\/]*\.)?facebook\.com(:\d+)?", url.lower()): - return HttpResponse('<script type="text/javascript">\ntop.location.href = "%s";\n</script>' % url) - else: - return HttpResponseRedirect(url) - - -def get_facebook_client(): - """ - Get the current Facebook object for the calling thread. - - """ - try: - return _thread_locals.facebook - except AttributeError: - raise ImproperlyConfigured('Make sure you have the Facebook middleware installed.') - - -def require_login(next=None, internal=None): - """ - Decorator for Django views that requires the user to be logged in. - The FacebookMiddleware must be installed. - - Standard usage: - @require_login() - def some_view(request): - ... - - Redirecting after login: - To use the 'next' parameter to redirect to a specific page after login, a callable should - return a path relative to the Post-add URL. 'next' can also be an integer specifying how many - parts of request.path to strip to find the relative URL of the canvas page. If 'next' is None, - settings.callback_path and settings.app_name are checked to redirect to the same page after logging - in. (This is the default behavior.) - @require_login(next=some_callable) - def some_view(request): - ... - """ - def decorator(view): - def newview(request, *args, **kwargs): - next = newview.__next__ - internal = newview.internal - - try: - fb = request.facebook - except: - raise ImproperlyConfigured('Make sure you have the Facebook middleware installed.') - - if internal is None: - internal = request.facebook.internal - - if callable(next): - next = next(request.path) - elif isinstance(next, int): - next = '/'.join(request.path.split('/')[next + 1:]) - elif next is None and fb.callback_path and request.path.startswith(fb.callback_path): - next = request.path[len(fb.callback_path):] - elif not isinstance(next, str): - next = '' - - if not fb.check_session(request): - #If user has never logged in before, the get_login_url will redirect to the TOS page - return fb.redirect(fb.get_login_url(next=next)) - - if internal and request.method == 'GET' and fb.app_name: - return fb.redirect('%s%s' % (fb.get_app_url(), next)) - - return view(request, *args, **kwargs) - newview.next = next - newview.internal = internal - return newview - return decorator - - -def require_add(next=None, internal=None, on_install=None): - """ - Decorator for Django views that requires application installation. - The FacebookMiddleware must be installed. - - Standard usage: - @require_add() - def some_view(request): - ... - - Redirecting after installation: - To use the 'next' parameter to redirect to a specific page after login, a callable should - return a path relative to the Post-add URL. 'next' can also be an integer specifying how many - parts of request.path to strip to find the relative URL of the canvas page. If 'next' is None, - settings.callback_path and settings.app_name are checked to redirect to the same page after logging - in. (This is the default behavior.) - @require_add(next=some_callable) - def some_view(request): - ... - - Post-install processing: - Set the on_install parameter to a callable in order to handle special post-install processing. - The callable should take a request object as the parameter. - @require_add(on_install=some_callable) - def some_view(request): - ... - """ - def decorator(view): - def newview(request, *args, **kwargs): - next = newview.__next__ - internal = newview.internal - - try: - fb = request.facebook - except: - raise ImproperlyConfigured('Make sure you have the Facebook middleware installed.') - - if internal is None: - internal = request.facebook.internal - - if callable(next): - next = next(request.path) - elif isinstance(next, int): - next = '/'.join(request.path.split('/')[next + 1:]) - elif next is None and fb.callback_path and request.path.startswith(fb.callback_path): - next = request.path[len(fb.callback_path):] - else: - next = '' - - if not fb.check_session(request): - if fb.added: - if request.method == 'GET' and fb.app_name: - return fb.redirect('%s%s' % (fb.get_app_url(), next)) - return fb.redirect(fb.get_login_url(next=next)) - else: - return fb.redirect(fb.get_add_url(next=next)) - - if not fb.added: - return fb.redirect(fb.get_add_url(next=next)) - - if 'installed' in request.GET and callable(on_install): - on_install(request) - - if internal and request.method == 'GET' and fb.app_name: - return fb.redirect('%s%s' % (fb.get_app_url(), next)) - - return view(request, *args, **kwargs) - newview.next = next - newview.internal = internal - return newview - return decorator - -# try to preserve the argspecs -try: - import decorator -except ImportError: - pass -else: - def updater(f): - def updated(*args, **kwargs): - original = f(*args, **kwargs) - def newdecorator(view): - return decorator.new_wrapper(original(view), view) - return decorator.new_wrapper(newdecorator, original) - return decorator.new_wrapper(updated, f) - require_login = updater(require_login) - require_add = updater(require_add) - -class FacebookMiddleware(object): - """ - Middleware that attaches a Facebook object to every incoming request. - The Facebook object created can also be accessed from models for the - current thread by using get_facebook_client(). - - """ - - def __init__(self, api_key=None, secret_key=None, app_name=None, callback_path=None, internal=None): - self.api_key = api_key or settings.FACEBOOK_API_KEY - self.secret_key = secret_key or settings.FACEBOOK_SECRET_KEY - self.app_name = app_name or getattr(settings, 'FACEBOOK_APP_NAME', None) - self.callback_path = callback_path or getattr(settings, 'FACEBOOK_CALLBACK_PATH', None) - self.internal = internal or getattr(settings, 'FACEBOOK_INTERNAL', True) - self.proxy = None - if getattr(settings, 'USE_HTTP_PROXY', False): - self.proxy = settings.HTTP_PROXY - - def process_request(self, request): - _thread_locals.facebook = request.facebook = Facebook(self.api_key, self.secret_key, app_name=self.app_name, callback_path=self.callback_path, internal=self.internal, proxy=self.proxy) - if not self.internal: - if 'fb_sig_session_key' in request.GET and 'fb_sig_user' in request.GET: - request.facebook.session_key = request.session['facebook_session_key'] = request.GET['fb_sig_session_key'] - request.facebook.uid = request.session['fb_sig_user'] = request.GET['fb_sig_user'] - elif request.session.get('facebook_session_key', None) and request.session.get('facebook_user_id', None): - request.facebook.session_key = request.session['facebook_session_key'] - request.facebook.uid = request.session['facebook_user_id'] - - def process_response(self, request, response): - if not self.internal and request.facebook.session_key and request.facebook.uid: - request.session['facebook_session_key'] = request.facebook.session_key - request.session['facebook_user_id'] = request.facebook.uid - - if request.facebook.session_key_expires: - expiry = datetime.datetime.fromtimestamp(request.facebook.session_key_expires) - request.session.set_expiry(expiry) - - try: - fb = request.facebook - except: - return response - - if not fb.is_session_from_cookie: - # Make sure the browser accepts our session cookies inside an Iframe - response['P3P'] = 'CP="NOI DSP COR NID ADMa OPTa OUR NOR"' - fb_cookies = { - 'expires': fb.session_key_expires, - 'session_key': fb.session_key, - 'user': fb.uid, - } - - expire_time = None - if fb.session_key_expires: - expire_time = datetime.utcfromtimestamp(fb.session_key_expires) - - for k in fb_cookies: - response.set_cookie(self.api_key + '_' + k, fb_cookies[k], expires=expire_time) - response.set_cookie(self.api_key , fb._hash_args(fb_cookies), expires=expire_time) - - return response diff --git a/helios_auth/auth_systems/facebookclient/djangofb/context_processors.py b/helios_auth/auth_systems/facebookclient/djangofb/context_processors.py deleted file mode 100644 index 82805a537f3033eb9f7b7597cc2ca7b17fddb82e..0000000000000000000000000000000000000000 --- a/helios_auth/auth_systems/facebookclient/djangofb/context_processors.py +++ /dev/null @@ -1,6 +0,0 @@ -def messages(request): - """Returns messages similar to ``django.core.context_processors.auth``.""" - if hasattr(request, 'facebook') and request.facebook.uid is not None: - from .models import Message - messages = Message.objects.get_and_delete_all(uid=request.facebook.uid) - return {'messages': messages} \ No newline at end of file diff --git a/helios_auth/auth_systems/facebookclient/djangofb/default_app/__init__.py b/helios_auth/auth_systems/facebookclient/djangofb/default_app/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/helios_auth/auth_systems/facebookclient/djangofb/default_app/models.py b/helios_auth/auth_systems/facebookclient/djangofb/default_app/models.py deleted file mode 100644 index 666ccd3f39403df207fac99cee88c6ca00789b8f..0000000000000000000000000000000000000000 --- a/helios_auth/auth_systems/facebookclient/djangofb/default_app/models.py +++ /dev/null @@ -1,31 +0,0 @@ -from django.db import models - -# get_facebook_client lets us get the current Facebook object -# from outside of a view, which lets us have cleaner code -from facebook.djangofb import get_facebook_client - -class UserManager(models.Manager): - """Custom manager for a Facebook User.""" - - def get_current(self): - """Gets a User object for the logged-in Facebook user.""" - facebook = get_facebook_client() - user, created = self.get_or_create(id=int(facebook.uid)) - if created: - # we could do some custom actions for new users here... - pass - return user - -class User(models.Model): - """A simple User model for Facebook users.""" - - # We use the user's UID as the primary key in our database. - id = models.IntegerField(primary_key=True) - - # TODO: The data that you want to store for each user would go here. - # For this sample, we let users let people know their favorite progamming - # language, in the spirit of Extended Info. - language = models.CharField(maxlength=64, default='Python') - - # Add the custom manager - objects = UserManager() diff --git a/helios_auth/auth_systems/facebookclient/djangofb/default_app/templates/canvas.fbml b/helios_auth/auth_systems/facebookclient/djangofb/default_app/templates/canvas.fbml deleted file mode 100644 index 6734dd17caa138540fb10d0fcb750d70c8600d33..0000000000000000000000000000000000000000 --- a/helios_auth/auth_systems/facebookclient/djangofb/default_app/templates/canvas.fbml +++ /dev/null @@ -1,22 +0,0 @@ -<fb:header> - {% comment %} - We can use {{ fbuser }} to get at the current user. - {{ fbuser.id }} will be the user's UID, and {{ fbuser.language }} - is his/her favorite language (Python :-). - {% endcomment %} - Welcome, <fb:name uid="{{ fbuser.id }}" firstnameonly="true" useyou="false" />! -</fb:header> - -<div class="clearfix" style="float: left; border: 1px #d8dfea solid; padding: 10px 10px 10px 10px; margin-left: 30px; margin-bottom: 30px; width: 500px;"> - Your favorite language is {{ fbuser.language|escape }}. - <br /><br /> - - <div class="grayheader clearfix"> - <br /><br /> - - <form action="." method="POST"> - <input type="text" name="language" value="{{ fbuser.language|escape }}" /> - <input type="submit" value="Change" /> - </form> - </div> -</div> diff --git a/helios_auth/auth_systems/facebookclient/djangofb/default_app/urls.py b/helios_auth/auth_systems/facebookclient/djangofb/default_app/urls.py deleted file mode 100644 index d6084742bb17200bb3a452905e94f734f4c5b6be..0000000000000000000000000000000000000000 --- a/helios_auth/auth_systems/facebookclient/djangofb/default_app/urls.py +++ /dev/null @@ -1,7 +0,0 @@ -from django.conf.urls import url - -from .views import canvas - -urlpatterns = [ - url(r'^$', canvas), -] diff --git a/helios_auth/auth_systems/facebookclient/djangofb/default_app/views.py b/helios_auth/auth_systems/facebookclient/djangofb/default_app/views.py deleted file mode 100644 index 1cd91f831ca38cbd27f6823e9f979bd83d5df729..0000000000000000000000000000000000000000 --- a/helios_auth/auth_systems/facebookclient/djangofb/default_app/views.py +++ /dev/null @@ -1,38 +0,0 @@ -from django.http import HttpResponse -# from django.views.generic.simple import direct_to_template -#uncomment the following two lines and the one below -#if you dont want to use a decorator instead of the middleware -#from django.utils.decorators import decorator_from_middleware -#from facebook.djangofb import FacebookMiddleware - -# Import the Django helpers -import facebook.djangofb as facebook - -# The User model defined in models.py -from .models import User - -# We'll require login for our canvas page. This -# isn't necessarily a good idea, as we might want -# to let users see the page without granting our app -# access to their info. See the wiki for details on how -# to do this. -#@decorator_from_middleware(FacebookMiddleware) -@facebook.require_login() -def canvas(request): - # Get the User object for the currently logged in user - user = User.objects.get_current() - - # Check if we were POSTed the user's new language of choice - if 'language' in request.POST: - user.language = request.POST['language'][:64] - user.save() - - # User is guaranteed to be logged in, so pass canvas.fbml - # an extra 'fbuser' parameter that is the User object for - # the currently logged in user. - #return direct_to_template(request, 'canvas.fbml', extra_context={'fbuser': user}) - return None - -@facebook.require_login() -def ajax(request): - return HttpResponse('hello world') diff --git a/helios_auth/auth_systems/facebookclient/djangofb/models.py b/helios_auth/auth_systems/facebookclient/djangofb/models.py deleted file mode 100644 index 07604f40d2525e1837c099442af2de9f8479e1ae..0000000000000000000000000000000000000000 --- a/helios_auth/auth_systems/facebookclient/djangofb/models.py +++ /dev/null @@ -1,36 +0,0 @@ -from django.db import models -from django.utils.html import escape -from django.utils.safestring import mark_safe - -FB_MESSAGE_STATUS = ( - (0, 'Explanation'), - (1, 'Error'), - (2, 'Success'), -) - -class MessageManager(models.Manager): - def get_and_delete_all(self, uid): - messages = [] - for m in self.filter(uid=uid): - messages.append(m) - m.delete() - return messages - -class Message(models.Model): - """Represents a message for a Facebook user.""" - uid = models.CharField(max_length=25) - status = models.IntegerField(choices=FB_MESSAGE_STATUS) - message = models.CharField(max_length=300) - objects = MessageManager() - - def __unicode__(self): - return self.message - - def _fb_tag(self): - return self.get_status_display().lower() - - def as_fbml(self): - return mark_safe('<fb:%s message="%s" />' % ( - self._fb_tag(), - escape(self.message), - )) diff --git a/helios_auth/auth_systems/facebookclient/webappfb.py b/helios_auth/auth_systems/facebookclient/webappfb.py deleted file mode 100644 index 5fdf77af5c05ce29ccd56b6326ca4b8f64a08294..0000000000000000000000000000000000000000 --- a/helios_auth/auth_systems/facebookclient/webappfb.py +++ /dev/null @@ -1,170 +0,0 @@ -# -# webappfb - Facebook tools for Google's AppEngine "webapp" Framework -# -# Copyright (c) 2009, Max Battcher -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# * Neither the name of the author nor the names of its contributors may -# be used to endorse or promote products derived from this software -# without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND ANY -# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -# DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY -# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from google.appengine.api import memcache -from google.appengine.ext.webapp import RequestHandler -from facebook import Facebook -import yaml - -""" -Facebook tools for Google AppEngine's object-oriented "webapp" framework. -""" - -# This global configuration dictionary is for configuration variables -# for Facebook requests such as the application's API key and secret -# key. Defaults to loading a 'facebook.yaml' YAML file. This should be -# useful and familiar for most AppEngine development. -FACEBOOK_CONFIG = yaml.load(file('facebook.yaml', 'r')) - -class FacebookRequestHandler(RequestHandler): - """ - Base class for request handlers for Facebook apps, providing useful - Facebook-related tools: a local - """ - - def _fbconfig_value(self, name, default=None): - """ - Checks the global config dictionary and then for a class/instance - variable, using a provided default if no value is found. - """ - if name in FACEBOOK_CONFIG: - default = FACEBOOK_CONFIG[name] - - return getattr(self, name, default) - - def initialize(self, request, response): - """ - Initialize's this request's Facebook client. - """ - super(FacebookRequestHandler, self).initialize(request, response) - - app_name = self._fbconfig_value('app_name', '') - api_key = self._fbconfig_value('api_key', None) - secret_key = self._fbconfig_value('secret_key', None) - - self.facebook = Facebook(api_key, secret_key, - app_name=app_name) - - require_app = self._fbconfig_value('require_app', False) - require_login = self._fbconfig_value('require_login', False) - need_session = self._fbconfig_value('need_session', False) - check_session = self._fbconfig_value('check_session', True) - - self._messages = None - self.redirecting = False - - if require_app or require_login: - if not self.facebook.check_session(request): - self.redirect(self.facebook.get_login_url(next=request.path)) - self.redirecting = True - return - elif check_session: - self.facebook.check_session(request) # ignore response - - # NOTE: require_app is deprecated according to modern Facebook login - # policies. Included for completeness, but unnecessary. - if require_app and not self.facebook.added: - self.redirect(self.facebook.get_add_url(next=request.path)) - self.redirecting = True - return - - if not (require_app or require_login) and need_session: - self.facebook.auth.getSession() - - def redirect(self, url, **kwargs): - """ - For Facebook canvas pages we should use <fb:redirect /> instead of - a normal redirect. - """ - if self.facebook.in_canvas: - self.response.clear() - self.response.out.write('<fb:redirect url="%s" />' % (url, )) - else: - super(FacebookRequestHandler, self).redirect(url, **kwargs) - - def add_user_message(self, kind, msg, detail='', time=15 * 60): - """ - Add a message to the current user to memcache. - """ - if self.facebook.uid: - key = 'messages:%s' % self.facebook.uid - self._messages = memcache.get(key) - message = { - 'kind': kind, - 'message': msg, - 'detail': detail, - } - if self._messages is not None: - self._messages.append(message) - else: - self._messages = [message] - memcache.set(key, self._messages, time=time) - - def get_and_delete_user_messages(self): - """ - Get all of the messages for the current user; removing them. - """ - if self.facebook.uid: - key = 'messages:%s' % self.facebook.uid - if not hasattr(self, '_messages') or self._messages is None: - self._messages = memcache.get(key) - memcache.delete(key) - return self._messages - return None - -class FacebookCanvasHandler(FacebookRequestHandler): - """ - Request handler for Facebook canvas (FBML application) requests. - """ - - def canvas(self, *args, **kwargs): - """ - This will be your handler to deal with Canvas requests. - """ - raise NotImplementedError() - - def get(self, *args): - """ - All valid canvas views are POSTS. - """ - # TODO: Attempt to auto-redirect to Facebook canvas? - self.error(404) - - def post(self, *args, **kwargs): - """ - Check a couple of simple safety checks and then call the canvas - handler. - """ - if self.redirecting: return - - if not self.facebook.in_canvas: - self.error(404) - return - - self.canvas(*args, **kwargs) - -# vim: ai et ts=4 sts=4 sw=4 diff --git a/helios_auth/auth_systems/facebookclient/wsgi.py b/helios_auth/auth_systems/facebookclient/wsgi.py deleted file mode 100644 index f6a790db14858d762159478a4aa51e7323144b5d..0000000000000000000000000000000000000000 --- a/helios_auth/auth_systems/facebookclient/wsgi.py +++ /dev/null @@ -1,129 +0,0 @@ -"""This is some simple helper code to bridge the Pylons / PyFacebook gap. - -There's some generic WSGI middleware, some Paste stuff, and some Pylons -stuff. Once you put FacebookWSGIMiddleware into your middleware stack, -you'll have access to ``environ["pyfacebook.facebook"]``, which is a -``facebook.Facebook`` object. If you're using Paste (which includes -Pylons users), you can also access this directly using the facebook -global in this module. - -""" - -# Be careful what you import. Don't expect everyone to have Pylons, -# Paste, etc. installed. Degrade gracefully. - -from facebook import Facebook - -__docformat__ = "restructuredtext" - - -# Setup Paste, if available. This needs to stay in the same module as -# FacebookWSGIMiddleware below. - -try: - from paste.registry import StackedObjectProxy - from webob.exc import _HTTPMove - from paste.util.quoting import strip_html, html_quote, no_quote -except ImportError: - pass -else: - facebook = StackedObjectProxy(name="PyFacebook Facebook Connection") - - - class CanvasRedirect(_HTTPMove): - - """This is for canvas redirects.""" - - title = "See Other" - code = 200 - template = '<fb:redirect url="%(location)s" />' - - def html(self, environ): - """ text/html representation of the exception """ - body = self.make_body(environ, self.template, html_quote, no_quote) - return body - -class FacebookWSGIMiddleware(object): - - """This is WSGI middleware for Facebook.""" - - def __init__(self, app, config, facebook_class=Facebook): - """Initialize the Facebook middleware. - - ``app`` - This is the WSGI application being wrapped. - - ``config`` - This is a dict containing the keys "pyfacebook.apikey" and - "pyfacebook.secret". - - ``facebook_class`` - If you want to subclass the Facebook class, you can pass in - your replacement here. Pylons users will want to use - PylonsFacebook. - - """ - self.app = app - self.config = config - self.facebook_class = facebook_class - - def __call__(self, environ, start_response): - config = self.config - real_facebook = self.facebook_class(config["pyfacebook.apikey"], - config["pyfacebook.secret"]) - registry = environ.get('paste.registry') - if registry: - registry.register(facebook, real_facebook) - environ['pyfacebook.facebook'] = real_facebook - return self.app(environ, start_response) - - -# The remainder is Pylons specific. - -try: - import pylons - from pylons.controllers.util import redirect_to as pylons_redirect_to - from routes import url_for -except ImportError: - pass -else: - - - class PylonsFacebook(Facebook): - - """Subclass Facebook to add Pylons goodies.""" - - def check_session(self, request=None): - """The request parameter is now optional.""" - if request is None: - request = pylons.request - return Facebook.check_session(self, request) - - # The Django request object is similar enough to the Paste - # request object that check_session and validate_signature - # should *just work*. - - def redirect_to(self, url): - """Wrap Pylons' redirect_to function so that it works in_canvas. - - By the way, this won't work until after you call - check_session(). - - """ - if self.in_canvas: - raise CanvasRedirect(url) - pylons_redirect_to(url) - - def apps_url_for(self, *args, **kargs): - """Like url_for, but starts with "http://apps.facebook.com".""" - return "http://apps.facebook.com" + url_for(*args, **kargs) - - - def create_pylons_facebook_middleware(app, config): - """This is a simple wrapper for FacebookWSGIMiddleware. - - It passes the correct facebook_class. - - """ - return FacebookWSGIMiddleware(app, config, - facebook_class=PylonsFacebook)