import logging from authlib.flask.client import OAuth from app import settings from .clients import Auth0Client, MockClient _logger = logging.getLogger(__name__) oauth_registry = OAuth() def init_app(app): global oauth_registry # Reinitialize the Oauth registry. # In tests for instance, the app module is imported once, thus the registry # kept its _clients and _registry values. oauth_registry = OAuth() oauth_registry.init_app(app) if settings.MOCK_OAUTH: _logger.info("MOCK_OAUTH set, using Mock oauth client.") oauth_registry.register(settings.OAUTH_CLIENT_NAME, client_cls=MockClient) else: if not settings.OAUTH_JWKS_URL: raise Exception("Please set OAUTH_JWKS_URL.") _logger.info("Registering Auth0 oauth client") oauth_registry.register( settings.OAUTH_CLIENT_NAME, client_id=settings.OAUTH_CLIENT_ID, client_secret=settings.OAUTH_CLIENT_SECRET, api_base_url=settings.OAUTH_BASE_URL, access_token_url=settings.OAUTH_BASE_URL + "/oauth/token",
@app.after_request def send_credentials_cookie(resp): token = oauth.google.token if not request.cookies.get("access_token") and token.get("access_token"): resp.set_cookie('access_token', token['access_token'], expires=token['expires_at'], httponly=True) resp.set_cookie('expires_at', str(token['expires_at']), httponly=True) if not session.get('user_id'): session['user_id'] = oauth.google.profile()['sub'] return resp oauth = OAuth(app, fetch_token=fetch_token) def handle_authorize(remote, token, user_info): if token: resp = redirect(url_for("upload")) resp.set_cookie('access_token', token['access_token'], max_age=token['expires_in'], httponly=True) resp.set_cookie('expires_at', str(token['expires_at']), httponly=True) resp.set_cookie('refresh_token', token['refresh_token'], httponly=True) session['user_id'] = user_info['sub'] return resp raise Unauthorized()
def init(app, db, config, base_prefix='/auth', root_uri='/', providers=['google', 'facebook', 'github'], smtp=None, fix_ssl=True): """ Initalize framework Args: app: Flask app db: pyaltt2.db.Database object config: configuration dict base_prefix: base prefix for auth urls root_uri: default next uri providers: oauth2 providers list smtp: pyaltt2.mail.SMTP object, required if email confirmations are used fix_ssl: force SSL everywhere (True by default) """ if not app.config.get('SECRET_KEY'): app.config['SECRET_KEY'] = gen_random_str() _d.x_prefix, _d.dot_prefix = _format_prefix(base_prefix) _d.db = db.clone(rq_func=rq) _d.kv = KVStorage(db=db, table_name='webauth_kv') _d.root_uri = root_uri _d.smtp = smtp if fix_ssl: from werkzeug.middleware.proxy_fix import ProxyFix app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1) def init_db(): from sqlalchemy import (MetaData, Table, Column, BigInteger, VARCHAR, JSON, CHAR, DateTime, ForeignKey, Index, Boolean, Numeric) meta = MetaData() user = Table( 'webauth_user', meta, Column('id', BigInteger(), primary_key=True, autoincrement=True), Column('email', VARCHAR(255), nullable=True, unique=True), Column('password', CHAR(64), nullable=True), Column('api_key', CHAR(32), nullable=True, unique=True), Index('webauth_user_api_key', 'api_key'), Column('d_created', DateTime(timezone=True), nullable=False), Column('d_active', DateTime(timezone=True), nullable=True), Column('confirmed', Boolean, nullable=False, server_default='0'), Column('otp', Numeric(1, 0), nullable=False, server_default='0'), Column('otp_secret', CHAR(16), nullable=True)) user_auth = Table( f'webauth_user_auth', meta, Column('id', BigInteger(), primary_key=True, autoincrement=True), Column('user_id', BigInteger(), ForeignKey('webauth_user.id', ondelete='CASCADE'), nullable=False), Index('webauth_user_auth_user_id', 'user_id'), Column('provider', VARCHAR(15), nullable=False), Column('sub', VARCHAR(255), nullable=False), Column('name', VARCHAR(255), nullable=True), Index('webauth_user_auth_sub_provider', 'sub', 'provider', unique=True)) user_log = Table( f'webauth_user_log', meta, Column('id', BigInteger(), primary_key=True, autoincrement=True), Column('user_id', BigInteger(), nullable=False), Index('webauth_user_log_user_id', 'user_id'), Column('d', DateTime(timezone=True), nullable=False), Column('event', VARCHAR(1024), nullable=False), Column('ip', VARCHAR(45), nullable=False)) meta.create_all(db.connect()) def handle_authorize(remote, token, user_info): if user_info: try: provider = remote if isinstance(remote, str) else remote.name user_id = _handle_user_auth(user_info, provider=provider) touch(user_id) session[f'{_d.x_prefix}user_id'] = user_id session[f'{_d.x_prefix}user_picture'] = user_info.picture session[f'{_d.x_prefix}user_name'] = _get_oauth_user_name( user_info, provider) session[f'{_d.x_prefix}user_confirmed'] = True _call_handler('account.login', user_id=user_id) _log_user_event(f'account.login:{provider}') return redirect(_next_uri()) except ResourceAlreadyExists: response = _call_handler('exception.provider_exists') return response if response else Response( 'oauth provider is already ' + 'registered for another account', status=409) except AccessDenied: response = _call_handler('exception.registration_denied') return response if response else Response( 'account registration is disabled', status=403) # session.permanent = True else: response = _call_handler('exception.provider_failed') return response if response else Response('forbidden', status=403) def google_login(): redirect_uri = url_for(f'{_d.dot_prefix}google.auth', _external=True) return oauth.google.authorize_redirect(redirect_uri) def google_auth(): token = oauth.google.authorize_access_token() user_info = oauth.google.parse_id_token(token) return handle_authorize('google', token, user_info) for k in config: app.config[k.upper().replace('-', '_')] = config_value(config=config, config_path=k) oauth = OAuth(app) app.add_url_rule(f'{base_prefix}/logout', f'{_d.dot_prefix}.logout', logout, methods=['GET']) app.add_url_rule(f'{base_prefix}/confirm/<key>', f'{_d.dot_prefix}confirm', handle_confirm, methods=['GET']) for p in providers: if p == 'google': oauth.register( 'google', server_metadata_url= 'https://accounts.google.com/.well-known/openid-configuration', client_kwargs={'scope': 'openid profile'}, ) app.add_url_rule(f'{base_prefix}/google/login', f'{_d.dot_prefix}google.login', google_login, methods=['GET']) app.add_url_rule(f'{base_prefix}/google/auth', f'{_d.dot_prefix}google.auth', google_auth, methods=['GET']) else: blueprint = loginpass.create_flask_blueprint( _provider_mod[p], oauth, handle_authorize) app.register_blueprint(blueprint, url_prefix=f'{base_prefix}/{p}') init_db() return
fh.setLevel(logging.INFO) fh.setFormatter(fmt) ch = logging.StreamHandler() ch.setLevel(logging.INFO) ch.setFormatter(fmt) log = logging.getLogger('notebook2') log.setLevel(logging.INFO) logging.basicConfig( handlers=[fh, ch], level=logging.INFO) app = Flask(__name__) sockets = Sockets(app) oauth = OAuth(app) scss_path = os.path.join(app.static_folder, 'styles') css_path = os.path.join(app.static_folder, 'css') os.makedirs(css_path, exist_ok=True) sass.compile(dirname=(scss_path, css_path), output_style='compressed') def read_string(f): with open(f, 'r') as f: return f.read().strip() # Must be int for Kubernetes V1 api timeout_seconds property KUBERNETES_TIMEOUT_IN_SECONDS = float(os.environ.get('KUBERNETES_TIMEOUT_IN_SECONDS', 5))
return Client(cluster, allow_reconnect=True) db = SQLAlchemy() mako = MakoTemplates() sockets = Sockets() rds = Redis.from_url(REDIS_URL) def fetch_token(name): token_session_key = '{}-token'.format(name.lower()) return session.get(token_session_key, {}) def update_token(name, token): token_session_key = '{}-token'.format(name.lower()) session[token_session_key] = token return token def delete_token(name=OAUTH_APP_NAME): token_session_key = '{}-token'.format(name.lower()) session.pop(token_session_key) oauth = OAuth(fetch_token=fetch_token, update_token=update_token) github.register_to(oauth) cache = Cache(config={'CACHE_TYPE': 'redis'}) sess = Session()
@app.route('/') def index(): return '<a href="/login">Login</a>' def update_token(token): session['token'] = token if __name__ == '__main__': app.secret_key = 'client' port, secret = sys.argv[1:] auth0 = OAuth(app).register( 'auth0', client_id=config.CLIENT_ID, client_secret=secret, api_base_url='https://sumana.auth0.com', access_token_url='https://sumana.auth0.com/oauth/token', refresh_token_url='https://sumana.auth0.com/oauth/token', authorize_url='https://sumana.auth0.com/authorize', grant_type='authorization_code', update_token=update_token, client_kwargs={ 'scope': 'openid profile offline_access read:balance read:cards add:balance delete:balance delete:cards', }, ) app.run(port=int(port), debug=True)
from flask import Flask, jsonify, redirect, request, send_from_directory, session, url_for from authlib.flask.client import OAuth from werkzeug.exceptions import HTTPException import psycopg2 # pylint: disable=invalid-name app = Flask(__name__, static_url_path='/build') app.secret_key = os.environ.get('FLASK_SECRET_KEY', 'development') logging.basicConfig(level=logging.INFO) rc = OAuth(app).register( 'Recurse Center', api_base_url='https://www.recurse.com/api/v1/', authorize_url='https://www.recurse.com/oauth/authorize', access_token_url='https://www.recurse.com/oauth/token', client_id=os.environ['CLIENT_ID'], client_secret=os.environ['CLIENT_SECRET'], ) connection = psycopg2.connect(os.environ['DATABASE_URL']) @app.route('/') def index(): "Get the single-page app HTML" return send_from_directory('build', 'index.html') @app.route('/static/<path:path>') def static_file(path): "Get the single-page app assets" return send_from_directory('build/static', path)
def setup(app, config): oauth = OAuth(app) domain = URL(config.domain) domain.scheme = "https" auth0 = oauth.register( "auth0", client_id=config.client.id, client_secret=config.client.secret, api_base_url=domain, access_token_url=domain + "oauth/token", authorize_url=domain + "authorize", client_kwargs={"scope": "openid profile"}, ) def requires_auth(f): @decorate(f) def decorated(*args, **kwargs): if PROFILE_KEY not in session: return redirect("/login") return f(*args, **kwargs) return decorated @register_thread def login(): output = auth0.authorize_redirect( redirect_uri=config.callback, audience=config.audience ) return output @register_thread def logout(): session.clear() return_url = url_for("home", _external=True) params = { "returnTo": return_url, "client_id": config.client.id, } return redirect(auth0.api_base_url + "/v2/logout?" + urlencode(params)) @register_thread def callback(): try: auth0.authorize_access_token() resp = auth0.get("userinfo") userinfo = resp.json() session[JWT_PAYLOAD] = userinfo session[PROFILE_KEY] = { "user_id": userinfo["sub"], "name": userinfo["name"], "picture": userinfo["picture"], } return redirect("/dashboard") except Exception as e: Log.warning("problem with callback {{url}}", url=request, cause=e) raise e return requires_auth, login, logout, callback
def init_webapp(config, test=False): """Initialize the web application. Initializes and configures the Flask web application. Call this method to make the web application and respective database engine usable. If initialized with `test=True` the application will use an in-memory SQLite database, and should be used for unit testing, but not much else. """ # Make app work with proxies (like nginx) that set proxy headers. app.wsgi_app = ProxyFix(app.wsgi_app) # logging.getLogger('flask_cors').level = logging.DEBUG # Note, this url namespace also exists for the Flask-Restless extension and # is where CRUD interfaces live, so be careful not to collide with model # names here. We could change this, but it's nice to have API live in the # same url namespace. app.register_blueprint(api, url_prefix='/api') # Initialize Flask configuration if test: app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite://' else: app.config['SQLALCHEMY_DATABASE_URI'] = config['webapp'][ 'database_uri'] # FIXME: Port these over to configobj. app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['SECRET_KEY'] = os.environ.get('SECRET_KEY', 'abc123') app.config['SECURITY_TOKEN_MAX_AGE'] = 60 app.config['SECURITY_TOKEN_AUTHENTICATION_HEADER'] = 'Auth-Token' app.config['SECURITY_PASSWORD_HASH'] = 'bcrypt' app.config['SECURITY_PASSWORD_SALT'] = os.environ.get('SALT', 'salt123') app.config['SECURITY_REGISTERABLE'] = True app.config['SECURITY_CONFIRMABLE'] = False app.config['SECURITY_SEND_REGISTER_EMAIL'] = False # This thing is a supreme PIA with API, and because we're using token based # authentication. app.config['WTF_CSRF_ENABLED'] = False # Initialize Flask-CORS CORS(app, supports_credentials=True) # CORS(app, supports_credentials=True, resources={r"/*": {"origins": "*"}}) # Initialize Flask-Bootstrap Bootstrap(app) # Initialize Flask-Security user_datastore = SQLAlchemyUserDatastore(db, User, Role) Security(app, user_datastore) app.config['GOOGLE_CLIENT_ID'] = os.environ.get('GOOGLE_CLIENT_ID', 'abc123') app.config['GOOGLE_CLIENT_SECRET'] = os.environ.get( 'GOOGLE_CLIENT_SECRET', 'password') app.config[ 'GOOGLE_REFRESH_TOKEN_URL'] = 'https://www.googleapis.com/oauth2/v4/token' app.config['GOOGLE_CLIENT_KWARGS'] = dict(scope=' '.join([ 'openid', 'https://www.googleapis.com/auth/userinfo.profile', 'https://www.googleapis.com/auth/calendar.readonly', ])) # Initialize Authlib. oauth = OAuth() oauth.init_app(app, fetch_token=authlib_fetch_token, update_token=authlib_update_token) google_blueprint = create_flask_blueprint(Google, oauth, authlib_handle_authorize) app.register_blueprint(google_blueprint, url_prefix='/google') # Save the oauth object in the app so handlers can use it to build clients. app.oauth = oauth # Initialize Flask-SQLAlchemy db.app = app db.init_app(app) # NOTE: You don't want to use this if you're using alembic, since alembic # is now in charge of creating/upgrading/downgrading your database. If you # choose to not use alembic, you can add this line here. # db.create_all() # Initialize Flask-Restless manager = APIManager( app, flask_sqlalchemy_db=db, preprocessors=dict(GET_MANY=[restless_api_auth_func]), ) # manager.create_api(TableName methods=['GET', 'POST', 'OPTIONS']) return app
def handle_auth_error(ex): """ Error handler for token related errors. Arguments: ex {[type]} -- [description] Returns: [type] -- [description] """ response = jsonify(ex.error) response.status_code = ex.status_code return response OAUTH = OAuth(APP) AUTH0 = OAUTH.register( "auth0", consumer_key=AUTH0_CLIENT_ID, consumer_secret=AUTH0_CLIENT_SECRET, request_token_params={ "scope": "openid profile email", "audience": AUTH0_AUDIENCE }, base_url="https://%s" % AUTH0_DOMAIN, access_token_method="POST", access_token_url="/oauth/token", authorize_url="/authorize", )
rc.hset("conf", 'gitlab_host', conf['gitlab']['host']) SSH_EXP_TIME = conf.get('ssh_expiration_time', 60 * 60 * 24) app = Flask(__name__) app.debug = True app.secret_key = 'development' def fetch_gitlab_token(): if not 'current_user' in session or not rc.exists("oauth:%s" % session['current_user']): return d = json.loads(rc.get("oauth:%s" % session['current_user']).decode('utf8')) return OAuth2Token.from_dict(d) oauth = OAuth(app, cache=rc) oauth.register('gitlab', api_base_url='https://%s/api/v4/' % conf['gitlab']['host'], request_token_url=None, access_token_url='https://%s/oauth/token' % conf['gitlab']['host'], authorize_url='https://%s/oauth/authorize' % conf['gitlab']['host'], access_token_method='POST', client_id=conf['gitlab']['consumer_key'], client_secret=conf['gitlab']['consumer_secret'], fetch_token=fetch_gitlab_token ) @app.route('/login') def login(): redirect_uri = url_for('authorize', _external=True)
class ids(): device_id = "" access_token = "" devicelist = {} # This keeps you logged in def update_token(name, token): if Users.token is not None: Users.token = None Users.token = token return Users.token logs = simple_logger.log_handling("Main", 'logs.log') oauth = OAuth(app, update_token=update_token) oauth.init_app(app) # This is initializing spotify api stuff oauth.register( 'spotify', client_id=spotify_id, client_secret=spotify_secret, api_base_url='https://api.spotify.com/v1/', access_token_url='https://accounts.spotify.com/api/token', authorize_url='https://accounts.spotify.com/authorize', client_kwargs={ 'scope': 'user-modify-playback-state user-read-currently-playing user-read-playback-state' }, )
__all__ = [ 'register_to', 'GitHub', 'OAUTH_BACKENDS', 'login', 'nonce_key', 'backend', 'remote', 'oauth', 'StackOverflow', 'login_aa', 'nonce_key_aa', 'backend_aa', 'remote_aa', 'oauth_aa', ] oauth = OAuth() backend = GitHub remote = register_to(backend, oauth, RemoteApp) nonce_key = '_{}:nonce'.format(backend.OAUTH_NAME) login = Blueprint('auth_' + backend.OAUTH_NAME, __name__) oauth_aa = OAuth() backend_aa = StackOverflow remote_aa = register_to(backend_aa, oauth_aa, RemoteApp) nonce_key_aa = '_{}:nonce'.format(backend_aa.OAUTH_NAME) login_aa = Blueprint('auth_' + backend_aa.OAUTH_NAME, __name__ + "_aa") from . import utils, _flask # noqa pylint: disable=wrong-import-position
def get(self, k): return self._data.get(k) def set(self, k, v, timeout=None): self._data[k] = v def delete(self, k): if k in self._data: del self._data[k] # Basic setup app = Flask(__name__) app.config.from_pyfile('config.py') bootstrap = Bootstrap(app) oauth = OAuth(app, Cache()) def handle_authorize(remote, token, user_info): app.logger.debug(user_info) user = market.lookup_user(host='GitHub', sub=user_info['sub'], username=user_info['preferred_username'], profile=user_info['profile']) session['host'] = user.host session['sub'] = user.sub where = session.get('destination') if where: del (session['destination']) return redirect(where) return redirect(url_for('index'))
def create_app(test_config=None): # create and configure the app app = Flask(__name__) app.secret_key = "super secret key" setup_db(app) # setup cross origin CORS(app) @app.after_request def after_request(response): response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization,true') response.headers.add('Access-Control-Allow-Methods', 'GET,PATCH,POST,DELETE,OPTIONS') return response oauth = OAuth(app) auth0 = oauth.register( 'auth0', client_id=AUTH0_CLIENT_ID, client_secret=AUTH0_CLIENT_SECRET, api_base_url=AUTH0_BASE_URL, access_token_url=AUTH0_BASE_URL + '/oauth/token', authorize_url=AUTH0_BASE_URL + '/authorize', client_kwargs={ 'scope': 'openid profile email', }, ) # Setup home route @app.route('/') def index(): return render_template('index.html') @app.route('/login') def login(): return auth0.authorize_redirect(redirect_uri=AUTH0_CALLBACK_URL, audience=AUTH0_AUDIENCE) @app.route('/callback') def callback_handling(): # Handles response from token endpoint res = auth0.authorize_access_token() token = res.get('access_token') # Store the user information in flask session. session['jwt_token'] = token return redirect('/dashboard') @app.route('/logout') def logout(): # Clear session stored data session.clear() # Redirect user to logout endpoint params = { 'returnTo': url_for('index', _external=True), 'client_id': AUTH0_CLIENT_ID } return redirect(auth0.api_base_url + '/v2/logout?' + urlencode(params)) @app.route('/dashboard') @requires_signed_in def dashboard(): return render_template( 'dashboard.html', token=session['jwt_token'], ) """Movies Routes""" # Route for getting all movies @app.route('/movies') @requires_auth('get:movies') def get_movies(jwt): """Get all movies route""" movies = Movie.query.all() return jsonify({ 'success': True, 'movies': [movie.format() for movie in movies], }), 200 # Route for getting a specific movie @app.route('/movies/<int:id>') @requires_auth('get:movies') def get_movie_by_id(jwt, id): """Get a specific movie route""" movie = Movie.query.get(id) # return 404 if there is no movie with id if movie is None: abort(404) else: return jsonify({ 'success': True, 'movie': movie.format(), }), 200 @app.route('/movies', methods=['POST']) @requires_auth('post:movies') def post_movie(jwt): """Create a movie route""" # Process request data data = request.get_json() title = data.get('title', None) release_date = data.get('release_date', None) # return 400 for empty title or release date if title is None or release_date is None: abort(400) movie = Movie(title=title, release_date=release_date) try: movie.insert() return jsonify({'success': True, 'movie': movie.format()}), 201 except Exception: abort(500) @app.route('/movies/<int:id>', methods=['PATCH']) @requires_auth('patch:movies') def patch_movie(jwt, id): """Update a movie route""" data = request.get_json() title = data.get('title', None) release_date = data.get('release_date', None) movie = Movie.query.get(id) if movie is None: abort(404) if title is None or release_date is None: abort(400) movie.title = title movie.release_date = release_date try: movie.update() return jsonify({'success': True, 'movie': movie.format()}), 200 except Exception: abort(500) @app.route('/movies/<int:id>', methods=['DELETE']) @requires_auth('delete:movies') def delete_movie(jwt, id): """Delete a movie route""" movie = Movie.query.get(id) if movie is None: abort(404) try: movie.delete() return jsonify({ 'success': True, 'message': f'movie id {movie.id}, titled {movie.title} was deleted', }) except Exception: db.session.rollback() abort(500) """Actors Routes""" @app.route('/actors') @requires_auth('get:actors') def get_actors(jwt): """Get all actors route""" actors = Actor.query.all() return jsonify({ 'success': True, 'actors': [actor.format() for actor in actors], }), 200 @app.route('/actors/<int:id>') @requires_auth('get:actors') def get_actor_by_id(jwt, id): """Get all actors route""" actor = Actor.query.get(id) if actor is None: abort(404) else: return jsonify({ 'success': True, 'actor': actor.format(), }), 200 @app.route('/actors', methods=['POST']) @requires_auth('post:actors') def post_actor(jwt): """Get all movies route""" data = request.get_json() name = data.get('name', None) age = data.get('age', None) gender = data.get('gender', None) actor = Actor(name=name, age=age, gender=gender) if name is None or age is None or gender is None: abort(400) try: actor.insert() return jsonify({'success': True, 'actor': actor.format()}), 201 except Exception: abort(500) @app.route('/actors/<int:id>', methods=['PATCH']) @requires_auth('patch:actors') def patch_actor(jwt, id): """Update an actor Route""" data = request.get_json() name = data.get('name', None) age = data.get('age', None) gender = data.get('gender', None) actor = Actor.query.get(id) if actor is None: abort(404) if name is None or age is None or gender is None: abort(400) actor.name = name actor.age = age actor.gender = gender try: actor.update() return jsonify({'success': True, 'actor': actor.format()}), 200 except Exception: abort(500) @app.route('/actors/<int:id>', methods=['DELETE']) @requires_auth('delete:actors') def delete_actor(jwt, id): """Delete an actor Route""" actor = Actor.query.get(id) if actor is None: abort(404) try: actor.delete() return jsonify({ 'success': True, 'message': f'actor id {actor.id}, named {actor.name} was deleted', }) except Exception: db.session.rollback() abort(500) # Error Handling @app.errorhandler(422) def unprocessable(error): return jsonify({ "success": False, "error": 422, "message": "unprocessable" }), 422 @app.errorhandler(404) def resource_not_found(error): return jsonify({ "success": False, "error": 404, "message": "resource not found" }), 404 @app.errorhandler(400) def bad_request(error): return jsonify({ "success": False, "error": 400, "message": "bad request" }), 400 @app.errorhandler(500) def internal_server_error(error): return jsonify({ "success": False, "error": 500, "message": "internal server error" }), 500 @app.errorhandler(AuthError) def handle_auth_error(exception): response = jsonify(exception.error) response.status_code = exception.status_code return response return app
def create_app(test_config=None): # When running locally, disable OAuthlib's HTTPs verification. # ACTION ITEM for developers: # When running in production *do not* leave this option enabled. os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' # create and configure the app app = Flask(__name__, instance_relative_config=True) app.config.from_mapping( # OVERRIDE WHEN DEPLOYING APP SECRET_KEY=constants.SECRET_KEY, ) app.debug = True if test_config is None: # load the instance config, if it exists, when not testing app.config.from_pyfile('config.py', silent=True) else: # load the test config if passed in app.config.from_mapping(test_config) # ensure the instance folder exists try: os.makedirs(app.instance_path) except OSError: pass oauth = OAuth(app) auth0 = oauth.register( 'auth0', client_id=auth.AUTH0_CLIENT_ID, client_secret=auth.AUTH0_CLIENT_SECRET, api_base_url=auth.AUTH0_BASE_URL, access_token_url=auth.AUTH0_BASE_URL + '/oauth/token', authorize_url=auth.AUTH0_BASE_URL + '/authorize', client_kwargs={ 'scope': 'openid profile', }, ) @app.errorhandler(Exception) def handle_auth_error(ex): return auth.handle_auth_error(ex) @app.route('/') def index(): if (session): authenticated = True else: authenticated = False return render_template('index.html', authenticated=authenticated) @app.route('/about') def about(): if (session): authenticated = True else: authenticated = False return render_template('about.html', authenticated=authenticated) @app.route('/contact') def contact(): if (session): authenticated = True else: authenticated = False return render_template('contact.html', authenticated=authenticated) @app.route('/home') def home_calendar(): start = calendar.get_start_of_week() end = calendar.get_next_month() timezone = 'America/New_York' usercalendar = calendar.get_calendar( session['jwt_payload']['sub'], start, end, timezone ) events = [] for event in usercalendar: id = 0 events.append({ 'id': id, 'start': event.starttime, 'end': event.endtime, }) id = id + 1 friends = database.get_friends(session['jwt_payload']['sub']) return render_template('homeCalendar.html', events=events, friends=friends) @app.route('/compare') def compare_calendar(): friendID = request.args.get('id') userID = session['jwt_payload']['sub'] start = calendar.get_start_of_week() end = calendar.get_next_month() timezone = 'America/New_York' compared_calendar = calendar.compare_user_calendars( userID, friendID, start, end, timezone ) events = [] for event in compared_calendar: id = 0 events.append({ 'id': id, 'start': event.starttime, 'end': event.endtime, 'rendering': 'background' }) id = id + 1 friends = database.get_friends(session['jwt_payload']['sub']) return render_template( 'compareCalendar.html', events=events, friends=friends, friendID=friendID, userID=userID ) @app.route('/addfriend') def add_friend(): email = request.args.get('email') database.create_friend(email) return redirect('/home') @app.route('/create_event') def create_event(): user1id = request.args.get('userID') user2id = request.args.get('friendID') summary = request.args.get('title') start = request.args.get('start') end = request.args.get('end') calendar.create_event( user1id, user2id, summary, '', start, end, 'America/New_York' ) return redirect('/home') @app.route('/callback') def callback_handling(): return auth.callback_handling(auth0) @app.route('/credentials') def load_credentials(): return auth.load_credentials() @app.route('/login') def login(): return auth.login(auth0) @app.route('/dashboard') @auth.requires_auth def dashboard(): return auth.dashboard() @app.route('/logout') def logout(): return auth.logout(auth0) @app.route('/webtest') def web_test(): start = "2019-04-22T19:56:40-04:00" end = "2019-05-22T19:56:40-04:00" timezone = "America/New_York" usercalendar = calendar.compare_user_calendars(session['jwt_payload']['sub'], session['jwt_payload']['sub'], start, end, timezone) freebusy_string = "" for event in usercalendar: freebusy_string += event.starttime + ' - ' + event.endtime + '<br />' return freebusy_string @app.route('/authorize') def authorize(): return calendar_auth.authorize() @app.route('/oauth2callback') def oauth2callback(): return calendar_auth.oauth2callback() @app.route('/revoke') def revoke(): return calendar_auth.revoke() @app.route('/clear') def clear_credentials(): return calendar_auth.clear_credentials() return app
def get_current_user(): user = g.get('current_user') if user: return user # retrieve login user by session sid = session.get(session_key_login) if not sid: return None user = User.query.get(sid) if user is None: logout() g.current_user = user return user def fetch_token(name): user = get_current_user() conn = Connect.query.filter_by(user_id=user.id, name=name).first() return conn.to_dict() oauth = OAuth(fetch_token=fetch_token) def init_app(app): oauth.init_app(app) register_apps(oauth, ['google'])
sys.exit() logging.info(var_name + ": " + value) return value # pylint: disable=invalid-name app = Flask(__name__, static_url_path='/build') app.secret_key = getEnvVar('FLASK_SECRET_KEY', 'development') logging.basicConfig(level=logging.INFO) rc = OAuth(app).register( 'Recurse Center', api_base_url='https://www.recurse.com/api/v1/', authorize_url='https://www.recurse.com/oauth/authorize', access_token_url='https://www.recurse.com/oauth/token', client_id=getEnvVar('CLIENT_ID'), client_secret=getEnvVar('CLIENT_SECRET'), ) connection = psycopg2.connect(getEnvVar('DATABASE_URL')) @app.route('/') def index(): "Get the single-page app HTML" return send_from_directory('build', 'index.html') @app.route('/static/<path:path>') def static_file(path):
def __init__(self, register, libraries, settings): print("Start OAuth 2.0 Server") app = Flask(__name__) oauth = OAuth(app) github_bp = create_flask_blueprint(GitHub, oauth, self.handle_authorize) app.register_blueprint(github_bp, url_prefix='/github')
g.current_user = user return user current_user = LocalProxy(get_current_user) def fetch_token(name): user = get_current_user() conn = Connect.query.filter_by(user_id=user.id, name=name).first() return conn.to_dict() def require_login(f): @wraps(f) def decorated(*args, **kwargs): if not current_user: url = url_for('account.login', next=request.path) return redirect(url) return f(*args, **kwargs) return decorated oauth = OAuth(cache=cache, fetch_token=fetch_token) def init_app(app): oauth.init_app(app) register_apps(oauth, [])
def create_flask_application(self): application = Flask(__name__) gzip = Gzip(application) application.log = {} application.killurl = str(uuid.uuid4()) application.jinja_env.add_extension('jinja2.ext.do') application.config.update( SESSION_TYPE='filesystem', PERMANENT_SESSION_LIFETIME=60*15, # 15 min SECRET_KEY=self.secret_key, GITHUB_CLIENT_ID=self.client_id, GITHUB_CLIENT_SECRET=self.client_secret, GITHUB_CLIENT_KWARGS = { 'scope': 'repo' } ) Session(application) oauth = OAuth(application) github_bp = create_flask_blueprint(GitHub, oauth, handle_authorize) application.register_blueprint(github_bp, url_prefix='/github') @application.template_filter('remove_terms', ) def remove_terms(content, repository_configuration, word_boundaries=True, whole_urls=True): """ remove the blacklisted terms from the content :param content: the content to anonymize :param repository_configuration: the configuration of the repository :return: the anonymized content """ repo = repository_configuration['repository'] if repo[-1] == '/': repo = repo[0:-1] content = re.compile("%s/blob/master" % repo, re.IGNORECASE).sub( "%s/repository/%s" % (self.public_url, repository_configuration["id"]), content) content = re.compile(repo, re.IGNORECASE).sub("%s/repository/%s" % (self.public_url, repository_configuration["id"]), content) for term in repository_configuration['terms']: if word_boundaries: regex = re.compile(r'\b%s\b' % term, re.IGNORECASE) else: regex = re.compile(term, re.IGNORECASE) if whole_urls: def sub_url(m): if regex.search(m.group(0)): return 'XXX' return m.group(0) url_regex = re.compile('\\b((https?|ftp|file)://)[-A-Za-z0-9+&@#/%?=~_|!:,.;]+[-A-Za-z0-9+&@#/%=~_|]\\b') content = url_regex.sub(sub_url, content) content = regex.sub("XXX", content) return content @application.template_filter('file_render', ) def file_render(file, repository_configuration): """ produce the html representation of a file :param file: the file to display :param repository_configuration: the configuration of the repository :return: the html representation of the file """ if type(file) == github.Commit.Commit: return Markup(remove_terms(render_template('patch.html', patch=file), repository_configuration)) if file.type == 'dir': return "" if file.size > 1000000: return Markup("The file %s is too big to be anonymized (beyond 1MB, Github limit)" % (file.name)) if ".md" in file.name or file.name == file.name.upper() or "changelog" == file.name.lower(): gh = self.github if 'token' in repository_configuration and repository_configuration['token'] is not None: gh = github.Github(repository_configuration['token']) return Markup("<div class='markdown-body'>%s</div>" % remove_terms( gh.render_markdown(file.decoded_content.decode('utf-8')), repository_configuration)) if ".jpg" in file.name or ".png" in file.name or ".png" in file.name or ".gif" in file.name: index = file.name.index('.') file_extension = file.name[index + 1:] return Markup("<img src='data:image/%s;base64, %s' alt='%s'>" % (file_extension, file.content, file.name)) if istext(file.decoded_content): return Markup("<pre><code>{}</code></pre>")\ .format(Markup.escape(remove_terms(file.decoded_content.decode("utf-8"), repository_configuration))) return Markup("<b>%s has an unknown extension, we are unable to anonymize it (known extensions md/txt/json/java/...)</b>" % (file.name)) @application.route('/' + application.killurl, methods=['POST']) def seriouslykill(): func = request.environ.get('werkzeug.server.shutdown') func() return "Shutting down..." def get_element_from_path(g_repo, g_commit, path): """ get a github element from its path :param g_repo: the github repository :param path: the path of the element :return: the element """ if path == '': return g_repo.get_contents('', g_commit.sha), None current_element = os.path.basename(path) folder_content = g_repo.get_contents(quote(os.path.dirname(path)), g_commit.sha) for file in folder_content: if file.name == current_element: return file, folder_content return None, folder_content @application.route('/myrepo', methods=['GET']) def myrepo(): user = session.get('user', None) if user is None or 'token' not in user or user['token'] is None: return redirect('github/login') g = github.Github(user['token']['access_token']) repos = g.get_user().get_repos(sort="full_name") for repo in repos: repo.uuid = str(uuid.uuid4()) return render_template('newrepo.html', repos=repos) @application.route('/repository/<id>/commit/<sha>', methods=['GET']) def commit(id, sha): """ display anonymously a commit from the repository :param id: the repository id :param sha: the commit id """ config_path = self.config_dir + "/" + str(id) + "/config.json" if not os.path.exists(config_path): return render_template('404.html'), 404 with open(config_path) as f: data = json.load(f, object_hook=json_util.object_hook) (username, repo, branch) = clean_github_repository(data['repository']) gh = self.github if 'token' in data: gh = github.Github(data['token']) g_repo = gh.get_repo("%s/%s" % (username, repo)) commit = g_repo.get_commit(sha) return render_template('repo.html', repository=data, current_repository=id, current_file=commit, files=[], path=[]) def is_up_to_date(repository_config, g_commit): """ check is the cache is up to date :param repository_config: the repository configuration :param g_commit: the Github commit :return: True if the cache is up to date """ commit_date = datetime.strptime(g_commit.last_modified, "%a, %d %b %Y %H:%M:%S %Z") return 'pushed_at' in repository_config and commit_date.strftime("%s") == repository_config["pushed_at"] def get_type_content(file_name, path, repository_configuration, g_repo, is_website): """ Get the content type of a file from its extension :param file_name: the filename :param path: the path of the file :param repository_configuration: the repository configuration :param g_repo: the Github repository :return: the content type """ if is_website: content_type = 'text/plain; charset=utf-8' if ".html" in file_name: content_type = 'text/html; charset=utf-8' if ".md" in file_name or file_name == file_name.upper(): content_type = 'text/html; charset=utf-8' if ".jpg" in file_name \ or ".png" in file_name \ or ".gif" in file_name: content_type = 'image/jpeg' if ".png" in file_name: content_type = 'image/png' elif ".gif" in file_name: content_type = 'image/gif' if ".txt" in file_name \ or ".log" in file_name \ or ".csv" in file_name \ or ".xml" in file_name \ or ".json" in file_name \ or ".java" in file_name \ or ".py" in file_name \ or ".lua" in file_name \ or ".js" in file_name: content_type = 'text/plain; charset=utf-8' if ".xml" in file_name: content_type = 'application/xml; charset=utf-8' elif ".json" in file_name: content_type = 'application/json; charset=utf-8' elif ".js" in file_name: content_type = 'application/javascript; charset=utf-8' if ".css" in file_name: content_type = 'text/css; charset=utf-8' return content_type return 'text/html; charset=utf-8' def get_content(current_file, files, path, repository_config, g_repo): """ get the content if the page :param current_file: the current file :param files: the list of file of the current directory :param path: the accessed path :param repository_config: the repository configuration :param g_repo: the Github repository :return: the content of the page """ cache_path = os.path.join(self.config_dir, repository_config['id'], "cache") file_path = path if current_file is not None: if current_file.type == 'dir': file_path = os.path.join(current_file.path, "index.html") else: file_path = current_file.path cached_file_path = os.path.join(cache_path, file_path) content_type = get_type_content(path, path, repository_config, g_repo, False).replace("; charset=utf-8", "") if os.path.exists(cached_file_path): return send_from_directory(os.path.dirname(cached_file_path), os.path.basename(cached_file_path), mimetype=content_type) content = '' if current_file.type != 'dir' and is_website(path, repository_config, g_repo): if current_file.size > 1000000: blob = g_repo.get_git_blob(current_file.sha) if blob.encoding == 'base64': content = base64.b64decode(blob.content).decode('utf-8') else: content = blob.content.decode('utf-8') else: content = current_file.decoded_content.decode('utf-8') if "text" in content_type: content = remove_terms(content, repository_config) if ".md" in current_file.name: gh = self.github if 'token' in repository_config: gh = github.Github(repository_config['token']) content = remove_terms(gh.render_markdown(content), repository_config) else: tree = files if type(tree) != list: tree = files.tree content = render_template('repo.html', repository=repository_config, current_repository=repository_config['id'], current_file=current_file, files=tree, path_directory=path if type( current_file) is not github.ContentFile.ContentFile or current_file.type == 'dir' else os.path.dirname( current_file.path), path=path.split("/") if path != '' else []) content_cache_path = cached_file_path if not os.path.exists(os.path.dirname(content_cache_path)): os.makedirs(os.path.dirname(content_cache_path)) with open(content_cache_path, 'w') as f: if type(content) == str: f.write(content) else: f.write(content.encode('utf8')) return content def is_website(path, repository_config, g_repo): """ Check if the current request is a request to a GitHub pages :param path: the current path :param repository_config: the repository configuration :param g_repo: the Github repository :return: True if the current path is a website """ return path[:4] == "docs" def is_default_file(f): default_name = ["readme", "index"] for name in default_name: try: if type(f) is github.ContentFile.ContentFile: f.name.lower().index(name) elif type(f) is github.GitTreeElement.GitTreeElement: f.path.lower().index(name) return True except ValueError: continue return False def get_current_folder_files(path, current_file, repository_config, g_repo, g_commit): """ get the list of files of the current repository :param path: the path to the current file :param current_file: the current file :param repository_config: the repository configuration :param g_repo: the GitHub repository :return: the list of file of the current repository """ files = [] if current_file is None: return files, current_file if type(current_file) is not github.ContentFile.ContentFile: files = g_repo.get_git_tree(g_commit.sha) for f in current_file: if is_default_file(f): current_file = f break if type(current_file) is not github.ContentFile.ContentFile: current_file = current_file[0] elif current_file.type == 'file': if os.path.dirname(path) == '': files = g_repo.get_git_tree(g_commit.sha) else: f, folder = get_element_from_path(g_repo, g_commit, os.path.dirname(path)) if f is None: files = folder else: files = g_repo.get_git_tree(f.sha) else: files = g_repo.get_git_tree(current_file.sha) for f in files.tree: if is_default_file(f): current_file, folder = get_element_from_path(g_repo, g_commit, os.path.join(path, f.path)) break if len(files.tree) == 1 and type(files.tree[0]) is github.ContentFile.ContentFile: current_file, folder = get_element_from_path(g_repo, g_commit, os.path.join(path, files.tree[0].path)) return files, current_file @application.route('/repository/<id>', methods=['GET'], defaults={'path': ''}) @application.route('/repository/<id>/', methods=['GET'], defaults={'path': ''}) @application.route('/repository/<id>/<path:path>', methods=['GET']) @application.route('/r/<id>', methods=['GET'], defaults={'path': ''}) @application.route('/r/<id>/', methods=['GET'], defaults={'path': ''}) @application.route('/r/<id>/<path:path>', methods=['GET']) def repository(id, path): repo_path = self.config_dir + "/" + str(id) config_path = repo_path + "/config.json" if not os.path.exists(config_path): return render_template('404.html'), 404 with open(config_path, 'r') as f: repository_configuration = json.load(f, object_hook=json_util.object_hook) if 'expiration_date' in repository_configuration and repository_configuration['expiration_date'] is not None: if repository_configuration['expiration_date'] <= datetime.now(repository_configuration['expiration_date'].tzinfo): if repository_configuration['expiration'] == 'redirect': return redirect(repository_configuration['repository']) elif repository_configuration['expiration'] == 'remove': return render_template('404.html'), 404 (username, repo, branch) = clean_github_repository(repository_configuration['repository']) gh = self.github if 'token' in repository_configuration and repository_configuration['token'] is not None: gh = github.Github(repository_configuration['token']) g_commit = None try: g_repo = gh.get_repo("%s/%s" % (username, repo)) if branch is None: branch = g_repo.default_branch g_commit = g_repo.get_commit(branch) except: return render_template('empty.html'), 404 if not is_up_to_date(repository_configuration, g_commit): if os.path.exists(os.path.join(repo_path, "cache")): shutil.rmtree(os.path.join(repo_path, "cache")) commit_date = datetime.strptime(g_commit.last_modified, "%a, %d %b %Y %H:%M:%S %Z") repository_configuration["pushed_at"] = commit_date.strftime("%s") with open(config_path, 'w') as fa: json.dump(repository_configuration, fa, default=json_util.default) cache_path = os.path.join(self.config_dir, id, "cache") if os.path.isfile(os.path.join(cache_path, path)): return send_from_directory(os.path.dirname(os.path.join(cache_path, path)), os.path.basename(os.path.join(cache_path, path)), mimetype=get_type_content(path, path, repository_configuration, g_repo, is_website(path, repository_configuration, g_repo)).replace("; charset=utf-8", "")) elif os.path.exists(os.path.join(cache_path, path, "index.html")): return send_from_directory(os.path.join(cache_path, path), "index.html", mimetype='text/html') elif os.path.exists(os.path.join(cache_path, path, "README.md")): return send_from_directory(os.path.join(cache_path, path), "README.md", mimetype='text/html') clean_path = path if len(clean_path) > 0 and clean_path[-1] == '/': clean_path = clean_path[0:-1] current_file, files = get_element_from_path(g_repo, g_commit, clean_path) if current_file is None: return render_template('404.html'), 404 if type(current_file) == github.ContentFile.ContentFile and current_file.type == 'dir' and len(path) > 0 and path[-1] != '/': return redirect(url_for('repository', id=id, path=path + '/')) files, current_file = get_current_folder_files(clean_path, current_file, repository_configuration, g_repo, g_commit) content = get_content(current_file, files, clean_path, repository_configuration, g_repo) content_type = get_type_content(current_file.name, clean_path, repository_configuration, g_repo, False) return content, {'Content-Type': content_type} @application.route('/', methods=['GET']) def index(): id = request.args.get('id', None) repo_name = clean_github_repository(request.args.get('githubRepository', None)) repo = None if id is not None: config_path = self.config_dir + "/" + id + "/config.json" if os.path.exists(config_path): with open(config_path) as f: data = json.load(f, object_hook=json_util.object_hook) if repo_name == clean_github_repository(data['repository']): repo = data return render_template('index.html', repo=repo) @application.route('/robots.txt') def robots(): return application.send_static_file('robots.txt') @application.route('/', methods=['POST']) def add_repository(): id = request.args.get('id', str(uuid.uuid4())) config_path = os.path.join(self.config_dir, str(id)) repo = request.form['githubRepository'] terms = request.form['terms'] expiration_date = None expiration = None if 'expiration' in request.form: expiration = request.form['expiration'] if 'expiration_date' in request.form and request.form['expiration_date'] != '': expiration_date = datetime.strptime(request.form['expiration_date'], '%Y-%m-%d') user = session.get('user', None) token = None if os.path.exists(config_path): with open(os.path.join(config_path, "config.json"), 'r') as r: data = json.load(r) if 'token' in data: token = data['token'] if token is None and user is not None and 'token' in user and user['token'] is not None: token = user['token']['access_token'] if not os.path.exists(config_path): os.mkdir(config_path) with open(config_path + "/config.json", 'w') as outfile: json.dump({ "id": id, "repository": repo, "terms": terms.splitlines(), "token": token, "expiration_date": expiration_date, "expiration": expiration }, outfile, default=json_util.default) return redirect(url_for('repository', id=id)) return application
def __init__(self): self.clients = set() self._authlib_clients = OAuth()
from authlib.flask.client import OAuth import config import os if os.getenv('FLASK_ENV') == 'production': config = eval("config.ProductionConfig") else: config = eval("config.DevelopmentConfig") oauth = OAuth() #generating new instance of oauth class oauth.register('google', client_id=config.GOOGLE_CLIENT_ID, client_secret=config.GOOGLE_CLIENT_SECRET, access_token_url='https://accounts.google.com/o/oauth2/token', access_token_params=None, refresh_token_url=None, authorize_url='https://accounts.google.com/o/oauth2/auth', api_base_url='https://www.googleapis.com/oauth2/v1/', client_kwargs={ 'scope': 'https://www.googleapis.com/auth/userinfo.email', 'token_endpoint_auth_method': 'client_secret_basic', 'token_placement': 'header', 'prompt': 'consent' })
def create_app(test_config=None): app = Flask(__name__) setup_db(app) CORS(app) @app.after_request def after_request(response): response.headers.add('Access-Control-Allow-Headers', 'Content-Type,Authorization,true') response.headers.add('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE, OPTIONS') return response # taken from auth0 website instructions oauth = OAuth(app) auth0 = oauth.register( 'auth0', client_id=AUTH0_CLIENT_ID, client_secret=AUTH0_CLIENT_SECRET, api_base_url=AUTH0_BASE_URL, access_token_url=AUTH0_BASE_URL + '/oauth/token', authorize_url=AUTH0_BASE_URL + '/authorize', client_kwargs={ 'scope': 'openid profile email', }, ) # taken from instructions at auth0 @app.route('/') def index(): return 'Healthy app' # Route for getting all shows @app.route('/shows') @requires_auth('get:shows') def get_shows(jwt): """Get all shows route""" try: shows = Show.query.all() return jsonify({ 'success': True, 'shows': [show.format() for show in shows], }), 200 except BaseException: abort(404) # Route for getting a specific show @app.route('/shows/<int:id>') @requires_auth('get:shows') def get_show_by_id(jwt, id): """Get a specific show route""" try: show = Show.query.get(id) # return 404 if there is no show with id if show is None: abort(400) else: return jsonify({ 'success': True, 'show': show.format(), }), 200 except BaseException: abort(404) @app.route('/shows', methods=['POST']) @requires_auth('post:shows') def post_show(jwt): """Create a show route""" # Process request data data = request.get_json() show_name = data.get('show_name', None) show_date = data.get('show_date', None) # return 400 for empty show_name or show date if show_name is None or show_date is None: abort(400) show = Show(show_name=show_name, show_date=show_date) try: show.insert() return jsonify({'success': True, 'show': show.format()}), 200 except BaseException: abort(404) @app.route('/shows/<int:id>', methods=['PATCH']) @requires_auth('patch:shows') def patch_show(jwt, id): """Update a show route""" data = request.get_json() show_name = data.get('show_name', None) show_date = data.get('show_date', None) show = Show.query.get(id) if show: if show is None: abort(400) if show_name is None or show_date is None: abort(400) show.show_name = show_name show.show_date = show_date try: show.update() return jsonify({'success': True, 'show': show.format()}), 200 except BaseException: abort(422) else: abort(404) @app.route('/shows/<int:id>', methods=['DELETE']) @requires_auth('delete:shows') def delete_show(jwt, id): """Delete a show route""" show = Show.query.get(id) if show: if show is None: abort(400) try: show.delete() return jsonify({ 'success': True, 'message': f'show id {show.id}, show named {show.show_name} was deleted', }) except BaseException: db.session.rollback() abort(422) else: abort(404) @app.route('/magicians') @requires_auth('get:magicians') def get_magicians(jwt): """Get all magicians route""" try: magicians = Magician.query.all() return jsonify({ 'success': True, 'magicians': [magician.format() for magician in magicians], }), 200 except BaseException: abort(404) @app.route('/magicians/<int:id>') @requires_auth('get:magicians') def get_magician_by_id(jwt, id): """Get all magicians route""" magician = Magician.query.get(id) try: if magician is None: abort(404) else: return jsonify({ 'success': True, 'magician': magician.format(), }), 200 except BaseException: abort(404) @app.route('/magicians', methods=['POST']) @requires_auth('post:magicians') def post_magician(jwt): """Get all shows route""" data = request.get_json() name = data.get('name', None) age = data.get('age', None) gender = data.get('gender', None) magician = Magician(name=name, age=age, gender=gender) if name is None or age is None or gender is None: abort(400) try: magician.insert() return jsonify({ 'success': True, 'magician': magician.format() }), 200 except BaseException: abort(422) @app.route('/magicians/<int:id>', methods=['PATCH']) @requires_auth('patch:magicians') def patch_magician(jwt, id): """Update an magician Route""" data = request.get_json() name = data.get('name', None) age = data.get('age', None) gender = data.get('gender', None) magician = Magician.query.get(id) if magician: if magician is None: abort(400) if name is None or age is None or gender is None: abort(400) magician.name = name magician.age = age magician.gender = gender try: magician.update() return jsonify({ 'success': True, 'magician': magician.format() }), 200 except BaseException: abort(422) else: abort(404) @app.route('/magicians/<int:id>', methods=['DELETE']) @requires_auth('delete:magicians') def delete_magician(jwt, id): """Delete an magician Route""" magician = Magician.query.get(id) if magician: if magician is None: abort(404) try: magician.delete() return jsonify({ 'success': True, 'message': f'magician id {magician.id}, named {magician.name} was deleted', }) except BaseException: db.session.rollback() abort(422) else: abort(404) # Error Handling @app.errorhandler(422) def unprocessable(error): return jsonify({ "success": False, "error": 422, "message": "unprocessable" }), 422 @app.errorhandler(404) def resource_not_found(error): return jsonify({ "success": False, "error": 404, "message": "resource not found" }), 404 @app.errorhandler(400) def bad_request(error): return jsonify({ "success": False, "error": 400, "message": "bad request" }), 400 @app.errorhandler(500) def internal_server_error(error): return jsonify({ "success": False, "error": 500, "message": "internal server error" }), 500 @app.errorhandler(AuthError) def handle_auth_error(exception): response = jsonify(exception.error) response.status_code = exception.status_code return response return app
app = Flask(__name__.split()[0], instance_relative_config='NO_INSTANCE_CONFIG' not in os.environ) # Loads configuration information from config.py and instance/config.py app.config.from_object('config') if 'NO_INSTANCE_CONFIG' not in os.environ: app.config.from_pyfile('config.py') celery = Celery(app.name, broker=app.config['CELERY_BROKER_URL']) celery.conf.update(app.config) # Enable authentication if configured. oauth = None # pylint: disable=C0103 if app.config.get('WATERAUTH_AUTHORIZE_URL'): oauth = OAuth(app) # pylint: disable=C0103 oauth.register( 'waterauth', client_kwargs={'verify': app.config.get('VERIFY_CERT', True)}) if app.config.get('LOGGING_ENABLED'): log_directory = app.config.get('LOGGING_DIRECTORY') loglevel = app.config.get('LOGGING_LEVEL') handler = _create_log_handler(log_directory) # Do not set logging level in the handler. # Otherwise, if Flask's DEBUG is set to False, # all logging will be disabled. # Instead, set the level in the logger object. app.logger.setLevel(loglevel) app.logger.addHandler(handler) # celery uses two loggers: one global/worker logger and a second task logger
from authlib.flask.client import OAuth import config import os if os.getenv('FLASK_ENV') == 'production': config = eval("config.ProductionConfig") else: config = eval("config.DevelopmentConfig") oauth = OAuth() oauth.register('google', client_id=config.GOOGLE_CLIENT_ID, client_secret=config.GOOGLE_CLIENT_SECRET, access_token_url='https://accounts.google.com/o/oauth2/token', access_token_params=None, refresh_token_url=None, authorize_url='https://accounts.google.com/o/oauth2/auth', api_base_url='https://www.googleapis.com/oauth2/v1/', client_kwargs={ 'scope': 'https://www.googleapis.com/auth/userinfo.email', 'token_endpoint_auth_method': 'client_secret_basic', 'token_placement': 'header', 'prompt': 'consent' })
def create_app(): app = Flask(__name__) app.secret_key = config("SECRET_KEY") app.config['SQLALCHEMY_DATABASE_URI'] = config("DATABASE_URL") app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False DB.init_app(app) oauth = OAuth(app) auth0 = oauth.register( 'auth0', client_id=config("CLIENT_ID"), client_secret=config("CLIENT_SECRET"), api_base_url=config("API_BASE_URL"), access_token_url=config("ACCESS_TOKEN_URL"), authorize_url=config("AUTHORIZE_URL"), client_kwargs={ 'scope': 'openid profile', }, ) def requires_auth(f): @wraps(f) def decorated(*args, **kwargs): if 'profile' not in session: # Redirect to Login page here return redirect('/') return f(*args, **kwargs) return decorated @app.route('/') def home(): return render_template('home.html') @app.route('/callback') def callback_handling(): # Handles response from token endpoint auth0.authorize_access_token() resp = auth0.get('userinfo') userinfo = resp.json() # Store the user information in flask session. session['jwt_payload'] = userinfo session['profile'] = { 'user_id': userinfo['sub'], 'name': userinfo['name'], 'picture': userinfo['picture'] } db_user = (User.query.get(userinfo['sub']) or User(id=userinfo['sub'], name=userinfo['name'])) DB.session.add(db_user) DB.session.commit() return redirect('/dashboard') @app.route('/login') def login(): return auth0.authorize_redirect( redirect_uri='http://127.0.0.1:5000/callback', audience='https://crawftv.auth0.com/userinfo') @app.route('/dashboard') @requires_auth def dashboard(): return render_template('dashboard.html', userinfo=session['profile'], userinfo_pretty=json.dumps( session['jwt_payload'], indent=4)) @app.route('/logout') @requires_auth def logout(): # Clear session stored data session.clear() # Redirect user to logout endpoint params = { 'returnTo': url_for('home', _external=False), 'client_id': config('CLIENT_ID') } return redirect(auth0.api_base_url + '/v2/logout?' + urlencode(params)) @app.route('/users') @requires_auth def display_users_page(): users = User.query.all() return render_template('users.html', users=users) @app.route('/q', methods=['POST', 'GET']) @requires_auth def display_questions(): questions = Question.query.all() if request.method == 'POST': text = request.values["text"] section = request.values['section'] q = Question(text=text, user_id=session['profile']['user_id'], solved_status=False, date=datetime.datetime.now(), section=section) DB.session.add(q) DB.session.commit() return render_template('questions.html', questions=questions) @app.route('/q/<int:question_id>', methods=['GET', 'POST']) @requires_auth def display_individual_question(question_id): question = Question.query.get(question_id) answers = Answer.query.filter_by(question_id=question_id).all() if request.method == 'POST': a = Answer(text=request.values['answer'], user_id=session['profile']['user_id'], is_solution=False, date=datetime.datetime.now(), question_id=question_id) DB.session.add(a) DB.session.commit() return render_template('individual_question.html', answers=answers, question=question) return app