def api_auth_callback(self): s = self._settings d = settings_defaults() code = flask.request.args.get("code") token_endpoint = s.get(['token_endpoint']) client_id = s.get(['client_id']) client_secret = s.get(['client_secret']) userinfo_endpoint = s.get(['userinfo_endpoint']) orguser_endpoint = s.get(['orguser_endpoint']) organization = s.get(['organization']) username_key = s.get(['username_key']) self._logger.info('token_endpoint: ' + str(token_endpoint)) client = WebApplicationClient(client_id) token_url, headers, body = client.prepare_token_request( token_endpoint, # authorization_response=flask.request.url, # redirect_url=flask.request.base_url, code=code ) headers['Accept'] = 'application/json' token_response = requests.post( token_url, headers=headers, data=body, auth=(client_id, client_secret), ) client.parse_request_body_response(json.dumps(token_response.json())) uri, headers, body = client.add_token(userinfo_endpoint) headers['Accept'] = 'application/json' userinfo_response = requests.get(uri, headers=headers, data=body) userinfo = userinfo_response.json() username = userinfo[username_key] uri, headers, body = client.add_token(orguser_endpoint.format(organization, username)) headers['Accept'] = 'application/json' orguser_response = requests.get(uri, headers=headers, data=body) if orguser_response.status_code == 204: # User is part of the specified organization, find user or create it if it doesn't exist user = self._user_manager.login_user(OAuth2PGCUser(username)) flask.session["usersession.id"] = user.session flask.g.user = user self._logger.info("authenticated: " + str(user.is_authenticated)) self._logger.info("user: "******"Actively logging in user {} from {}".format(user.get_id(), remote_addr)) r = flask.redirect('/') r.delete_cookie("active_logout") eventManager().fire(Events.USER_LOGGED_IN, payload=dict(username=user.get_id())) return r return flask.redirect('/?error=unauthorized')
def __init__(self): super(FacebookSignIn, self).__init__('facebook') self.client = WebApplicationClient(self.consumer_id) self.authorize_url = app.config["FACEBOOK_AUTHORIZE_URL"] self.access_token_url = app.config["FACEBOOK_ACCESS_TOKEN_URL"] self.user_info_url = app.config["FACEBOOK_USER_INFO_URL"]
def do_run(config, endpoint_list): global activation_key activation_key = config.get("activation_key").strip() app_name = "REST API Modular Input" if len(activation_key) > 32: activation_hash = activation_key[:32] activation_ts = activation_key[32:][::-1] current_ts = time.time() m = hashlib.md5() m.update((app_name + activation_ts)) if not m.hexdigest().upper() == activation_hash.upper(): logging.error( "FATAL Trial Activation key for App '%s' failed. Please ensure that you copy/pasted the key correctly." % app_name) sys.exit(2) if ((current_ts - long(activation_ts)) > 604800): logging.error( "FATAL Trial Activation key for App '%s' has now expired. Please visit http://www.baboonbones.com/#activation to purchase a non expiring key." % app_name) sys.exit(2) else: m = hashlib.md5() m.update((app_name)) if not m.hexdigest().upper() == activation_key.upper(): logging.error( "FATAL Activation key for App '%s' failed. Please ensure that you copy/pasted the key correctly." % app_name) sys.exit(2) #setup some globals server_uri = config.get("server_uri") global SPLUNK_PORT global STANZA global SESSION_TOKEN global delimiter SPLUNK_PORT = server_uri[18:] STANZA = config.get("name") SESSION_TOKEN = config.get("session_key") # encrypted_username, encrypted_password = get_credentials(SESSION_TOKEN) #params http_method = config.get("http_method", "GET") request_payload = config.get("request_payload") #none | basic | digest | oauth1 | oauth2 auth_type = config.get("auth_type", "none") #Delimiter to use for any multi "key=value" field inputs delimiter = config.get("delimiter", ",") #for basic and digest auth_user = config.get("auth_user") auth_password = config.get("auth_password") #for oauth1 oauth1_client_key = config.get("oauth1_client_key") oauth1_client_secret = config.get("oauth1_client_secret") oauth1_access_token = config.get("oauth1_access_token") oauth1_access_token_secret = config.get("oauth1_access_token_secret") #for oauth2 oauth2_token_type = config.get("oauth2_token_type", "Bearer") oauth2_access_token = config.get("oauth2_access_token") oauth2_refresh_token = config.get("oauth2_refresh_token") oauth2_refresh_url = config.get("oauth2_refresh_url") oauth2_refresh_props_str = config.get("oauth2_refresh_props") oauth2_client_id = config.get("oauth2_client_id") oauth2_client_secret = config.get("oauth2_client_secret") oauth2_refresh_props = {} if not oauth2_refresh_props_str is None: oauth2_refresh_props = dict((k.strip(), v.strip()) for k, v in ( item.split('=', 1) for item in oauth2_refresh_props_str.split(delimiter))) oauth2_refresh_props['client_id'] = oauth2_client_id oauth2_refresh_props['client_secret'] = oauth2_client_secret http_header_propertys = {} http_header_propertys_str = config.get("http_header_propertys") if not http_header_propertys_str is None: http_header_propertys = dict((k.strip(), v.strip()) for k, v in ( item.split('=', 1) for item in http_header_propertys_str.split(delimiter))) url_args = {} url_args_str = config.get("url_args") if not url_args_str is None: url_args = dict( (k.strip(), v.strip()) for k, v in (item.split('=', 1) for item in url_args_str.split(delimiter))) #json | xml | text response_type = config.get("response_type", "text") streaming_request = int(config.get("streaming_request", 0)) http_proxy = config.get("http_proxy") https_proxy = config.get("https_proxy") proxies = {} if not http_proxy is None: proxies["http"] = http_proxy if not https_proxy is None: proxies["https"] = https_proxy cookies = {} cookies_str = config.get("cookies") if not cookies_str is None: cookies = dict((k.strip(), v.strip()) for k, v in (item.split('=', 1) for item in cookies_str.split(delimiter))) request_timeout = int(config.get("request_timeout", 30)) backoff_time = int(config.get("backoff_time", 10)) sequential_stagger_time = int(config.get("sequential_stagger_time", 0)) polling_interval_string = config.get("polling_interval", "60") if polling_interval_string.isdigit(): polling_type = 'interval' polling_interval = int(polling_interval_string) else: polling_type = 'cron' cron_start_date = datetime.now() cron_iter = croniter(polling_interval_string, cron_start_date) index_error_response_codes = int( config.get("index_error_response_codes", 0)) response_filter_pattern = config.get("response_filter_pattern") if response_filter_pattern: global REGEX_PATTERN REGEX_PATTERN = re.compile(response_filter_pattern) response_handler_args = {} response_handler_args_str = config.get("response_handler_args") if not response_handler_args_str is None: response_handler_args = dict((k.strip(), v.strip()) for k, v in ( item.split('=', 1) for item in response_handler_args_str.split(delimiter))) response_handler = config.get("response_handler", "DefaultResponseHandler") module = __import__("responsehandlers") class_ = getattr(module, response_handler) global RESPONSE_HANDLER_INSTANCE RESPONSE_HANDLER_INSTANCE = class_(**response_handler_args) custom_auth_handler = config.get("custom_auth_handler") if custom_auth_handler: module = __import__("authhandlers") class_ = getattr(module, custom_auth_handler) custom_auth_handler_args = {} custom_auth_handler_args_str = config.get("custom_auth_handler_args") if not custom_auth_handler_args_str is None: custom_auth_handler_args = dict( (k.strip(), v.strip()) for k, v in ( item.split('=', 1) for item in custom_auth_handler_args_str.split(delimiter))) CUSTOM_AUTH_HANDLER_INSTANCE = class_(**custom_auth_handler_args) try: auth = None oauth2 = None if auth_type == "basic": auth = HTTPBasicAuth(auth_user, auth_password) elif auth_type == "digest": auth = HTTPDigestAuth(auth_user, auth_password) elif auth_type == "oauth1": auth = OAuth1(oauth1_client_key, oauth1_client_secret, oauth1_access_token, oauth1_access_token_secret) elif auth_type == "oauth2": token = {} token["token_type"] = oauth2_token_type token["access_token"] = oauth2_access_token token["refresh_token"] = oauth2_refresh_token token["expires_in"] = "5" client = WebApplicationClient(oauth2_client_id) oauth2 = OAuth2Session(client, token=token, auto_refresh_url=oauth2_refresh_url, auto_refresh_kwargs=oauth2_refresh_props, token_updater=oauth2_token_updater) elif auth_type == "custom" and CUSTOM_AUTH_HANDLER_INSTANCE: auth = CUSTOM_AUTH_HANDLER_INSTANCE req_args = { "verify": False, "stream": bool(streaming_request), "timeout": float(request_timeout) } if auth: req_args["auth"] = auth if url_args: req_args["params"] = url_args if cookies: req_args["cookies"] = cookies if http_header_propertys: req_args["headers"] = http_header_propertys if proxies: req_args["proxies"] = proxies if request_payload and not http_method == "GET": req_args["data"] = request_payload while True: if polling_type == 'cron': next_cron_firing = cron_iter.get_next(datetime) while get_current_datetime_for_cron() != next_cron_firing: time.sleep(float(10)) for endpoint in endpoint_list: if "params" in req_args: req_args_params_current = dictParameterToStringFormat( req_args["params"]) else: req_args_params_current = "" if "cookies" in req_args: req_args_cookies_current = dictParameterToStringFormat( req_args["cookies"]) else: req_args_cookies_current = "" if "headers" in req_args: req_args_headers_current = dictParameterToStringFormat( req_args["headers"]) else: req_args_headers_current = "" if "data" in req_args: req_args_data_current = req_args["data"] else: req_args_data_current = "" try: if oauth2: if http_method == "GET": r = oauth2.get(endpoint, **req_args) elif http_method == "POST": r = oauth2.post(endpoint, **req_args) elif http_method == "PUT": r = oauth2.put(endpoint, **req_args) elif http_method == "HEAD": r = oauth2.head(endpoint, **req_args) else: if http_method == "GET": r = requests.get(endpoint, **req_args) elif http_method == "POST": r = requests.post(endpoint, **req_args) elif http_method == "PUT": r = requests.put(endpoint, **req_args) elif http_method == "HEAD": r = requests.head(endpoint, **req_args) except requests.exceptions.Timeout, e: logging.error("HTTP Request Timeout error: %s" % str(e)) time.sleep(float(backoff_time)) continue except Exception as e: logging.error("Exception performing request: %s" % str(e)) time.sleep(float(backoff_time)) continue try: r.raise_for_status() if streaming_request: for line in r.iter_lines(): if line: handle_output(r, line, response_type, req_args, endpoint) else: handle_output(r, r.text, response_type, req_args, endpoint) except requests.exceptions.HTTPError, e: error_output = r.text error_http_code = r.status_code if index_error_response_codes: error_event = "" error_event += 'http_error_code = %s error_message = %s' % ( error_http_code, error_output) print_xml_single_instance_mode(error_event) sys.stdout.flush() logging.error("HTTP Request error: %s" % str(e)) time.sleep(float(backoff_time)) continue
def test_code_in_uri(self): """Tests whether the value of code is retained in the uri""" client = WebApplicationClient('*****@*****.**') uri = "https://gCallback/?state=dummy_state&code=dummy_code" self.assertTrue('dummy_code' in client.parse_request_uri_response( uri, state='dummy_state').values())
def __init__(self, mendeley, state): MendeleyLoginAuthenticator.__init__(self, mendeley, WebApplicationClient(mendeley.client_id), state) self.token_url = self.mendeley.host + '/oauth/token' self.auth = HTTPBasicAuth(self.mendeley.client_id, self.mendeley.client_secret)
def create_app(): app = Flask(__name__) app.secret_key = os.environ.get("SECRET_KEY") or os.urandom(24) login_disabled = os.getenv('LOGIN_DISABLED') == 'True' app.config['LOGIN_DISABLED'] = login_disabled handler = logging.StreamHandler(sys.stdout) app.logger.addHandler(handler) app.logger.setLevel(os.getenv('LOG_LEVEL', 'INFO')) loggly_token = os.getenv('LOGGLY_TOKEN') loggly_tag = os.getenv('LOGGLY_TAG') if loggly_token is not None and loggly_tag is not None: handler = HTTPSHandler( f'https://logs-01.loggly.com/inputs/{loggly_token}/tag/{loggly_tag}' ) handler.setFormatter( logging.Formatter( "[%(asctime)s] %(levelname)s in %(module)s: %(message)s")) app.logger.addHandler(handler) log = logging.getLogger('app') collection = get_db_collection() # User session management setup login_manager = LoginManager() # This information is obtained upon registration of a new GitHub account client_id = os.getenv('CLIENT_ID') client_secret = os.getenv('CLIENT_SECRET') authorization_url = 'https://github.com/login/oauth/authorize' access_token_url = 'https://github.com/login/oauth/access_token' # OAuth 2.0 Client setup oauth_client = WebApplicationClient(client_id) log.info('Web Application has initialised') # Logic to redirect to Github OAuth flow when unauthenticated @login_manager.unauthorized_handler def unauthenticated(): log.debug('Redirecting user to be authenticated via GitHub OAuth') request_uri = oauth_client.prepare_request_uri(authorization_url) return redirect(request_uri) # This callback is used to reload the user object from the user ID stored in the session. @login_manager.user_loader def load_user(user_id): return User(user_id) # Once the actual application object has been created, you can configure it for login with: login_manager.init_app(app) # Implement the callback route @app.route("/login/callback", methods=["GET"]) def callback(): log.debug( 'Callback URL has been invoked after the user has been authenticated' ) token_url, token_headers, token_body = oauth_client.prepare_token_request( token_url="https://github.com/login/oauth/access_token", authorization_response=request.url, client_secret=client_secret) token_response = requests.post(token_url, headers=token_headers, data=token_body) oauth_client.parse_request_body_response( token_response.content.decode()) # Add token to the request uri, body or authorization header. user_info_request_url, user_info_request_headers, user_info_request_body = oauth_client.add_token( uri='https://api.github.com/user', ) user_info_response = requests.get(user_info_request_url, data=user_info_request_body, headers=user_info_request_headers) github_username = user_info_response.json()['login'] user = User(github_username) login_success = login_user(user) if login_success: log.debug(f'Successful logon for {github_username}') return redirect(url_for('index')) else: log.warning(f'Failed logon for {github_username}') return "Unauthorised", 403 @app.route('/') @login_required def index(): user = User(current_user.get_id()) reader = (not login_disabled) and user.get_role() == Role.Reader items = get_all_items(collection) return render_template('index.html', view_model=ViewModel(items, reader)) @app.route('/', methods=['POST']) @login_required @restricted def add_item(): title = request.form['item_title'] description = request.form['item_description'] log.debug( f'Request to add a new item with title: {title} and description: {description}' ) add_new_item(collection, title, description) log.debug( f'New item added with title: {title} and description: {description}' ) return redirect(url_for('index')) @app.route('/items/<id>/complete', methods=['POST']) @login_required @restricted def complete_item(id): log.debug(f'Request to mark item with id: {id} as complete') mark_item_as_complete(collection, id) log.debug(f'Item with id: {id} marked as complete') return redirect(url_for('index')) @app.route('/items/<id>/inprogress', methods=['POST']) @login_required @restricted def in_progress_item(id): log.debug(f'Request to mark item with id: {id} as in progress') mark_item_as_in_progress(collection, id) log.debug(f'Item with id: {id} marked as in progress') return redirect(url_for('index')) @app.route('/items/<id>/uncomplete', methods=['POST']) @login_required @restricted def uncomplete_item(id): log.debug(f'Request to mark item with id: {id} as uncompleted') mark_item_as_uncomplete(collection, id) log.debug(f'Item with id: {id} marked as uncompleted') return redirect(url_for('index')) @app.route('/items/delete/<id>', methods=['POST']) @login_required @restricted def delete_item(id): log.debug(f'Request to delete item with id: {id}') remove_item(collection, id) log.debug(f'Item with id: {id} has been deleted') return redirect(url_for('index')) if __name__ == '__main__': app.run(debug=True) return app
login_manager = LoginManager() oauthPage = Blueprint('oauth', __name__, template_folder='templates') # Configuration appConfig = getConfig() oauth_app_client_id = appConfig["oauth_app_client_id"] oauth_app_client_secret = appConfig["oauth_app_client_secret"] oauth_provider_discovery_url = ( appConfig["oauth_provider_discovery_url"] ) # OAuth2 client setup client = WebApplicationClient(oauth_app_client_id) def get_oauth_provider_cfg(): return requests.get(oauth_provider_discovery_url, verify=False).json() @login_manager.unauthorized_handler def unauthorized(): return "You must be logged in to access this content.", 403 # Flask-Login helper to retrieve a user from our db @login_manager.user_loader def load_user(user_id): sUser = session['SUSER']
login_user, logout_user, ) app = Flask(__name__, template_folder='templates') # We can make this secret key as environ variable later to sign cookies app.secret_key = "test" #os.environ.get("SECRET_KEY")# or os.urandom(24) app.config["MONGO_URI"] = "mongodb://*****:*****@app.route("/") def index(): if 'user_id' in session: print(session['user_id']) return render_template("index.html") @app.route("/postings") def postings(): # If not logged in, show Login button
import requests import datetime from bson.json_util import dumps from bson.json_util import loads from todo_app.flask_config import Config from todo_app.classModels import Item, ViewModel, User import pymongo from werkzeug.exceptions import Forbidden import logging from loggly.handlers import HTTPSHandler from logging import Formatter client_id = os.getenv("client_id") client_secret = os.getenv("client_secret") redirect_uri_value = os.getenv("redirect_uri") client = WebApplicationClient(client_id) def create_app(): app = Flask(__name__) app.config.from_object(Config) sess = Session() app.secret_key = os.getenv("SECRET_KEY") app.logger.setLevel(app.config['LOG_LEVEL']) app.config['SESSION_TYPE'] = 'filesystem' sess.init_app(app) if app.config['LOGGLY_TOKEN'] is not None: handler = HTTPSHandler(f'https://logs-01.loggly.com/inputs/{app.config["LOGGLY_TOKEN"]}/tag/todo-app') handler.setFormatter(Formatter("[%(asctime)s] %(levelname)s in %(module)s: %(message)s")) app.logger.addHandler(handler) collection=os.getenv("MONGO_COLLECTION") mongo_val = pymongo.MongoClient(os.getenv("MONGODB_CONNECTION_STRING"))
import json from demix.utils.logging import logger_factory from demix.auth import encode from demix.config import get_cfg from demix.db import get_db from demix.utils.flask import protected, current_user, custom_error GOOGLE_DISCOVERY_URL = ( "https://accounts.google.com/.well-known/openid-configuration") auth = Blueprint( 'auth', __name__, ) cfg = get_cfg('google') # stores google secret info client = WebApplicationClient(cfg['client_id']) # needed for google def get_google_provider_cfg(): return requests.get(GOOGLE_DISCOVERY_URL).json() google_provider_cfg = get_google_provider_cfg() logger = logger_factory(__name__) db = get_db() @auth.route("/api/me") @protected def me(): user = current_user()
def create_app(): mongo_db_client = pymongo.MongoClient( os.getenv('DATABASE_CONNECTION_STRING')) db = mongo_db_client[os.getenv('DATABASE_NAME')] collection = db['todo_app_items'] users_collection = db['users'] app = Flask(__name__) app.config.from_object('todo_app.flask_config.Config') app.secret_key = os.getenv('SECRET_KEY') login_manager = LoginManager() web_application_client = WebApplicationClient(os.getenv('CLIENT_ID')) class User(UserMixin): def __init__(self, id, name, user_role): self.id = id self.name = name self.user_role = user_role @login_manager.unauthorized_handler def unauthenticated(): return redirect( web_application_client.prepare_request_uri( 'https://github.com/login/oauth/authorize')) @login_manager.user_loader def load_user(user_id): query = {'github_id': user_id} db_user = users_collection.find_one(query) user = User(user_id, db_user['name'], db_user['user_role']) return user login_manager.init_app(app) @app.route('/login/callback', methods=['GET']) def login_user_callback(): token_url, headers, data = web_application_client.prepare_token_request( 'https://github.com/login/oauth/access_token', code=request.args['code'], client_id=os.getenv('CLIENT_ID'), client_secret=os.getenv('CLIENT_SECRET')) headers['Accept'] = 'application/json' response = requests.post(token_url, headers=headers, data=data) web_application_client.parse_request_body_response(response.text) access_token = web_application_client.token['access_token'] header = {'Authorization': f'Bearer {access_token}'} response = requests.get('https://api.github.com/user', headers=header).json() github_id = str(response['id']) query = {'github_id': github_id} db_user = users_collection.find_one(query) if (db_user) == None: if (users_collection.count_documents({}) == 0): user_role = 'admin' else: user_role = 'reader' post = { 'name': response['login'], 'github_id': github_id, 'user_role': user_role } users_collection.insert_one(post) db_user = users_collection.find_one(query) user = User(db_user['github_id'], db_user['name'], db_user['user_role']) login_user(user) return redirect('/') def is_writer(): return app.config[ 'LOGIN_DISABLED'] or current_user.user_role == 'writer' def is_admin(): return app.config['LOGIN_DISABLED'] or current_user.user_role == 'admin' @app.route('/') @login_required def index(): items = collection.find() cards = [] for item in items: cards.append( Item(item['_id'], item['name'], item['description'], item['due_date'].strftime('%d/%m/%Y'), item['status'])) item_view_model = ViewModel(cards) return render_template('index.html', view_model=item_view_model, is_writer=is_writer(), is_admin=is_admin()) @app.route('/create-todo/', methods=['POST']) def create_todo(): if not is_writer(): return redirect('/') title = request.form.get('title') desc = request.form.get('description') due = request.form.get('due-date') post = { 'name': title, 'description': desc, 'due_date': datetime.fromisoformat(due), 'status': todo_status } collection.insert_one(post) return redirect('/') @app.route('/todo/<id>', methods=['POST']) def to_do(id): if not is_writer(): return redirect('/') query = {'_id': ObjectId(id)} update_values = {'$set': {'status': todo_status}} collection.update_one(query, update_values) return redirect('/') @app.route('/doing/<id>', methods=['POST']) def doing(id): if not is_writer(): return redirect('/') query = {'_id': ObjectId(id)} update_values = {'$set': {'status': doing_status}} collection.update_one(query, update_values) return redirect('/') @app.route('/done/<id>', methods=['POST']) def done(id): if not is_writer(): return redirect('/') query = {'_id': ObjectId(id)} update_values = {'$set': {'status': done_status}} collection.update_one(query, update_values) return redirect('/') @app.route('/delete/<id>', methods=['POST']) def delete(id): if not is_writer(): return redirect('/') query = {'_id': ObjectId(id)} collection.delete_one(query) return redirect('/') @app.route('/users', methods=['GET']) def users(): db_users = users_collection.find() users = [] for item in db_users: user = User(item['github_id'], item['name'], item['user_role']) users.append(user) return render_template('users.html', users=users) @app.route('/update-user-role/<id>/<user_role>', methods=['POST']) def update_user_role(id, user_role): if not is_admin(): return redirect('/') query = {'github_id': id} update_values = {'$set': {'user_role': user_role}} users_collection.update_one(query, update_values) return redirect('/users') return app
def create_app(): app = Flask(__name__) CLIENT_ID = os.environ.get("GITHUB_CLIENT_ID", None) CLIENT_SECRET = os.environ.get("GITHUB_CLIENT_SECRET", None) SECRET_KEY = os.environ.get("SECRET_KEY", None) WRITER_ROLE = os.environ.get("ROLEWRITER_USER", None) redirect_uri = os.environ.get("GITHUB_REDIRECT_URI", None) app.secret_key = SECRET_KEY logger = app.logger logger.setLevel(os.environ.get("LOG_LEVEL", "INFO")) if os.environ.get("LOGGLY_TOKEN", "") != "": handler = HTTPSHandler( f'https://logs-01.loggly.com/inputs/{os.environ.get("LOGGLY_TOKEN")}/tag/todo-app' ) handler.setFormatter( Formatter( "[%(asctime)s] %(levelname)s in %(module)s: %(message)s")) app.logger.addHandler(handler) client = WebApplicationClient(CLIENT_ID) login_manager = LoginManager() login_manager.init_app(app) logger.debug("Created Application") @login_manager.unauthorized_handler def unauthenticated(): identity_url = client.prepare_request_uri( 'https://github.com/login/oauth/authorize', redirect_uri) app.logger.debug("Github authentication") return redirect(identity_url) @app.route("/login/callback") def callback(): try: app.logger.debug("Github callback start") code = request.args.get("code") token_url, headers, body = client.prepare_token_request( "https://github.com/login/oauth/access_token", authorization_response=request.url, redirect_url=request.base_url, code=code, ) token_response = requests.post( token_url, headers=headers, data=body, auth=(CLIENT_ID, CLIENT_SECRET), ) # Parse the tokens! params = client.parse_request_body_response(token_response.text) uri, headers, body = client.add_token( "https://api.github.com/user") userinfo_response = requests.get(uri, headers=headers, data=body) app.logger.debug("Github callback succeess") users_name = userinfo_response.json()["login"] users_id = userinfo_response.json()["id"] email = userinfo_response.json()["email"] user = User(users_id, users_name, email, ROLES['reader']) appsession['users_id'] = users_id appsession['users_name'] = users_name appsession['email'] = email if users_name == WRITER_ROLE: user.access = ROLES['writer'] else: user.access = ROLES['reader'] app.logger.info("Logged in user %s", users_name) app.logger.info("Logged in user email %s", email) app.logger.info("Logged in user role %s", user.access) appsession['roles'] = user.access login_user(user) return redirect(url_for('index')) except Exception as e: app.logger.error(str(e)) return "Could not authenticate user." @login_manager.user_loader def load_user(user_id): app.logger.debug("Creating user object") m_user_id = appsession.get('users_id') m_users_name = appsession.get('users_name') m_users_roles = appsession.get('roles') m_email = appsession.get('email') user = User(m_user_id, m_users_name, m_email, m_users_roles) return user @app.route('/') @login_required @requires_roles('reader', 'writer') def index(): app.logger.debug("Index start") items = session.Boards().get_items() item_view_model = session.ViewModel(items) if app.config.get("LOGIN_DISABLED", False): mcurrent_user = '' misWriter = True #for E2E testing else: mcurrent_user = current_user.username misWriter = (appsession.get('roles') == ROLES['writer']) app.logger.info("Is Writer %s", misWriter) app.logger.debug("Index end") return render_template('index.html', view_model=item_view_model, isWriter=misWriter, currentuser=mcurrent_user) @app.route('/', methods=['POST']) @login_required @requires_roles('writer') def add_item(): title = request.form.get('title') app.logger.info("Add Item %s", title) if title != '': session.Boards().add_item(title) app.logger.info("Item Successfully Added by %s", current_user.id) return redirect('/') @app.route('/<id>') @login_required @requires_roles('writer') def complete_item(id): if (id != "favicon.ico"): app.logger.info("Complete Item %s", id) todo_class = session.Boards() item = todo_class.get_item(id) item['status'] = "Completed" todo_class.save_item(item) app.logger.info("Item %s successfully Completed", id) return redirect('/') @app.route('/todo/<id>') @login_required @requires_roles('writer') def uncomplete_item(id): if (id != "favicon.ico"): app.logger.info("UnComplete Item %s", id) todo_class = session.Boards() item = todo_class.get_item(id) item['status'] = "Not Started" todo_class.save_item(item) app.logger.info("Item %s Set to unomplete.", id) return redirect('/') @app.route('/doing/<id>') @login_required @requires_roles('writer') def start_item(id): if (id != "favicon.ico"): app.logger.info("Start Item %s", id) todo_class = session.Boards() item = todo_class.get_item(id) item['status'] = "Doing" todo_class.save_item(item) app.logger.info("Item %s successfully Started.", id) return redirect('/') @app.route('/remove/<id>') @login_required @requires_roles('writer') def delete_item(id): app.logger.info("Remove Item %s", id) todo_class = session.Boards() todo_class.remove_item(id) app.logger.info("Item %s successfully Removed.", id) return redirect('/') return app
def create_app(): app = Flask(__name__) app.config.from_object('todo_app.flask_config.Config') app.logger.setLevel(app.config['LOG_LEVEL']) app.wsgi_app = ReverseProxied(app.wsgi_app) if app.config['LOGGLY_TOKEN'] is not None: handler = HTTPSHandler(f'https://logs-01.loggly.com/inputs/{app.config["LOGGLY_TOKEN"]}/tag/todo-app') formatter = jsonlogger.JsonFormatter("[%(asctime)s] %(levelname)s in %(module)s: %(message)s %(requesterIpAddr)s") handler.setFormatter(formatter) app.logger.addHandler(handler) client_id = os.environ['GITHUB_CLIENT_ID'] client_secret = os.environ['GITHUB_CLIENT_SECRET'] base_url="https://api.github.com" authorization_url="https://github.com/login/oauth/authorize" token_endpoint = "https://github.com/login/oauth/access_token" client = WebApplicationClient(client_id) todo = mongodb_todo() usermanager = MongoDbUserService() login_manager = LoginManager() login_manager.init_app(app) @app.errorhandler(Exception) def handle_error(e): app.logger.error('exception', extra={ "method": "{}".format(request.method), "requesterIpAddr": "{}".format(request.remote_addr), "url": "{}".format(request.url) }, exc_info=True) return render_template("error.html", error=str(e)) @app.after_request def after_request(response): app.logger.info("after_request", extra={ "method": "{}".format(request.method), "requesterIpAddr": "{}".format(request.remote_addr), "url": "{}".format(request.url), "status_code": "{}".format(response.status) }) return response @login_manager.user_loader def load_user(user_id): return UserToLogin(user_id) @login_manager.unauthorized_handler def unauthenticated(): app.logger.info("Unauthorized attemp made.", extra={ "method": "{}".format(request.method), "requesterIpAddr": "{}".format(request.remote_addr), "url": "{}".format(request.url) }) return redirect(url_for('login')) @app.route('/logout') @login_required def logout(): app.logger.info("User {} logged out of the system.".format(current_user.id), extra={ "method": "{}".format(request.method), "requesterIpAddr": "{}".format(request.remote_addr), "url": "{}".format(request.url) }) logout_user() session.clear() return redirect("https://github.com/logout") @app.route("/login") def login(): request_uri = client.prepare_request_uri( authorization_url, redirect_uri=request.base_url + "/callback", scope=None, ) return redirect(request_uri) @app.route("/login/callback") def callback(): code = request.args.get("code") app.logger.debug("{}".format(code), extra={ "method": "{}".format(request.method), "requesterIpAddr": "{}".format(request.remote_addr), "url": "{}".format(request.url) }) # Prepare and send request to get tokens! token_url, headers, body = client.prepare_token_request( token_endpoint, authorization_response=request.url, redirect_url=request.base_url, code=code, ) token_response = requests.post( token_url, headers=headers, data=body, auth=(client_id, client_secret), ) if token_response.status_code != 200: return redirect(url_for('login')) json_data = token_response.content.decode('utf8').replace("'", '"') # Parse the tokens! client.parse_request_body_response(json_data) userinfo_endpoint = "{}/user".format(base_url) uri, headers, body = client.add_token(userinfo_endpoint) userinfo_response = requests.get(uri, headers=headers, data=body) if userinfo_response.ok: account_info_json = userinfo_response.json() currentUserName = str(account_info_json['login']) login_user(UserToLogin(currentUserName)) app.logger.info("User logged in {}".format(current_user.id), extra={ "method": "{}".format(request.method), "requesterIpAddr": "{}".format(request.remote_addr), "url": "{}".format(request.url) }) if usermanager.get_totalusercount() == 0: usermanager.create_user(username=currentUserName,role="admin") app.logger.info("User logged in {} has been give admin level access.".format(current_user.id), extra={ "method": "{}".format(request.method), "requesterIpAddr": "{}".format(request.remote_addr), "url": "{}".format(request.url) }) if (usermanager.get_totalusercount() > 0) and (usermanager.get_findusercount(qry={"username": currentUserName}) == 0): usermanager.create_user(username=currentUserName,role="read") app.logger.info("User logged in {} has been give read level access.".format(current_user.id), extra={ "method": "{}".format(request.method), "requesterIpAddr": "{}".format(request.remote_addr), "url": "{}".format(request.url) }) return redirect(url_for('get_index')) @app.route('/', methods=['GET']) @login_required def sendhome(): return redirect(url_for('get_index')) ##### Core TODO_Tasks##### #error handling for 404 # @app.errorhandler(404) # def not_found(e): # return render_template("error.html", error='resource not found!') @app.route('/contact') def contact(): return render_template('contact.html') @app.route('/home', methods=['GET']) @login_required def get_index(): cardslist = [] items = todo.get_AllItems() if (app.config['LOGIN_DISABLED']): userRole = False else: userRole = usermanager.IsDisable() for item in items: cardslist.append(Card(item)) item_view_model = ViewModel(cardslist) return render_template('index.html', view_model=item_view_model, strRole=userRole) @app.route('/new', methods=['GET']) # New Task @login_required @usermanager.hasWritePermission def getnew_post(): return render_template('new_task.html') @app.route('/home', methods=['POST']) # New Task @login_required @usermanager.hasWritePermission def post_index(): response = todo.create_task( name = request.form['title'], due = request.form['duedate'], desc = request.form['descarea'] ) if response is not None: if current_app.config["LOGIN_DISABLED"]==False: app.logger.info("{} create new task".format(current_user.id), extra={ "method": "{}".format(request.method), "requesterIpAddr": "{}".format(request.remote_addr), "url": "{}".format(request.url), "data": "name: {} due: {} desc: {}".format(request.form['title'], str(request.form['duedate']), request.form['descarea']) }) return redirect('/home') else: return render_template("error.html",error="failed to create task!") @app.route('/edit/<id>', methods=['GET']) #Edit task @login_required @usermanager.hasWritePermission def get_edit(id): item = todo.get_task(id=id) if item is not None: item_info = Card(item) return render_template('edit.html', task=item_info) else: return render_template("error.html", error="failed to obtain task info!") @app.route('/edit/<id>', methods=['POST']) #Edit task @login_required @usermanager.hasWritePermission def post_edit(id): response= todo.update_task( id = id, name = request.form['title'], desc = request.form['descarea'], due = request.form['duedate'], status = request.form['status'] ) if response is not None: if current_app.config["LOGIN_DISABLED"]==False: app.logger.info("{} update task".format(current_user.id), extra={ "method": "{}".format(request.method), "requesterIpAddr": "{}".format(request.remote_addr), "url": "{}".format(request.url), "data": "id: {} name: {} due: {} desc: {} status: {}".format(id, request.form['title'], str(request.form['duedate']), request.form['descarea'], request.form['status']) }) return redirect('/home') else: return render_template("error.html", error="failed to update task!") @app.route('/delete/<id>') # delete task @login_required @usermanager.hasWritePermission def delete(id): response = todo.delete_task(id=id) if response is not None: if current_app.config["LOGIN_DISABLED"]==False: app.logger.info("{} deleted task".format(current_user.id), extra={ "method": "{}".format(request.method), "requesterIpAddr": "{}".format(request.remote_addr), "url": "{}".format(request.url), "data": "id: {}".format(id) }) return redirect('/home') else: return render_template("error.html",error="failed to delete task!") ### Additional views ### @app.route('/getpreviousdonetasks', methods=['GET']) @login_required def get_previous_done_tasks(): cardslist = [] items = todo.get_older_done_task() for item in items: cardslist.append(Card(item)) item_view_model = ViewModel(cardslist) userRole = usermanager.IsDisable() return render_template('previous_done_task.html', view_model=item_view_model, strRole=userRole) @app.route('/gettodaydonetasks', methods=['GET']) @login_required def get_today_done_tasks(): cardslist = [] items = todo.get_today_done_task() for item in items: cardslist.append(Card(item)) item_view_model = ViewModel(cardslist) userRole = usermanager.IsDisable() return render_template('today_done_task.html', view_model=item_view_model, strRole=userRole) ############# UserManagement ########################## @app.route('/usermanager', methods=['GET']) #portal @login_required @usermanager.hasRoleAdmin def get_usermanager(): user_list = [] items = usermanager.get_AllUsers() for item in items: user_list.append(User(item)) item_view_model = ViewModel(user_list) return render_template('userManager.html', view_model=item_view_model) @app.route('/edituser/<id>', methods=['GET']) #Edit user @login_required @usermanager.hasRoleAdmin def get_edituser(id): item = usermanager.get_user(id=id) if item is not None: item_info = User(item) return render_template('editUser.html', user=item_info) else: return render_template("error.html", error="failed to obtain user info!") @app.route('/edituser/<id>', methods=['POST']) #Edit user @login_required @usermanager.hasRoleAdmin def post_edituser(id): response = usermanager.update_user( id = id, username = request.form['username'], role = request.form['role'] ) if response is not None: app.logger.info("{} updated user permission".format(current_user.id), extra={ "method": "{}".format(request.method), "requesterIpAddr": "{}".format(request.remote_addr), "url": "{}".format(request.url), "data": "id: {} username: {} role: {}".format(id, request.form['username'], request.form['role']) }) return redirect('/usermanager') else: return render_template("error.html", error="failed to update user!") @app.route('/deleteuser/<id>') # delete user @login_required @usermanager.hasRoleAdmin def deleteuser(id): response = usermanager.delete_user(id=id) if response is not None: app.logger.info("{} deleted user".format(current_user.id), extra={ "method": "{}".format(request.method), "requesterIpAddr": "{}".format(request.remote_addr), "url": "{}".format(request.url), "data": "id: {}".format(id) }) return redirect('/usermanager') else: return render_template("error.html",error="failed to delete user!") ############################################### return app
def create_app(): """ Create the todo app Returns: app: The flask application. """ app = Flask(__name__) app.config.from_object('todo_app.flask_config.Config') app.config['LOGIN_DISABLED'] = os.getenv('LOGIN_DISABLED') == 'True' login_manager = LoginManager() oauth_client_id = os.environ['OAUTH_CLIENT_ID'] oauth_client_secret = os.environ['OAUTH_CLIENT_SECRET'] client = WebApplicationClient(oauth_client_id) @login_manager.unauthorized_handler def unauthenticated(): oauth_get_uri = client.prepare_request_uri( uri="https://github.com/login/oauth/authorize", state="todoapp") return redirect(oauth_get_uri, code=302) @login_manager.user_loader def load_user(user_id): return User(id=user_id, role=user_id_to_role.get(str(user_id), Role.READER)) login_manager.init_app(app) @app.route('/') @authorised_role(role=Role.READER) @login_required def index(): items = get_items() items_view_model = ItemsViewModel(items) return render_template('index.html', view_model=items_view_model, user=current_user, login_disabled=app.config['LOGIN_DISABLED']) @app.route('/login/callback') def login_callback(): code = request.args.get("code") post_token_request = client.prepare_token_request( "https://github.com/login/oauth/access_token", state="todoapp", client_id=oauth_client_id, client_secret=oauth_client_secret, code=code) (post_token_url, post_token_headers, post_token_body) = post_token_request post_token_headers["Accept"] = "application/json" token_response = requests.post(post_token_url, data=post_token_body, headers=post_token_headers) client.parse_request_body_response(token_response.text) (get_user_url, get_user_headers, _) = client.add_token("https://api.github.com/user") user_response = requests.get(get_user_url, headers=get_user_headers).json() user_id = user_response["id"] user = User(id=user_response["id"], role=user_id_to_role.get(user_id, Role.READER)) login_user(user) return redirect('/') @app.route('/todos', methods=['POST']) @authorised_role(role=Role.WRITER) @login_required def add_todo(): title = request.form.get('title') add_item(title) return redirect('/') @app.route('/todos/<id>', methods=['POST']) @authorised_role(role=Role.WRITER) @login_required def update_todo(id): status = request.form.get('status') item = get_item(id) item.status = ItemStatus.COMPLETE if status == 'COMPLETE' else ItemStatus.NOT_STARTED save_item(item) return redirect('/') @app.route('/todos/<id>/delete', methods=['POST']) @authorised_role(role=Role.WRITER) @login_required def remove_todo(id): delete_item(id) return redirect('/') return app
ip_ban = IpBan(ban_seconds=200) ip_ban.init_app(app) ip_ban.load_nuisances() ip_ban.ip_whitelist_add('1.223.233.222') ip_ban.ip_whitelist_add('172.18.0.4') ip_ban.url_pattern_add('/.env',match_type='string') CORS(app,resources={ r'*':{'origins':'*', 'methods' : '*', 'allow-headers':'*', 'supports_credentials':True } }) google_oauth = app.config['GOOGLE_OAUTH'] google_client = WebApplicationClient(google_oauth['client_id']) google_discovery_uri = "https://accounts.google.com/.well-known/openid-configuration" github_oauth = app.config['GITHUB_OAUTH'] github_client = WebApplicationClient(github_oauth['client_id']) from admin.model.mysql import User def init_login(): login_manager = LoginManager() login_manager.init_app(app) login_manager.session_protection='strong' @login_manager.user_loader def load_user(user_id): return db.session.query(User).get(user_id)
print("Required environment variables are not set. Exiting...") exit(0) logging.basicConfig(filename=config['PATH_TO_LOG_FILE'], level=logging.INFO, format=config['LOG_FORMAT']) LOGGER = logging.getLogger() LOGGER.info("All the environment variable required are set") # Flask app setup app = Flask(__name__) app.secret_key = os.environ.get("SECRET_KEY") or os.urandom(24) # OAuth 2 client setup CLIENT = WebApplicationClient(config['CLIENT_ID']) # -------------------------- ROUTES ------------------------------- @app.route("/") def home(): LOGGER.info("Home page accessed") return render_template('connect.html') @app.route("/login") def login(): LOGGER.info( "Client requested to connect to Xero. Fetching Xero request URL from Xero" ) request_uri = CLIENT.prepare_request_uri(
def create_oauth2_session(self): if self.auth_type != OAUTH2: raise ValueError( 'Auth type must be %r for credentials type OAuth2Credentials' % OAUTH2) has_token = False scope = ['https://outlook.office365.com/.default'] session_params = {} token_params = {} if isinstance(self.credentials, OAuth2AuthorizationCodeCredentials): # Ask for a refresh token scope.append('offline_access') # We don't know (or need) the Microsoft tenant ID. Use # common/ to let Microsoft select the appropriate tenant # for the provided authorization code or refresh token. # # Suppress looks-like-password warning from Bandit. token_url = 'https://login.microsoftonline.com/common/oauth2/v2.0/token' # nosec client_params = {} has_token = self.credentials.access_token is not None if has_token: session_params['token'] = self.credentials.access_token elif self.credentials.authorization_code is not None: token_params['code'] = self.credentials.authorization_code self.credentials.authorization_code = None if self.credentials.client_id is not None and self.credentials.client_secret is not None: # If we're given a client ID and secret, we have enough # to refresh access tokens ourselves. In other cases the # session will raise TokenExpiredError and we'll need to # ask the calling application to refresh the token (that # covers cases where the caller doesn't have access to # the client secret but is working with a service that # can provide it refreshed tokens on a limited basis). session_params.update({ 'auto_refresh_kwargs': { 'client_id': self.credentials.client_id, 'client_secret': self.credentials.client_secret, }, 'auto_refresh_url': token_url, 'token_updater': self.credentials.on_token_auto_refreshed, }) client = WebApplicationClient(self.credentials.client_id, **client_params) else: token_url = 'https://login.microsoftonline.com/%s/oauth2/v2.0/token' % self.credentials.tenant_id client = BackendApplicationClient( client_id=self.credentials.client_id) session = self.raw_session(self.service_endpoint, oauth2_client=client, oauth2_session_params=session_params) if not has_token: # Fetch the token explicitly -- it doesn't occur implicitly token = session.fetch_token( token_url=token_url, client_id=self.credentials.client_id, client_secret=self.credentials.client_secret, scope=scope, **token_params) # Allow the credentials object to update its copy of the new # token, and give the application an opportunity to cache it self.credentials.on_token_auto_refreshed(token) session.auth = get_auth_instance(auth_type=OAUTH2, client=client) return session
def get_google_client(): google_client_id = get_google_client_id() return WebApplicationClient(google_client_id)
def get_session(self, *, state=None, redirect_uri=None, load_token=False, scopes=None): """ Create a requests Session object :param str state: session-state identifier to rebuild OAuth session (CSRF protection) :param str redirect_uri: callback URL specified in previous requests :param list(str) scopes: list of scopes we require access to :param bool load_token: load and ensure token is present :return: A ready to use requests session, or a rebuilt in-flow session :rtype: OAuth2Session """ redirect_uri = redirect_uri or self.oauth_redirect_url client_id = self.auth[0] if self.auth_flow_type in ('authorization', 'public'): oauth_client = WebApplicationClient(client_id=client_id) elif self.auth_flow_type == 'credentials': oauth_client = BackendApplicationClient(client_id=client_id) else: raise ValueError( '"auth_flow_type" must be "authorization", "credentials" or "public"' ) requested_scopes = scopes or self.scopes if load_token: # gets a fresh token from the store token = self.token_backend.get_token() if token is None: raise RuntimeError( 'No auth token found. Authentication Flow needed') oauth_client.token = token if self.auth_flow_type in ('authorization', 'public'): requested_scopes = None # the scopes are already in the token (Not if type is backend) session = OAuth2Session(client_id=client_id, client=oauth_client, token=token, scope=requested_scopes) else: session = OAuth2Session(client_id=client_id, client=oauth_client, state=state, redirect_uri=redirect_uri, scope=requested_scopes) session.proxies = self.proxy if self.request_retries: retry = Retry(total=self.request_retries, read=self.request_retries, connect=self.request_retries, backoff_factor=RETRIES_BACKOFF_FACTOR, status_forcelist=RETRIES_STATUS_LIST) adapter = HTTPAdapter(max_retries=retry) session.mount('http://', adapter) session.mount('https://', adapter) return session
def test_prepare_request_body(self): """ see issue #585 https://github.com/oauthlib/oauthlib/issues/585 `prepare_request_body` should support the following scenarios: 1. Include client_id alone in the body (default) 2. Include client_id and client_secret in auth and not include them in the body (RFC preferred solution) 3. Include client_id and client_secret in the body (RFC alternative solution) 4. Include client_id in the body and an empty string for client_secret. """ client = WebApplicationClient(self.client_id) # scenario 1, default behavior to include `client_id` r1 = client.prepare_request_body() self.assertEqual( r1, 'grant_type=authorization_code&client_id=%s' % self.client_id) r1b = client.prepare_request_body(include_client_id=True) self.assertEqual( r1b, 'grant_type=authorization_code&client_id=%s' % self.client_id) # scenario 2, do not include `client_id` in the body, so it can be sent in auth. r2 = client.prepare_request_body(include_client_id=False) self.assertEqual(r2, 'grant_type=authorization_code') # scenario 3, Include client_id and client_secret in the body (RFC alternative solution) # the order of kwargs being appended is not guaranteed. for brevity, check the 2 permutations instead of sorting r3 = client.prepare_request_body(client_secret=self.client_secret) r3_params = dict(urlparse.parse_qsl(r3, keep_blank_values=True)) self.assertEqual(len(r3_params.keys()), 3) self.assertEqual(r3_params['grant_type'], 'authorization_code') self.assertEqual(r3_params['client_id'], self.client_id) self.assertEqual(r3_params['client_secret'], self.client_secret) r3b = client.prepare_request_body(include_client_id=True, client_secret=self.client_secret) r3b_params = dict(urlparse.parse_qsl(r3b, keep_blank_values=True)) self.assertEqual(len(r3b_params.keys()), 3) self.assertEqual(r3b_params['grant_type'], 'authorization_code') self.assertEqual(r3b_params['client_id'], self.client_id) self.assertEqual(r3b_params['client_secret'], self.client_secret) # scenario 4, `client_secret` is an empty string r4 = client.prepare_request_body(include_client_id=True, client_secret='') r4_params = dict(urlparse.parse_qsl(r4, keep_blank_values=True)) self.assertEqual(len(r4_params.keys()), 3) self.assertEqual(r4_params['grant_type'], 'authorization_code') self.assertEqual(r4_params['client_id'], self.client_id) self.assertEqual(r4_params['client_secret'], '') # scenario 4b, `client_secret` is `None` r4b = client.prepare_request_body(include_client_id=True, client_secret=None) r4b_params = dict(urlparse.parse_qsl(r4b, keep_blank_values=True)) self.assertEqual(len(r4b_params.keys()), 2) self.assertEqual(r4b_params['grant_type'], 'authorization_code') self.assertEqual(r4b_params['client_id'], self.client_id) # scenario Warnings with warnings.catch_warnings(record=True) as w: warnings.simplefilter("always") # catch all # warning1 - raise a DeprecationWarning if a `client_id` is submitted rWarnings1 = client.prepare_request_body(client_id=self.client_id) self.assertEqual(len(w), 1) self.assertIsInstance(w[0].message, DeprecationWarning) # testing the exact warning message in Python2&Python3 is a pain # scenario Exceptions # exception1 - raise a ValueError if the a different `client_id` is submitted with self.assertRaises(ValueError) as cm: client.prepare_request_body(client_id='different_client_id')
} cat_data = None current_user_email = "" # google configurations GOOGLE_CLIENT_ID = ( "161589307268-m2b3kcts5njij3fjlf8g94bov125c833.apps.googleusercontent.com" ) GOOGLE_CLIENT_SECRET = "tFsSYxOXbx6Qy5_dcSjI7rJl" GOOGLE_DISCOVERY_URL = "https://accounts.google.com/.well-known/openid-configuration" email_verified= False userinfo_response = json.dumps({}) client_google = WebApplicationClient(GOOGLE_CLIENT_ID) def get_google_provider_cfg(): return requests.get(GOOGLE_DISCOVERY_URL).json() @app.route("/loginGoogle") def login_google(): # takeout auth endpoint url from google login google_provider_cfg = get_google_provider_cfg() authorization_endpoint = google_provider_cfg["authorization_endpoint"] # construct the request uri request_uri = client_google.prepare_request_uri( authorization_endpoint, redirect_uri=request.base_url + "/callbackGoogle",
def get_client(): client = WebApplicationClient(mg_config['client_id']) return client
from flaskps.resources import auth from flask_cors import CORS from flask_jwt_extended import ( JWTManager, jwt_required, create_access_token, get_jwt_identity, ) from oauthlib.oauth2 import WebApplicationClient app = Flask(__name__) app.secret_key = Config.GOOGLE_CLIENT_SECRET # OAuth 2 client setup client = WebApplicationClient(Config.GOOGLE_CLIENT_ID) # Setup the Flask-JWT-Extended extension app.config["JWT_SECRET_KEY"] = "sdlkjhghsgfinjpjaSOJIdSFOJSAdKJFA1" app.config['CORS_HEADERS'] = 'Content-Type' CORS(app, resources={r"/api/*": {"origins": "*"}}) app.config.from_object(Config) jwt = JWTManager(app) app.config["SESSION_TYPE"] = "filesystem" Session(app) @app.route("/glogin") def glogin(): return auth.google_login(client)
# Creating the Flask app instance printColoured(" * Initialising Flask application") app = Flask(__name__) CORS(app) # ===== App Configuration ===== SECRET_KEY = os.getenv("SECRET_KEY") app.secret_key = SECRET_KEY GOOGLE_API_CLIENT_SECRET = os.getenv("GOOGLE_API_CLIENT_SECRET") GOOGLE_API_CLIENT_ID = os.getenv("GOOGLE_API_CLIENT_ID") GOOGLE_DISCOVERY_URL = ( "https://accounts.google.com/.well-known/openid-configuration") google_client = WebApplicationClient(GOOGLE_API_CLIENT_ID) # Registering the default error handler app.register_error_handler(Exception, error_handler) # Database connection parameters: client = pymongo.MongoClient( "mongodb+srv://teamgalactic:[email protected]/galacticed?retryWrites=true&w=majority" ) # Creating the database handler: db = client["galacticed"] # The routes must be imported after the Flask application object is created. See https://flask.palletsprojects.com/en/1.1.x/patterns/packages/ import GalacticEd.routes
def create_app(): app = Flask(__name__) app.config.from_object(Config()) logger = Logger(app.logger, app.config) todoapi = TodoAPI(app.config) users_db = UserDB(app.config) login_manager = LoginManager() client = WebApplicationClient(app.config.get('GITHUB_CLIENT_ID', '')) login_manager.init_app(app) @login_manager.unauthorized_handler def unauthenticated(): uri = client.prepare_request_uri('https://github.com/login/oauth/authorize') logger.warning("User %s is not authenticated" % current_user) return redirect(uri, code=302) @login_manager.user_loader def load_user(user_id): return get_user(user_id) # All the routes and setup code etc def is_permitted(role): return app.config.get('LOGIN_DISABLED', '') == 'True' or role in current_user.roles def logged_user(): if app.config.get('LOGIN_DISABLED', '') == 'True': return User({'login':'******', 'roles':['writer'], 'avatar':'/favicon.ico'}) return current_user def get_user(user_id): return users_db.get_user(user_id) def add_user(user_profile): default_roles = ['reader'] if len(users_db.get_list_of_users()) == 0: default_roles = ['admin'] users_db.add_user({**user_profile, 'roles': default_roles}) def render_index_response(): item_view_model = ViewModel(sorted(todoapi.get_list_of_items(), key=lambda item : (item.status, item.id)), logged_user(), app.config.get('ENV')) return render_template('index.html', view_model= item_view_model) def render_usersadmin_response(): useradmin_view_model = UserAdminViewModel(users_db.get_list_of_users(), current_user, app.config.get('ENV')) return render_template('useradmin.html', view_model= useradmin_view_model) @app.route('/login/callback', methods=['GET', 'POST']) def _callback(): code = request.values['code'] token_url, headers, body = client.prepare_token_request(token_url = 'https://github.com/login/oauth/access_token', code = code ) token_response = requests.post(token_url, headers=headers, data=body, auth=(app.config.get('GITHUB_CLIENT_ID'), app.config.get('GITHUB_CLIENT_SECRET')),) client.parse_request_body_response(token_response.text)['access_token'] userinfo_endpoint = 'https://api.github.com/user' uri, headers, body = client.add_token(userinfo_endpoint) userinfo_response = requests.get(uri, headers=headers, data=body) user_id = userinfo_response.json()['login'] if get_user(user_id) is None: add_user(userinfo_response.json()) user = get_user(user_id) login_user(user) logger.info("Logged user %s" % user_id) return redirect('/', code=302) @app.route('/useradmin', methods=['GET']) @login_required def _useradmin(): if not is_permitted('admin'): logger.warning("Unauthorised User %s attempted to access /useradmin" % current_user.id) return redirect('/', code=302) return render_usersadmin_response() @app.route('/usersetrole/<user_id>/<role>/<add_remove>', methods=['POST']) @login_required def _usersetrole(user_id,role,add_remove): if not is_permitted('admin'): logger.warning("Unauthorised User %s attempted to access /usersetrole" % current_user.id) return redirect('/', code=302) user = users_db.get_user(user_id) roles = user.roles if role in roles and add_remove == 'remove': roles.remove(role) elif role not in roles and add_remove == 'add': roles.append(role) else: pass logger.info("%s role: %s from user: %s" %(add_remove, role, user_id)) users_db.modify_roles(user_id,roles) return render_usersadmin_response() @app.route('/', methods=['GET']) @login_required def _index(): return render_index_response() @app.route('/add', methods=['POST']) @login_required def _add(): if is_permitted('writer'): logger.info("Adding task: %s " % request.form) todoapi.add_item(request.form) else: logger.warning("Unauthorised User %s attempted to access /add" % current_user.id) return render_index_response() @app.route('/setstatus/<task_id>/<status>', methods=['POST']) @login_required def _setstatus(task_id, status): if is_permitted('writer'): logger.info("Changing task %s to %s" % (task_id, status), {"task_id": task_id, "new_status":status}) todoapi.modify_item(task_id, {'status': status}) else: logger.warning("Unauthorised User %s attempted to access /setstatus" % current_user.id) return render_index_response() @app.route('/delete/<task_id>', methods=['POST']) @login_required def _delete(task_id): if is_permitted('writer'): logger.info("Deleting task %s" % task_id, {"task_id": task_id}) todoapi.delete_item(task_id) else: logger.warning("Unauthorised User %s attempted to access /delete" % current_user.id) return render_index_response() @app.template_filter('strftime') def _jinja2_filter_datetime(date): ''' Used for the conversion of dates from the API ''' try: date = parser.parse(date) native = date.replace(tzinfo=None) fmt = '%d %b %Y' return native.strftime(fmt) except: return '' return app
REMEMBER_COOKIE_DURATION = datetime.timedelta(days=365), GOOGLE_CLIENT_ID = os.getenv("GOOGLE_CLIENT_ID"), GOOGLE_CLIENT_SECRET = os.getenv("GOOGLE_CLIENT_SECRET"), GOOGLE_DISCOVERY_URL = os.getenv("GOOGLE_DISCOVERY_URL"), IMAGEKIT_PRIVATE_KEY = os.getenv("IMAGEKIT_PRIVATE_KEY"), IMAGEKIT_PUBLIC_KEY = os.getenv("IMAGEKIT_PUBLIC_KEY"), IMAGEKIT_URL_ENDPOINT = os.getenv("IMAGEKIT_URL_ENDPOINT") ) # User session management setup # https://flask-login.readthedocs.io/en/latest login_manager = LoginManager() login_manager.init_app(app) # OAuth 2 client setup client = WebApplicationClient(app.config['GOOGLE_CLIENT_ID']) # enable CORS CORS(app, resources={r'/*': {'origins': '*'}}) @app.errorhandler(404) def not_found(error): return make_response(jsonify({'error': 'Not found'}), 404) @app.errorhandler(400) def bad_request(error): return make_response(jsonify({'error': 'Bad request'}), 400) @app.route("/") def index():
def __init__(self): super(GoogleSignIn, self).__init__('google') self.client = WebApplicationClient(self.consumer_id)
from contentagregator.config import google_config app = Flask(__name__) app.debug=True app.config.from_object('contentagregator.config.DevelopmentConfig') db = SQLAlchemy(app) assets = Environment(app) migrate = Migrate(app, db) api = Api(app) jwt = JWTManager(app) mail = Mail(app) seeder = FlaskSeeder(app, db) lang = Language(app) client = WebApplicationClient(google_config['google_client_id']) # celery setup def make_celery(app): celery = Celery(app.import_name, backend=app.config['CELERY_RESULT_BACKEND'], broker=app.config['CELERY_BROKER_URL']) celery.conf.update(app.config) TaskBase = celery.Task class ContextTask(TaskBase): abstract = True def __call__(self, *args, **kwargs): with app.app_context(): return TaskBase.__call__(self, *args, **kwargs) celery.Task = ContextTask return celery
app.secret_key = os.urandom(24) APPLICATION_NAME = "Catalog Application" # disable check SSL os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' # Configuration GOOGLE_CLIENT_ID = os.environ.get( "GOOGLE_CLIENT_ID", "412392477818-2l5m7m1mvne5duo38lc6j0es5su0l55r.apps.googleusercontent.com") GOOGLE_CLIENT_SECRET = os.environ.get("GOOGLE_CLIENT_SECRET", "MCzBxSTbUGAM-ZWYP4sXh_Zd") GOOGLE_DISCOVERY_URL = ( "https://accounts.google.com/.well-known/openid-configuration") # OAuth 2 client setup client = WebApplicationClient(GOOGLE_CLIENT_ID) # Connect to Database and create database session # engine = create_engine('sqlite:///catalogdb.db', # connect_args={'check_same_thread': False}, # poolclass=StaticPool) engine = create_engine('postgresql://*****:*****@localhost/catalog') Base.metadata.bind = engine DBSession = sessionmaker(bind=engine) session = DBSession() # User Helper Functions def createUser(user):
def get(self, request, *args, **kwargs): # Retrieve these data from the URL data = self.request.GET code = data['code'] state = data['state'] print("code=%s, state=%s" % (code, state)) # For security purposes, verify that the # state information is the same as was passed # to github_login() if self.request.session['state'] != state: messages.add_message(self.request, messages.ERROR, "State information mismatch!") return HttpResponseRedirect(reverse('github:welcome')) else: del self.request.session['state'] # fetch the access token from GitHub's API at token_url token_url = 'https://github.com/login/oauth/access_token' client_id = settings.GITHUB_OAUTH_CLIENT_ID client_secret = settings.GITHUB_OAUTH_SECRET # Create a Web Applicantion Client from oauthlib client = WebApplicationClient(client_id) # Prepare body for request data = client.prepare_request_body( code=code, redirect_uri=settings.GITHUB_OAUTH_CALLBACK_URL, client_id=client_id, client_secret=client_secret) # Post a request at GitHub's token_url # Returns requests.Response object response = requests.post(token_url, data=data) """ Parse the unicode content of the response object Returns a dictionary stored in client.token { 'access_token': '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', 'scope': ['read:user'], 'token_type': 'bearer' } """ client.parse_request_body_response(response.text) # Prepare an Authorization header for GET request using the 'access_token' value # using GitHub's official API format header = { 'Authorization': 'token {}'.format(client.token['access_token']) } # Retrieve GitHub profile data # Send a GET request # Returns requests.Response object response = requests.get('https://api.github.com/user', headers=header) # Store profile data in JSON json_dict = response.json() ''' Fields that are of interest: 'login' => json_dict['login'], 'name' => json_dict['name'], 'bio' => json_dict['bio'], 'blog' => json_dict['blog'], 'email' => json_dict['email'], # not public data 'avatar_url' => json_dict['avatar_url'], ''' # save the user profile in a session self.request.session['profile'] = json_dict # retrieve or create a Django User for this profile try: user = User.objects.get(username=json_dict['login']) messages.add_message( self.request, messages.DEBUG, "User %s already exists, Authenticated? %s" % (user.username, user.is_authenticated)) print("User %s already exists, Authenticated %s" % (user.username, user.is_authenticated)) # remember to log the user into the system login(self.request, user) except: # create a Django User for this login user = User.objects.create_user(json_dict['login'], json_dict['email']) messages.add_message( self.request, messages.DEBUG, "User %s is created, Authenticated %s?" % (user.username, user.is_authenticated)) print("User %s is created, Authenticated %s" % (user.username, user.is_authenticated)) # remember to log the user into the system login(self.request, user) # Redirect response to hide the callback url in browser return HttpResponseRedirect(reverse('github:welcome'))