def login(): try: email = request.json['email'] password = request.json['password'] except KeyError: return jsonify(status="error", message="Must supply email address and password"), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} if app.config['AUTH_REQUIRED'] and not db.is_user_valid(login=email): return jsonify(status="error", message="User %s is not authorized" % email), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} elif not db.is_user_valid(login=email): return jsonify(status="error", message="User %s does not exist" % email), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} else: user = db.get_users(query={"login": email}, password=True)[0] if not bcrypt.hashpw(password.encode('utf-8'), user['password'].encode('utf-8')) == user['password'].encode('utf-8'): return jsonify(status="error", message="User %s is not authorized" % email), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} try: customer = customer_match(email, groups=[email.split('@')[1]]) except NoCustomerMatch: return jsonify(status="error", message="No customer lookup defined for user %s" % email), 403 token = create_token(user['id'], user['name'], email, provider='basic', customer=customer, role=role(email)) return jsonify(token=token)
def login(): try: email = request.json["email"] domain = email.split("@")[1] password = request.json["password"] except KeyError: return ( jsonify(status="error", message="Must supply 'email' and 'password'"), 401, {"WWW-Authenticate": 'Basic realm="%s"' % BASIC_AUTH_REALM}, ) if app.config["AUTH_REQUIRED"] and not db.is_user_valid(login=email): return ( jsonify(status="error", message="User or password not valid"), 401, {"WWW-Authenticate": 'Basic realm="%s"' % BASIC_AUTH_REALM}, ) elif not db.is_user_valid(login=email): return ( jsonify(status="error", message="User %s does not exist" % email), 401, {"WWW-Authenticate": 'Basic realm="%s"' % BASIC_AUTH_REALM}, ) else: user = db.get_users(query={"login": email}, password=True)[0] if not bcrypt.hashpw(password.encode("utf-8"), user["password"].encode("utf-8")) == user["password"].encode( "utf-8" ): return ( jsonify(status="error", message="User or password not valid"), 401, {"WWW-Authenticate": 'Basic realm="%s"' % BASIC_AUTH_REALM}, ) if app.config["EMAIL_VERIFICATION"] and not db.is_email_verified(email): return jsonify(status="error", message="email address %s has not been verified" % email), 401 if app.config["AUTH_REQUIRED"] and not ( "*" in app.config["ALLOWED_EMAIL_DOMAINS"] or domain in app.config["ALLOWED_EMAIL_DOMAINS"] ): return jsonify(status="error", message="Login for user domain %s not allowed" % domain), 403 if app.config["CUSTOMER_VIEWS"]: try: customer = customer_match(email, groups=[domain]) except NoCustomerMatch: return jsonify(status="error", message="No customer lookup defined for user domain %s" % domain), 403 else: customer = None token = create_token(user["id"], user["name"], email, provider="basic", customer=customer, role=role(email)) return jsonify(token=token)
def login(): try: email = request.json['email'] domain = email.split('@')[1] password = request.json['password'] except KeyError: return jsonify(status="error", message="Must supply 'email' and 'password'"), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} if app.config['AUTH_REQUIRED'] and not db.is_user_valid(login=email): return jsonify(status="error", message="User or password not valid"), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} elif not db.is_user_valid(login=email): return jsonify(status="error", message="User %s does not exist" % email), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} else: user = db.get_users(query={"login": email}, password=True)[0] if not bcrypt.hashpw(password.encode('utf-8'), user['password'].encode( 'utf-8')) == user['password'].encode('utf-8'): return jsonify(status="error", message="User or password not valid"), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} if app.config['EMAIL_VERIFICATION'] and not db.is_email_verified(email): return jsonify(status="error", message="email address %s has not been verified" % email), 401 if app.config['AUTH_REQUIRED'] and not ( '*' in app.config['ALLOWED_EMAIL_DOMAINS'] or domain in app.config['ALLOWED_EMAIL_DOMAINS']): return jsonify(status="error", message="Login for user domain %s not allowed" % domain), 403 if app.config['CUSTOMER_VIEWS']: try: customer = customer_match(email, groups=[domain]) except NoCustomerMatch: return jsonify( status="error", message="No customer lookup defined for user domain %s" % domain), 403 else: customer = None token = create_token(user['id'], user['name'], email, provider='basic', customer=customer, scopes=scopes(email, groups=[user['role']])) return jsonify(token=token)
def get_user_keys(user): if not db.is_user_valid(user): return jsonify(status="error", message="not found"), 404 try: keys = db.get_keys({"user": user}) except Exception as e: return jsonify(status="error", message=str(e)), 500 if len(keys): return jsonify( status="ok", total=len(keys), keys=keys, time=datetime.datetime.utcnow() ) else: return jsonify( status="ok", message="not found", total=0, keys=[], time=datetime.datetime.utcnow() )
def twitter(): request_token_url = 'https://api.twitter.com/oauth/request_token' access_token_url = 'https://api.twitter.com/oauth/access_token' if request.json.get('oauth_token') and request.json.get('oauth_verifier'): auth = OAuth1(app.config['OAUTH2_CLIENT_ID'], client_secret=app.config['OAUTH2_CLIENT_SECRET'], resource_owner_key=request.json.get('oauth_token'), verifier=request.json.get('oauth_verifier')) r = requests.post(access_token_url, auth=auth) profile = dict(parse_qsl(r.text)) login = profile['screen_name'] if app.config['AUTH_REQUIRED'] and not db.is_user_valid(login=login): return jsonify(status="error", message="User %s is not authorized" % login), 403 token = create_token(profile['user_id'], '@' + login, login, provider='twitter') return jsonify(token=token) else: oauth = OAuth1(app.config['OAUTH2_CLIENT_ID'], client_secret=app.config['OAUTH2_CLIENT_SECRET'], callback_uri=app.config.get( 'TWITTER_CALLBACK_URL', request.headers.get('Referer', ''))) r = requests.post(request_token_url, auth=oauth) oauth_token = dict(parse_qsl(r.text)) return jsonify(oauth_token)
def twitter(): request_token_url = 'https://api.twitter.com/oauth/request_token' access_token_url = 'https://api.twitter.com/oauth/access_token' authenticate_url = 'https://api.twitter.com/oauth/authenticate' if request.args.get('oauth_token') and request.args.get('oauth_verifier'): auth = OAuth1(app.config['OAUTH2_CLIENT_ID'], client_secret=app.config['OAUTH2_CLIENT_SECRET'], resource_owner_key=request.args.get('oauth_token'), verifier=request.args.get('oauth_verifier')) r = requests.post(access_token_url, auth=auth) profile = dict(parse_qsl(r.text)) login = profile['screen_name'] if app.config['AUTH_REQUIRED'] and not db.is_user_valid(login=login): return jsonify(status="error", message="User %s is not authorized" % login), 403 token = create_token(profile['user_id'], '@'+login, login, provider='twitter') return jsonify(token=token) else: oauth = OAuth1(app.config['OAUTH2_CLIENT_ID'], client_secret=app.config['OAUTH2_CLIENT_SECRET'], callback_uri=app.config.get('TWITTER_CALLBACK_URL', request.headers.get('Referer', '')) ) r = requests.post(request_token_url, auth=oauth) oauth_token = dict(parse_qsl(r.text)) qs = urlencode(dict(oauth_token=oauth_token['oauth_token'])) return redirect(authenticate_url + '?' + qs)
def verify_token(token): if db.is_token_valid(token): return True url = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=' + token response = requests.get(url) token_info = response.json() if 'error' in token_info: LOG.warning('Token authentication failed: %s', token_info['error']) return False if 'audience' in token_info: if token_info['audience'] != app.config['OAUTH2_CLIENT_ID']: LOG.warning('Token supplied was for different web application') return False if 'email' in token_info: if not ('*' in app.config['ALLOWED_EMAIL_DOMAINS'] or token_info['email'].split('@')[1] in app.config['ALLOWED_EMAIL_DOMAINS'] or db.is_user_valid(token_info['email'])): LOG.info('User %s not authorized to access API', token_info['email']) return False else: LOG.warning('No email address present in token info') return False db.save_token(token) return True
def github(): access_token_url = 'https://github.com/login/oauth/access_token' users_api_url = 'https://api.github.com/user' params = { 'client_id': request.json['clientId'], 'redirect_uri': request.json['redirectUri'], 'client_secret': app.config['OAUTH2_CLIENT_SECRET'], 'code': request.json['code'] } headers = {'Accept': 'application/json'} r = requests.get(access_token_url, headers=headers, params=params) access_token = r.json() r = requests.get(users_api_url, params=access_token) profile = r.json() r = requests.get(profile['organizations_url'], params=access_token) organizations = [o['login'] for o in r.json()] login = profile['login'] try: customer = customer_match(login, organizations) except NoCustomerMatch: return jsonify(status="error", message="No customer lookup defined for user %s" % login), 403 if app.config['AUTH_REQUIRED'] and not ('*' in app.config['ALLOWED_GITHUB_ORGS'] or set(app.config['ALLOWED_GITHUB_ORGS']).intersection(set(organizations)) or db.is_user_valid(login=login)): return jsonify(status="error", message="User %s is not authorized" % login), 403 token = create_token(profile['id'], profile.get('name', None) or '@'+login, login, provider='github', customer=customer, role=role(login)) return jsonify(token=token)
def github(): access_token_url = 'https://github.com/login/oauth/access_token' users_api_url = 'https://api.github.com/user' params = { 'client_id': request.json['clientId'], 'redirect_uri': request.json['redirectUri'], 'client_secret': app.config['OAUTH2_CLIENT_SECRET'], 'code': request.json['code'] } r = requests.get(access_token_url, params=params) access_token = dict(parse_qsl(r.text)) r = requests.get(users_api_url, params=access_token) profile = json.loads(r.text) r = requests.get(profile['organizations_url'], params=access_token) organizations = [o['login'] for o in json.loads(r.text)] login = profile['login'] if app.config['AUTH_REQUIRED'] and not ('*' in app.config['ALLOWED_GITHUB_ORGS'] or set(app.config['ALLOWED_GITHUB_ORGS']).intersection(set(organizations)) or db.is_user_valid(login=login)): return jsonify(status="error", message="User %s is not authorized" % profile['login']), 403 token = create_token(profile['id'], profile.get('name', None) or '@'+login, login, provider='github') return jsonify(token=token)
def login(): try: email = request.json["email"] password = request.json["password"] except KeyError: return ( jsonify(status="error", message="Must supply email address and password"), 401, {"WWW-Authenticate": 'Basic realm="%s"' % BASIC_AUTH_REALM}, ) if app.config["AUTH_REQUIRED"] and not db.is_user_valid(login=email): return ( jsonify(status="error", message="User %s is not authorized" % email), 401, {"WWW-Authenticate": 'Basic realm="%s"' % BASIC_AUTH_REALM}, ) elif not db.is_user_valid(login=email): return ( jsonify(status="error", message="User %s does not exist" % email), 401, {"WWW-Authenticate": 'Basic realm="%s"' % BASIC_AUTH_REALM}, ) else: user = db.get_users(query={"login": email}, password=True)[0] if not bcrypt.hashpw(password.encode("utf-8"), user["password"].encode("utf-8")) == user["password"].encode( "utf-8" ): return ( jsonify(status="error", message="User %s is not authorized" % email), 401, {"WWW-Authenticate": 'Basic realm="%s"' % BASIC_AUTH_REALM}, ) if app.config["CUSTOMER_VIEWS"]: try: customer = customer_match(email, groups=[email.split("@")[1]]) except NoCustomerMatch: return jsonify(status="error", message="No customer lookup defined for user %s" % email), 403 else: customer = None token = create_token(user["id"], user["name"], email, provider="basic", customer=customer, role=role(email)) return jsonify(token=token)
def gitlab(): if not app.config['GITLAB_URL']: return jsonify( status="error", message="Must define GITLAB_URL setting in server configuration." ), 503 access_token_url = app.config['GITLAB_URL'] + '/oauth/token' gitlab_api_url = app.config['GITLAB_URL'] + '/api/v3' payload = { 'client_id': request.json['clientId'], 'client_secret': app.config['OAUTH2_CLIENT_SECRET'], 'redirect_uri': request.json['redirectUri'], 'grant_type': 'authorization_code', 'code': request.json['code'], } try: r = requests.post(access_token_url, data=payload) except Exception: return jsonify(status="error", message="Failed to call Gitlab API over HTTPS") access_token = r.json() r = requests.get(gitlab_api_url + '/user', params=access_token) profile = r.json() r = requests.get(gitlab_api_url + '/groups', params=access_token) groups = [g['path'] for g in r.json()] login = profile['username'] try: customer = customer_match(login, groups) except NoCustomerMatch: return jsonify(status="error", message="No customer lookup defined for user %s" % login), 403 if app.config['AUTH_REQUIRED'] and not ( '*' in app.config['ALLOWED_GITLAB_GROUPS'] or set(app.config['ALLOWED_GITLAB_GROUPS']).intersection( set(groups)) or db.is_user_valid(login=login)): return jsonify(status="error", message="User %s is not authorized" % login), 403 token = create_token(profile['id'], profile.get('name', None) or '@' + login, login, provider='gitlab', customer=customer, role=role(login)) return jsonify(token=token)
def login(): try: email = request.json['email'] domain = email.split('@')[1] password = request.json['password'] except KeyError: return jsonify(status="error", message="Must supply 'email' and 'password'"), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} if app.config['AUTH_REQUIRED'] and not db.is_user_valid(login=email): return jsonify(status="error", message="User or password not valid"), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} elif not db.is_user_valid(login=email): return jsonify(status="error", message="User %s does not exist" % email), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} else: user = db.get_users(query={"login": email}, password=True)[0] if not bcrypt.hashpw(password.encode('utf-8'), user['password'].encode('utf-8')) == user['password'].encode('utf-8'): return jsonify(status="error", message="User or password not valid"), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} if app.config['EMAIL_VERIFICATION'] and not db.is_email_verified(email): return jsonify(status="error", message="email address %s has not been verified" % email), 401 if app.config['AUTH_REQUIRED'] and not ('*' in app.config['ALLOWED_EMAIL_DOMAINS'] or domain in app.config['ALLOWED_EMAIL_DOMAINS']): return jsonify(status="error", message="Login for user domain %s not allowed" % domain), 403 if app.config['CUSTOMER_VIEWS']: try: customer = customer_match(email, groups=[domain]) except NoCustomerMatch: return jsonify(status="error", message="No customer lookup defined for user domain %s" % domain), 403 else: customer = None token = create_token(user['id'], user['name'], email, provider='basic', customer=customer, role=role(email)) return jsonify(token=token)
def login(): try: email = request.json['email'] password = request.json['password'] except KeyError: return jsonify(status="error", message="Must supply email address and password"), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} if app.config['AUTH_REQUIRED'] and not db.is_user_valid(login=email): return jsonify(status="error", message="User %s is not authorized" % email), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} elif not db.is_user_valid(login=email): return jsonify(status="error", message="User %s does not exist" % email), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} else: user = db.get_users(query={"login": email}, password=True)[0] if not bcrypt.hashpw(password.encode('utf-8'), user['password'].encode( 'utf-8')) == user['password'].encode('utf-8'): return jsonify(status="error", message="User %s is not authorized" % email), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} if app.config['CUSTOMER_VIEWS']: try: customer = customer_match(email, groups=[email.split('@')[1]]) except NoCustomerMatch: return jsonify(status="error", message="No customer lookup defined for user %s" % email), 403 else: customer = None token = create_token(user['id'], user['name'], email, provider='basic', customer=customer, role=role(email)) return jsonify(token=token)
def login(): try: email = request.json['email'] password = request.json['password'] except KeyError: return jsonify(status="error", message="Must supply email address and password"), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} if app.config['AUTH_REQUIRED'] and not db.is_user_valid(login=email): return jsonify(status="error", message="User %s is not authorized" % email), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} elif not db.is_user_valid(login=email): return jsonify(status="error", message="User %s does not exist" % email), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} else: user = db.get_users(query={"login": email})[0] if not bcrypt.hashpw(password.encode('utf-8'), user['password'].encode('utf-8')) == user['password'].encode('utf-8'): return jsonify(status="error", message="User %s is not authorized" % email), 401, \ {'WWW-Authenticate': 'Basic realm="%s"' % BASIC_AUTH_REALM} token = create_token(user['id'], user['name'], email, provider='basic') return jsonify(token=token)
def google(): access_token_url = 'https://accounts.google.com/o/oauth2/token' people_api_url = 'https://www.googleapis.com/plus/v1/people/me/openIdConnect' payload = { 'client_id': request.json['clientId'], 'client_secret': app.config['OAUTH2_CLIENT_SECRET'], 'redirect_uri': request.json['redirectUri'], 'grant_type': 'authorization_code', 'code': request.json['code'], } try: r = requests.post(access_token_url, data=payload) except Exception: return jsonify(status="error", message="Failed to call Google API over HTTPS") token = r.json() if 'id_token' not in token: return jsonify(status="error", message=token.get('error', "Invalid token")) id_token = token['id_token'].split('.')[1].encode('ascii', 'ignore') id_token += '=' * (4 - (len(id_token) % 4)) claims = json.loads(urlsafe_b64decode(id_token)) if claims.get('aud') != app.config['OAUTH2_CLIENT_ID']: return jsonify(status="error", message="Token client audience is invalid"), 400 email = claims.get('email') if app.config['AUTH_REQUIRED'] and not ('*' in app.config['ALLOWED_EMAIL_DOMAINS'] or email.split('@')[1] in app.config['ALLOWED_EMAIL_DOMAINS'] or db.is_user_valid(login=email)): return jsonify(status="error", message="User %s is not authorized" % email), 403 headers = {'Authorization': 'Bearer ' + token['access_token']} r = requests.get(people_api_url, headers=headers) profile = r.json() try: customer = customer_match(email, groups=[email.split('@')[1]]) except NoCustomerMatch: return jsonify(status="error", message="No customer lookup defined for user %s" % email), 403 try: token = create_token(profile['sub'], profile['name'], email, provider='google', customer=customer, role=role(email)) except KeyError: return jsonify(status="error", message="Google+ API is not enabled for this Client ID") return jsonify(token=token)
def github(): access_token_url = 'https://github.com/login/oauth/access_token' users_api_url = 'https://api.github.com/user' params = { 'client_id': request.json['clientId'], 'redirect_uri': request.json['redirectUri'], 'client_secret': app.config['OAUTH2_CLIENT_SECRET'], 'code': request.json['code'] } headers = {'Accept': 'application/json'} r = requests.get(access_token_url, headers=headers, params=params) access_token = r.json() r = requests.get(users_api_url, params=access_token) profile = r.json() r = requests.get(profile['organizations_url'], params=access_token) organizations = [o['login'] for o in r.json()] login = profile['login'] try: customer = customer_match(login, organizations) except NoCustomerMatch: return jsonify(status="error", message="No customer lookup defined for user %s" % login), 403 if app.config['AUTH_REQUIRED'] and not ( '*' in app.config['ALLOWED_GITHUB_ORGS'] or set(app.config['ALLOWED_GITHUB_ORGS']).intersection( set(organizations)) or db.is_user_valid(login=login)): return jsonify(status="error", message="User %s is not authorized" % login), 403 token = create_token(profile['id'], profile.get('name', None) or '@' + login, login, provider='github', customer=customer, role=role(login)) return jsonify(token=token)
def gitlab(): if not app.config['GITLAB_URL']: return jsonify(status="error", message="Must define GITLAB_URL setting in server configuration."), 503 access_token_url = app.config['GITLAB_URL'] + '/oauth/token' gitlab_api_url = app.config['GITLAB_URL'] + '/api/v3' payload = { 'client_id': request.json['clientId'], 'client_secret': app.config['OAUTH2_CLIENT_SECRET'], 'redirect_uri': request.json['redirectUri'], 'grant_type': 'authorization_code', 'code': request.json['code'], } try: r = requests.post(access_token_url, data=payload) except Exception: return jsonify(status="error", message="Failed to call Gitlab API over HTTPS") access_token = r.json() r = requests.get(gitlab_api_url+'/user', params=access_token) profile = r.json() r = requests.get(gitlab_api_url+'/groups', params=access_token) groups = [g['path'] for g in r.json()] login = profile['username'] try: customer = customer_match(login, groups) except NoCustomerMatch: return jsonify(status="error", message="No customer lookup defined for user %s" % login), 403 if app.config['AUTH_REQUIRED'] and not ('*' in app.config['ALLOWED_GITLAB_GROUPS'] or set(app.config['ALLOWED_GITLAB_GROUPS']).intersection(set(groups)) or db.is_user_valid(login=login)): return jsonify(status="error", message="User %s is not authorized" % login), 403 token = create_token(profile['id'], profile.get('name', None) or '@'+login, login, provider='gitlab', customer=customer, role=role(login)) return jsonify(token=token)
def get_user_keys(user): if not db.is_user_valid(user): return jsonify(status="error", message="not found"), 404 try: keys = db.get_keys({"user": user}) except Exception as e: return jsonify(status="error", message=str(e)), 500 if len(keys): return jsonify(status="ok", total=len(keys), keys=keys, time=datetime.datetime.utcnow()) else: return jsonify(status="ok", message="not found", total=0, keys=[], time=datetime.datetime.utcnow())
def google(): access_token_url = 'https://accounts.google.com/o/oauth2/token' people_api_url = 'https://www.googleapis.com/plus/v1/people/me/openIdConnect' payload = { 'client_id': request.json['clientId'], 'client_secret': app.config['OAUTH2_CLIENT_SECRET'], 'redirect_uri': request.json['redirectUri'], 'grant_type': 'authorization_code', 'code': request.json['code'], } try: r = requests.post(access_token_url, data=payload) except Exception: return jsonify(status="error", message="Failed to call Google API over HTTPS") token = r.json() if 'id_token' not in token: return jsonify(status="error", message=token.get('error', "Invalid token")) id_token = token['id_token'].split('.')[1].encode('ascii', 'ignore') id_token += '=' * (4 - (len(id_token) % 4)) claims = json.loads(urlsafe_b64decode(id_token)) if claims.get('aud') != app.config['OAUTH2_CLIENT_ID']: return jsonify(status="error", message="Token client audience is invalid"), 400 email = claims.get('email') if app.config['AUTH_REQUIRED'] and not ( '*' in app.config['ALLOWED_EMAIL_DOMAINS'] or email.split('@')[1] in app.config['ALLOWED_EMAIL_DOMAINS'] or db.is_user_valid(login=email)): return jsonify(status="error", message="User %s is not authorized" % email), 403 headers = {'Authorization': 'Bearer ' + token['access_token']} r = requests.get(people_api_url, headers=headers) profile = r.json() try: customer = customer_match(email, groups=[email.split('@')[1]]) except NoCustomerMatch: return jsonify(status="error", message="No customer lookup defined for user %s" % email), 403 try: token = create_token(profile['sub'], profile['name'], email, provider='google', customer=customer, role=role(email)) except KeyError: return jsonify(status="error", message="Google+ API is not enabled for this Client ID") return jsonify(token=token)