Example #1
0
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",
Example #2
0
@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()
Example #3
0
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
Example #4
0
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))
Example #5
0
    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()
Example #6
0
@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)
Example #7
0
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)
Example #8
0
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
Example #9
0
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
Example #10
0
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",
)

Example #11
0
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'
    },
)
Example #13
0
__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
Example #14
0
    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'))
Example #15
0
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
Example #16
0
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
Example #17
0
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'])
Example #18
0
        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')
Example #20
0
    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, [])
Example #21
0
    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
Example #22
0
 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'
               })
Example #24
0
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
Example #25
0
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'
               })
Example #27
0
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