diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..02fe7b72 --- /dev/null +++ b/.gitignore @@ -0,0 +1,33 @@ +# Compiled source # +################### +*.com +*.class +*.dll +*.exe +*.o +*.so + +# ignore all vagrant files +**/.vagrant + +# ignore all .json files +*.json + +# Packages # +############ +# it's better to unpack these files and commit the raw source +# git has its own built in compression methods +*.7z +*.dmg +*.gz +*.iso +*.jar +*.rar +*.tar +*.zip + +# Logs and databases # +###################### +*.log +*.sql +*.sqlite diff --git a/DeepinScreenshot_select-area_20190511121248.png b/DeepinScreenshot_select-area_20190511121248.png new file mode 100644 index 00000000..e609fc22 Binary files /dev/null and b/DeepinScreenshot_select-area_20190511121248.png differ diff --git a/README.md b/README.md index 90aafdc5..16c7cf96 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,18 @@ # OAuth2.0 Starter Code for Auth&Auth course +# Making the Code work with latest OAuth2.0 googleApi changes with Javascript + +This changed Codework has changes required to remove Jquery and Ajax completely and do all the Login and Logout requests using Javascript on python 2.7 + +No New libraries are required + +The code is tested on the legacy vagrant environment + +This code also has new features as *"signOut"* & *"Login"* links addeed to the restaurant page + + + + # Installing the Vagrant VM for ud330 - Authentication & Authorization **Note: If you already have a vagrant machine installed from previous Udacity courses skip to the 'Fetch the Source Code and VM Configuration' section** diff --git a/database_setup.pyc b/database_setup.pyc new file mode 100644 index 00000000..4da65f5d Binary files /dev/null and b/database_setup.pyc differ diff --git a/project.py b/project.py index 0c329b4e..994aeb4a 100644 --- a/project.py +++ b/project.py @@ -1,10 +1,22 @@ -from flask import Flask, render_template, request, redirect,jsonify, url_for, flash -app = Flask(__name__) - +from flask import Flask, render_template, request, redirect, jsonify, url_for, flash from sqlalchemy import create_engine, asc from sqlalchemy.orm import sessionmaker from database_setup import Base, Restaurant, MenuItem +from flask import session as login_session +import random +import string +from oauth2client.client import flow_from_clientsecrets +from oauth2client.client import FlowExchangeError +import httplib2 +import json +from flask import make_response +import requests +app = Flask(__name__) + +CLIENT_ID = json.loads( + open('client_secrets.json', 'r').read())['web']['client_id'] +APPLICATION_NAME = "Restaurant Menu Application" #Connect to Database and create database session engine = create_engine('sqlite:///restaurantmenu.db') @@ -14,6 +26,141 @@ session = DBSession() +@app.route('/login') +def showLogin(): + state = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in xrange(32)) + login_session['state'] = state + # Render the login template + return render_template('logingoogle.html', state = state, GOOGLE_CLIENT_ID=CLIENT_ID) + +@app.route('/gconnect', methods=['POST']) +def gconnect(): + if request.args.get('state') != login_session['state']: + response = make_response(json.dumps('Invalid state parameter.'), 401) + response.headers['Content-Type'] = 'application/json' + return response + # Obtain authorization code + code = request.data + + try: + # Upgrade the authorization code into a credentials object + oauth_flow = flow_from_clientsecrets('client_secrets.json', scope='') + oauth_flow.redirect_uri = 'postmessage' + credentials = oauth_flow.step2_exchange(code) + except FlowExchangeError: + response = make_response( + json.dumps('Failed to upgrade the authorization code.'), 401) + response.headers['Content-Type'] = 'application/json' + return response + + # Check that the access token is valid. + access_token = credentials.access_token + url = ('https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=%s' + % access_token) + h = httplib2.Http() + result = json.loads(h.request(url, 'GET')[1]) + # If there was an error in the access token info, abort. + if result.get('error') is not None: + response = make_response(json.dumps(result.get('error')), 500) + response.headers['Content-Type'] = 'application/json' + return response + + # Verify that the access token is used for the intended user. + gplus_id = credentials.id_token['sub'] + if result['user_id'] != gplus_id: + response = make_response( + json.dumps("Token's user ID doesn't match given user ID."), 401) + response.headers['Content-Type'] = 'application/json' + return response + + # Verify that the access token is valid for this app. + if result['issued_to'] != CLIENT_ID: + response = make_response( + json.dumps("Token's client ID does not match app's."), 401) + print "Token's client ID does not match app's." + response.headers['Content-Type'] = 'application/json' + return response + + stored_access_token = login_session.get('access_token') + stored_gplus_id = login_session.get('gplus_id') + if stored_access_token is not None and gplus_id == stored_gplus_id: + response = make_response(json.dumps('Current user is already connected.'), + 200) + response.headers['Content-Type'] = 'application/json' + return response + + # Store the access token in the session for later use. + login_session['access_token'] = credentials.access_token + login_session['gplus_id'] = gplus_id + + # Get user info + userinfo_url = "https://www.googleapis.com/oauth2/v1/userinfo" + params = {'access_token': credentials.access_token, 'alt': 'json'} + answer = requests.get(userinfo_url, params=params) + + data = answer.json() + login_session['logged_in'] = True + login_session['provider'] = 'google' + login_session['username'] = data['name'] + login_session['picture'] = data['picture'] + login_session['email'] = data['email'] + + output = '' + output += '
Login Link will go Here
- + Login