def get_token(self, args): user = self.session.get_user() response = unicode( urllib.urlopen( "https://login.salesforce.com/services/oauth2/token?", urllib.urlencode(args)).read(), 'utf-8') logging.info(response) tokens = simplejson.loads(response) access_token = tokens["access_token"] profile_url = tokens["id"] profile_res = self.call(profile_url, access_token=access_token) profile_body = unicode(profile_res.content, 'utf-8') profile = simplejson.loads(profile_body) account_name = str(profile["user_id"]) account = Account.gql( "WHERE service = :1 and account_name = :2 and user_ref = :3", "chatter", account_name, user.key()).get() if not account: account = Account(user_ref=user, service="chatter", account_name=str(profile["user_id"]), display_name=str(profile["display_name"]), account_info=profile_body, access_token=access_token) else: account.access_token = access_token account.display_name = str(profile["display_name"]) account.account_info = profile_body if tokens.get("refresh_token"): account.refresh_token = tokens["refresh_token"] account.put() return account
def accounts(self): user = self.session.get_user() accounts = Account.gql( "WHERE service = :1 and user_ref = :2 and access_token != :3", "facebook", user.key(), None) if accounts.count() == 0: return {} template_values = {'accounts': accounts} return template_values
def accounts(self): user = self.session.get_user() accounts = Account.gql( "WHERE service = :1 and user_ref = :2 and access_token != :3", "chatter", user.key(), None ) if accounts.count() == 0: return {} template_values = {"accounts": accounts} return template_values
def call(self, url, account_name=None, params={}, method="get", body=None, content_type=None, access_token=None, account=None): user = self.session.get_user() is_retry = account is not None if access_token is None: if account is None: account = Account.gql( "WHERE service = :1 and account_name = :2 and user_ref = :3", "chatter", account_name, user.key()).get() access_token = account.access_token account_info = simplejson.loads(account.account_info) if not url.startswith("http"): url = account_info["urls"]["rest"].replace( "{version}", "22.0") + url headers = {"Authorization": "OAuth " + access_token} #query = urllib.urlencode(params) 念のためコメントアウト query = utils.encoded_urlencode(params) response = None if method == "get": response = urlfetch.fetch(url + "?" + query, headers=headers) elif method == "post": if body: query = body headers[ 'Content-Type'] = content_type or 'application/x-www-form-urlencoded; charset=utf-8' response = urlfetch.fetch(url, payload=query, method=urlfetch.POST, headers=headers) elif method == "delete": response = urlfetch.fetch(url + "?" + query, method=urlfetch.DELETE, headers=headers) logging.info(url) logging.info(query) logging.info(str(response.status_code)) logging.info(response.content) if response.status_code == 401 and not is_retry: args = dict(client_id=settings.CHATTER_CLIENT_ID, client_secret=settings.CHATTER_CLIENT_SECRET, grant_type='refresh_token', refresh_token=account.refresh_token) account = self.get_token(args) response = self.call(url, account=account, params=params, method=method) return response
def call( self, url, account_name=None, params={}, method="get", body=None, content_type=None, access_token=None, account=None, ): user = self.session.get_user() is_retry = account is not None if access_token is None: if account is None: account = Account.gql( "WHERE service = :1 and account_name = :2 and user_ref = :3", "chatter", account_name, user.key() ).get() access_token = account.access_token account_info = simplejson.loads(account.account_info) if not url.startswith("http"): url = account_info["urls"]["rest"].replace("{version}", "22.0") + url headers = {"Authorization": "OAuth " + access_token} # query = urllib.urlencode(params) 念のためコメントアウト query = utils.encoded_urlencode(params) response = None if method == "get": response = urlfetch.fetch(url + "?" + query, headers=headers) elif method == "post": if body: query = body headers["Content-Type"] = content_type or "application/x-www-form-urlencoded; charset=utf-8" response = urlfetch.fetch(url, payload=query, method=urlfetch.POST, headers=headers) elif method == "delete": response = urlfetch.fetch(url + "?" + query, method=urlfetch.DELETE, headers=headers) logging.info(url) logging.info(query) logging.info(str(response.status_code)) logging.info(response.content) if response.status_code == 401 and not is_retry: args = dict( client_id=settings.CHATTER_CLIENT_ID, client_secret=settings.CHATTER_CLIENT_SECRET, grant_type="refresh_token", refresh_token=account.refresh_token, ) account = self.get_token(args) response = self.call(url, account=account, params=params, method=method) return response
def get_current_account(cls, user, account_name): key = "oauth_token/"+user.user_id+"/"+cls.service+"/"+account_name account = memcache.get(key) if account is not None: return account account = Account.gql( "WHERE service = :1 and account_name = :2 and user_ref = :3", cls.service, account_name, user.key()).get() if account == None or account.access_token == None: raise Exception('Access token is not saved. : service = %s, account_name = %s' % (cls.service, account_name) ) memcache.set(key, account, 24*60*60) #24時間キャッシュする return account
def call(user, account, url, params={}, method="get"): account = Account.gql( "WHERE service = :1 and account_name = :2 and user_ref = :3", "facebook", account, user.key()).get() params["access_token"] = account.access_token query = urllib.urlencode(params) response = None if method == "get": response = urlfetch.fetch(url+"?"+query, deadline=3) elif method == "post": response = urlfetch.fetch(url, payload=query, method=urlfetch.POST, deadline=10) elif method == "delete": response = urlfetch.fetch(url+"?"+query, method=urlfetch.DELETE, deadline=10) return response
def call(user, account, url, params={}, method="get"): account = Account.gql( "WHERE service = :1 and account_name = :2 and user_ref = :3", "facebook", account, user.key()).get() params["access_token"] = account.access_token query = urllib.urlencode(params) response = None if method == "get": response = urlfetch.fetch(url + "?" + query, deadline=3) elif method == "post": response = urlfetch.fetch(url, payload=query, method=urlfetch.POST, deadline=10) elif method == "delete": response = urlfetch.fetch(url + "?" + query, method=urlfetch.DELETE, deadline=10) return response
def multipartRequest(cls, user, account_name, url, params={}, files={}): account = Account.gql( "WHERE service = :1 and account_name = :2 and user_ref = :3", cls.service, account_name, user.key()).get() if account == None or account.access_token == None: raise Exception('Access token is not saved. : service = %s, account_name = %s' % (cls.service, account_name) ) BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$' body = utils.multipart_encode(params, files, BOUNDARY) headers = { 'Content-Type': 'multipart/form-data; boundary=%s' % BOUNDARY } token = oauth.Token(account.access_token, account.secret) client = cls.newOAuthClient(token) return client.request(url, "POST", body, headers)
def call_multipart(user, account_name, url, params={}, files={}): account = Account.gql( "WHERE service = :1 and account_name = :2 and user_ref = :3", "facebook", account_name, user.key()).get() if account == None or account.access_token == None: raise Exception('Access token is not saved. : service = facebook, account_name = %s' % (account_name) ) params["access_token"] = account.access_token BOUNDARY = u'----------ThIs_Is_tHe_bouNdaRY_$' body = utils.multipart_encode(params, files, BOUNDARY) headers = { 'Content-Type': 'multipart/form-data; boundary=%s' % BOUNDARY } response = urlfetch.fetch(url, method=urlfetch.POST, payload=body, headers=headers, deadline=10) return response
def call_multipart(user, account_name, url, params={}, files={}): account = Account.gql( "WHERE service = :1 and account_name = :2 and user_ref = :3", "facebook", account_name, user.key()).get() if account == None or account.access_token == None: raise Exception( 'Access token is not saved. : service = facebook, account_name = %s' % (account_name)) params["access_token"] = account.access_token BOUNDARY = u'----------ThIs_Is_tHe_bouNdaRY_$' body = utils.multipart_encode(params, files, BOUNDARY) headers = {'Content-Type': 'multipart/form-data; boundary=%s' % BOUNDARY} response = urlfetch.fetch(url, method=urlfetch.POST, payload=body, headers=headers, deadline=10) return response
def add_page_account(user, account, page_account): if not page_account.startswith('page_'): return page_id = page_account.split('_', 1)[1] url = "https://graph.facebook.com/" + page_id params = {"fields":"access_token"} response = call(user, account, url, params=params) if response.status_code != 200: raise Exception(str(response.status_code) + " failed to get page's access token. : " + response.content) content = unicode(response.content, 'utf-8') token_res = simplejson.loads(content) response = call(user, account, url) content = unicode(response.content, 'utf-8') profile_res = simplejson.loads(content) account = Account( user_ref=user, service="facebook", account_name=page_account, display_name=str(profile_res["name"]), group_image_url="https://graph.facebook.com/%s/picture" % profile_res["id"], account_info=content, access_token=token_res["access_token"] ) account.put() #既に同じアカウントが登録されていたら削除します saved_accounts = Account.gql( "WHERE service = :1 and user_ref = :2 and account_name = :3", "facebook", user.key(), account.account_name) for saved_account in saved_accounts: if saved_account.key() != account.key(): saved_account.delete()
def add_page_account(user, account, page_account): if not page_account.startswith('page_'): return page_id = page_account.split('_', 1)[1] url = "https://graph.facebook.com/" + page_id params = {"fields": "access_token"} response = call(user, account, url, params=params) if response.status_code != 200: raise Exception( str(response.status_code) + " failed to get page's access token. : " + response.content) content = unicode(response.content, 'utf-8') token_res = simplejson.loads(content) response = call(user, account, url) content = unicode(response.content, 'utf-8') profile_res = simplejson.loads(content) account = Account(user_ref=user, service="facebook", account_name=page_account, display_name=str(profile_res["name"]), group_image_url="https://graph.facebook.com/%s/picture" % profile_res["id"], account_info=content, access_token=token_res["access_token"]) account.put() #既に同じアカウントが登録されていたら削除します saved_accounts = Account.gql( "WHERE service = :1 and user_ref = :2 and account_name = :3", "facebook", user.key(), account.account_name) for saved_account in saved_accounts: if saved_account.key() != account.key(): saved_account.delete()
def get_token(self, args): user = self.session.get_user() response = unicode(urllib.urlopen( "https://login.salesforce.com/services/oauth2/token?", urllib.urlencode(args)).read(), 'utf-8') logging.info(response) tokens = simplejson.loads(response) access_token = tokens["access_token"] profile_url = tokens["id"] profile_res = self.call(profile_url, access_token=access_token) profile_body = unicode(profile_res.content, 'utf-8') profile = simplejson.loads(profile_body) account_name = str(profile["user_id"]) account = Account.gql( "WHERE service = :1 and account_name = :2 and user_ref = :3", "chatter", account_name, user.key()).get() if not account : account = Account( user_ref=user, service="chatter", account_name=str(profile["user_id"]), display_name=str(profile["display_name"]), account_info=profile_body, access_token=access_token ) else: account.access_token = access_token account.display_name = str(profile["display_name"]) account.account_info = profile_body if tokens.get("refresh_token") : account.refresh_token = tokens["refresh_token"] account.put() return account
def get(self, action="", account="", param=""): user = self.session.get_user() if action == "oauth": verification_code = self.request.get("code") args = dict(client_id=settings.CHATTER_CLIENT_ID, redirect_uri=self.request.path_url) if verification_code: args["client_secret"] = settings.CHATTER_CLIENT_SECRET args["code"] = verification_code args["grant_type"] = "authorization_code" account = self.get_token(args) # 既に同じアカウントが登録されていたら削除します saved_accounts = Account.gql( "WHERE service = :1 and user_ref = :2 and account_name = :3", "chatter", user.key(), account.account_name, ) for saved_account in saved_accounts: if saved_account.key() != account.key(): saved_account.delete() # ウィンドウを閉じます tmpl = os.path.join(os.path.dirname(__file__), "../view/oauth_callback.html") return self.response.out.write(template.render(tmpl, {"account": account})) else: args["response_type"] = "code" self.redirect("https://login.salesforce.com/services/oauth2/authorize?" + urllib.urlencode(args)) return if action == "add_column": template_values = self.accounts() tmpl = os.path.join(os.path.dirname(__file__), "../view/chatter_add_column.html") return self.response.out.write(template.render(tmpl, template_values)) if action == "accounts": template_values = self.accounts() tmpl = os.path.join(os.path.dirname(__file__), "../view/chatter_accounts.html") return self.response.out.write(template.render(tmpl, template_values)) if action == "messages": type = self.request.get("type") until = self.request.get("until") query = {} url = "query" query[ "q" ] = """SELECT Id, Type, CreatedById, CreatedBy.Name, InsertedBy.Profile.CreatedBy.SmallPhotoUrl, CreatedDate, LastModifiedDate, ParentId, Parent.Name, Parent.Type, RelatedRecordId, CommentCount, Body, Title, LinkUrl, ContentData, ContentFileName, (SELECT Id, FieldName, OldValue, NewValue FROM FeedTrackedChanges ORDER BY Id DESC), (SELECT Id, CommentBody, CreatedDate, CreatedBy.Name, InsertedBy.Profile.CreatedBy.SmallPhotoUrl FROM FeedComments ORDER BY CreatedDate DESC LIMIT 2), (SELECT CreatedBy.Name FROM FeedLikes) FROM NewsFeed""" if until: query["q"] += " WHERE LastModifiedDate <= %s " % until.replace("+0000", "z") query[ "q" ] += """ ORDER BY LastModifiedDate DESC, Id DESC LIMIT 20""" template_values = self.get_messages(account, url, query) self.response.headers["Content-Type"] = "application/json" return self.response.out.write(simplejson.dumps(template_values)) if action == "comments": id = self.request.get("id") query = {} url = "query" query["q"] = ( """SELECT Id, (SELECT Id, CommentBody, CreatedDate, CreatedBy.Name, InsertedBy.Profile.CreatedBy.SmallPhotoUrl FROM FeedComments ORDER BY CreatedDate DESC LIMIT 200) FROM NewsFeed WHERE Id = '%s' LIMIT 20""" % id ) messages = self.get_messages(account, url, query).get("messages") try: template_values = messages[0]["FeedComments"]["records"] except: logging.error(simplejson.dumps(messages)) self.error(500) return self.response.headers["Content-Type"] = "application/json" return self.response.out.write(simplejson.dumps(template_values)) return self.error(400)
def get(self, action=""): user = self.session.get_user() if action == "callback": #key_nameが来たらそれを使う(現在callbackできないYammer用) oauth_key = self.request.cookies.get('oauth_key', None) if oauth_key == "": self.error(400) return account_key = db.Key(oauth_key) account = Account.get(account_key) try: token = oauth.Token(account.request_token, account.secret) oauth_verifier = self.request.get("oauth_verifier") client = self.newOAuthClient(token) resp, content = client.request(self.access_token_url, "POST", body="oauth_verifier=%s" % oauth_verifier) if resp['status'] != '200': raise Exception('Invalid response %s.' % resp['status']) access_token = dict(parse_qsl(content)) account.access_token = access_token['oauth_token'] account.secret = access_token['oauth_token_secret'] account.put() self.account = account account_name, display_name, group_image_url, account_info = self.get_account_info() account.account_name = account_name account.display_name = display_name account.group_image_url = group_image_url account.account_info = account_info if account.account_name == None or account.account_info == None: raise Exception('Cannot get account information.') account.put() #24時間アクセストークンをキャッシュ key = "oauth_token/"+user.user_id+"/"+self.service+"/"+account.account_name memcache.set(key, account, 24*60*60) #既に同じアカウントが登録されていたら削除します saved_accounts = Account.gql( "WHERE service = :1 and user_ref = :2 and account_name = :3", self.service, user.key(), account.account_name) for saved_account in saved_accounts: if saved_account.key() != account.key(): saved_account.delete() except: #どこかでエラーが発生したらゴミが残らないように削除する account.delete() logging.exception(sys.exc_info()) raise sys.exc_info() #ウィンドウを閉じます tmpl = os.path.join(os.path.dirname(__file__), "../view/oauth_callback.html") return self.response.out.write(template.render(tmpl, {'account':account})) if action == "request": client = self.newOAuthClient() account_key = Account( user_ref=user, service=self.service).put() params = { 'oauth_callback': self.request.relative_url('callback') } resp, content = client.request(self.request_token_url, 'POST', body=urllib.urlencode(params, True)) if resp['status'] != '200': raise Exception('Invalid response %s. : %s' % (resp['status'], content)) request_token = dict(parse_qsl(content)) account = Account.get(account_key) account.request_token = request_token['oauth_token'] account.secret = request_token['oauth_token_secret'] account.put() cookie_val = str('oauth_key=%s;' % str(account_key)) self.response.headers.add_header('Set-Cookie', cookie_val) self.redirect(self.authorize_url + "?oauth_token=" + request_token['oauth_token']) return self.error(400)
def get(self, action="", account="", param=""): user = self.session.get_user() if action == "oauth": verification_code = self.request.get("code") args = dict(client_id=settings.CHATTER_CLIENT_ID, redirect_uri=self.request.path_url) if verification_code: args["client_secret"] = settings.CHATTER_CLIENT_SECRET args["code"] = verification_code args["grant_type"] = "authorization_code" account = self.get_token(args) #既に同じアカウントが登録されていたら削除します saved_accounts = Account.gql( "WHERE service = :1 and user_ref = :2 and account_name = :3", "chatter", user.key(), account.account_name) for saved_account in saved_accounts: if saved_account.key() != account.key(): saved_account.delete() #ウィンドウを閉じます tmpl = os.path.join(os.path.dirname(__file__), "../view/oauth_callback.html") return self.response.out.write( template.render(tmpl, {'account': account})) else: args["response_type"] = "code" self.redirect( "https://login.salesforce.com/services/oauth2/authorize?" + urllib.urlencode(args)) return if action == "add_column": template_values = self.accounts() tmpl = os.path.join(os.path.dirname(__file__), "../view/chatter_add_column.html") return self.response.out.write( template.render(tmpl, template_values)) if action == "accounts": template_values = self.accounts() tmpl = os.path.join(os.path.dirname(__file__), "../view/chatter_accounts.html") return self.response.out.write( template.render(tmpl, template_values)) if action == "messages": type = self.request.get("type") until = self.request.get("until") query = {} url = "query" query["q"] = '''SELECT Id, Type, CreatedById, CreatedBy.Name, InsertedBy.Profile.CreatedBy.SmallPhotoUrl, CreatedDate, LastModifiedDate, ParentId, Parent.Name, Parent.Type, RelatedRecordId, CommentCount, Body, Title, LinkUrl, ContentData, ContentFileName, (SELECT Id, FieldName, OldValue, NewValue FROM FeedTrackedChanges ORDER BY Id DESC), (SELECT Id, CommentBody, CreatedDate, CreatedBy.Name, InsertedBy.Profile.CreatedBy.SmallPhotoUrl FROM FeedComments ORDER BY CreatedDate DESC LIMIT 2), (SELECT CreatedBy.Name FROM FeedLikes) FROM NewsFeed''' if until: query["q"] += " WHERE LastModifiedDate <= %s " % until.replace( '+0000', 'z') query["q"] += ''' ORDER BY LastModifiedDate DESC, Id DESC LIMIT 20''' template_values = self.get_messages(account, url, query) self.response.headers["Content-Type"] = "application/json" return self.response.out.write(simplejson.dumps(template_values)) if action == "comments": id = self.request.get("id") query = {} url = "query" query["q"] = '''SELECT Id, (SELECT Id, CommentBody, CreatedDate, CreatedBy.Name, InsertedBy.Profile.CreatedBy.SmallPhotoUrl FROM FeedComments ORDER BY CreatedDate DESC LIMIT 200) FROM NewsFeed WHERE Id = '%s' LIMIT 20''' % id messages = self.get_messages(account, url, query).get('messages') try: template_values = messages[0]["FeedComments"]["records"] except: logging.error(simplejson.dumps(messages)) self.error(500) return self.response.headers["Content-Type"] = "application/json" return self.response.out.write(simplejson.dumps(template_values)) return self.error(400)
def get(self, action="", account="", param=""): verification_code = self.request.get("code") args = dict(client_id=settings.FACEBOOK_APP_ID, redirect_uri=self.request.path_url) if verification_code: args["client_secret"] = settings.FACEBOOK_APP_SECRET args["code"] = verification_code response = cgi.parse_qs(urllib.urlopen( "https://graph.facebook.com/oauth/access_token?" + urllib.urlencode(args)).read()) access_token = response["access_token"][-1] profile_res = unicode(urllib.urlopen( "https://graph.facebook.com/me?" + urllib.urlencode(dict(access_token=access_token))).read(),'utf-8') profile = simplejson.loads(profile_res) user = None is_not_login = False try: self.check_login() user = self.session.get_user() except utils.NotLoginError: is_not_login = True user = User.gql("WHERE user_id=:1 and service=:2", str(profile["id"]), "facebook").get() if user is None: user = User( user_id=str(profile["id"]), name=str(profile["name"]), mail=str(profile["email"]), service='facebook', access_token=access_token, post_key='control', last_access_time=datetime.datetime.now() ) user.put() session = Session(self.request, self.response) session.new(user) account = Account( user_ref=user, service="facebook", account_name=str(profile["id"]), display_name=str(profile["name"]), account_info=profile_res, scope=FACEBOOK_SCOPE, access_token=access_token ) account.put() #既に同じアカウントが登録されていたら削除します saved_accounts = Account.gql( "WHERE service = :1 and user_ref = :2 and account_name = :3", "facebook", user.key(), account.account_name) for saved_account in saved_accounts: if saved_account.key() != account.key(): saved_account.delete() if is_not_login: if action == 'mlogin': self.redirect('/mhome?xoauth_requestor_id='+user.user_id) return self.redirect('/') return #ウィンドウを閉じます tmpl = os.path.join(os.path.dirname(__file__), "../view/oauth_callback.html") return self.response.out.write(template.render(tmpl, {'account':account})) else: args["scope"] = FACEBOOK_SCOPE if action == 'oauth': args["display"] = 'popup' self.redirect( "https://www.facebook.com/dialog/oauth?" + #"https://graph.facebook.com/oauth/authorize?" + urllib.urlencode(args)) return
def get(self, action="", account="", param=""): verification_code = self.request.get("code") args = dict(client_id=settings.FACEBOOK_APP_ID, redirect_uri=self.request.path_url) if verification_code: args["client_secret"] = settings.FACEBOOK_APP_SECRET args["code"] = verification_code response = cgi.parse_qs( urllib.urlopen( "https://graph.facebook.com/oauth/access_token?" + urllib.urlencode(args)).read()) access_token = response["access_token"][-1] profile_res = unicode( urllib.urlopen("https://graph.facebook.com/me?" + urllib.urlencode(dict( access_token=access_token))).read(), 'utf-8') profile = simplejson.loads(profile_res) user = None is_not_login = False try: self.check_login() user = self.session.get_user() except utils.NotLoginError: is_not_login = True user = User.gql("WHERE user_id=:1 and service=:2", str(profile["id"]), "facebook").get() if user is None: user = User(user_id=str(profile["id"]), name=str(profile["name"]), mail=str(profile["email"]), service='facebook', access_token=access_token, post_key='control', last_access_time=datetime.datetime.now()) user.put() session = Session(self.request, self.response) session.new(user) account = Account(user_ref=user, service="facebook", account_name=str(profile["id"]), display_name=str(profile["name"]), account_info=profile_res, scope=FACEBOOK_SCOPE, access_token=access_token) account.put() #既に同じアカウントが登録されていたら削除します saved_accounts = Account.gql( "WHERE service = :1 and user_ref = :2 and account_name = :3", "facebook", user.key(), account.account_name) for saved_account in saved_accounts: if saved_account.key() != account.key(): saved_account.delete() if is_not_login: if action == 'mlogin': self.redirect('/mhome?xoauth_requestor_id=' + user.user_id) return self.redirect('/') return #ウィンドウを閉じます tmpl = os.path.join(os.path.dirname(__file__), "../view/oauth_callback.html") return self.response.out.write( template.render(tmpl, {'account': account})) else: args["scope"] = FACEBOOK_SCOPE if action == 'oauth': args["display"] = 'popup' self.redirect("https://www.facebook.com/dialog/oauth?" + #"https://graph.facebook.com/oauth/authorize?" + urllib.urlencode(args)) return