def create_app(config_obj=None): """ Create a Flask application object. :return: a Flask application object :rtype: flask.Flask """ app = Flask(__name__) if config_obj: app.config.from_object(config_obj) else: load_config(app) if app.config['ENV'] != 'development': if app.config['SECRET_KEY'] == 'replace-me-with-something-random': raise RuntimeError('You need to change the SECRET_KEY configuration for production') for config in ('AD_DOMAIN', 'AD_LDAP_URI', 'AD_USERS_GROUP', 'AD_ADMINS_GROUP', 'AD_SERVICE_USERNAME', 'AD_SERVICE_PASSWORD', 'SQLALCHEMY_DATABASE_URI'): if not app.config.get(config): raise RuntimeError('You need to set the "{0}" setting'.format(config)) init_logging(app) db.init_app(app) migrations_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)), 'migrations') Migrate(app, db, directory=migrations_dir) app.cli.command()(create_db) for status_code in default_exceptions.keys(): app.register_error_handler(status_code, json_error) app.register_error_handler(ValidationError, json_error) app.register_error_handler(ConfigurationError, json_error) app.register_error_handler(ADError, json_error) app.after_request(insert_headers) app.register_blueprint(api_v1, url_prefix='/api/v1') jwt = JWTManager(app) jwt.token_in_blacklist_loader(BlacklistedToken.is_token_revoked) jwt.user_claims_loader(add_jwt_claims) app.cli.command()(prune_blacklisted_tokens) return app
def create_app(config_name): app = Flask(__name__) api = Api(app) cors = CORS(app) app.config['SECRET_KEY'] = os.getenv('SECRET_KEY') app.config.from_object(app_config[config_name]) jwt = JWTManager(app) @jwt.user_claims_loader def add_claims_to_jwt(identity): from user.models import User #TODO: change condition to check if user is admin if identity == 1: return {'is_admin': True} return {'is_admin': False} @jwt.token_in_blacklist_loader def check_if_token_in_blacklist(decrypted_token): from security.blacklist.models import TokenBlacklist return decrypted_token['jti'] in TokenBlacklist.get_all() @jwt.expired_token_loader def expired_token_callback(): return jsonify({ "description": "The token has expired", "error": "token_expired" }), 401 @jwt.invalid_token_loader def invalid_token_callback(error): return jsonify({ "description": "Signature verification failed", "error": "invalid_token" }), 401 @jwt.unauthorized_loader def missing_token_callback(error): return jsonify({ "description": "Request does not contain an access token", "error": "unauthorized_required" }), 401 @jwt.needs_fresh_token_loader def token_not_fresh_call(): return jsonify({ "description": "The token has been revoked", "error": "token_revoked" }), 401 ### resource area ### from user.resources import (UserRegisterAPI, UserLoginAPI, UserAPI, UserLogoutAPI, TokenRefreshAPI) api.add_resource(UserRegisterAPI, '/api/v1/register') api.add_resource(UserLoginAPI, '/api/v1/login') api.add_resource(UserLogoutAPI, '/api/v1/logout') api.add_resource(TokenRefreshAPI, '/api/v1/refresh') api.add_resource(UserApi, '/api/v1/user') db.init_app(app) return app
def __init__(self, appbuilder): super(BaseSecurityManager, self).__init__(appbuilder) app = self.appbuilder.get_app # Base Security Config app.config.setdefault("AUTH_ROLE_ADMIN", "Admin") app.config.setdefault("AUTH_ROLE_PUBLIC", "Public") app.config.setdefault("AUTH_TYPE", AUTH_DB) # Self Registration app.config.setdefault("AUTH_USER_REGISTRATION", False) app.config.setdefault("AUTH_USER_REGISTRATION_ROLE", self.auth_role_public) # LDAP Config if self.auth_type == AUTH_LDAP: if "AUTH_LDAP_SERVER" not in app.config: raise Exception( "No AUTH_LDAP_SERVER defined on config" " with AUTH_LDAP authentication type." ) app.config.setdefault("AUTH_LDAP_SEARCH", "") app.config.setdefault("AUTH_LDAP_SEARCH_FILTER", "") app.config.setdefault("AUTH_LDAP_BIND_USER", "") app.config.setdefault("AUTH_LDAP_APPEND_DOMAIN", "") app.config.setdefault("AUTH_LDAP_USERNAME_FORMAT", "") app.config.setdefault("AUTH_LDAP_BIND_PASSWORD", "") # TLS options app.config.setdefault("AUTH_LDAP_USE_TLS", False) app.config.setdefault("AUTH_LDAP_ALLOW_SELF_SIGNED", False) app.config.setdefault("AUTH_LDAP_TLS_DEMAND", False) app.config.setdefault("AUTH_LDAP_TLS_CACERTDIR", "") app.config.setdefault("AUTH_LDAP_TLS_CACERTFILE", "") app.config.setdefault("AUTH_LDAP_TLS_CERTFILE", "") app.config.setdefault("AUTH_LDAP_TLS_KEYFILE", "") # Mapping options app.config.setdefault("AUTH_LDAP_UID_FIELD", "uid") app.config.setdefault("AUTH_LDAP_FIRSTNAME_FIELD", "givenName") app.config.setdefault("AUTH_LDAP_LASTNAME_FIELD", "sn") app.config.setdefault("AUTH_LDAP_EMAIL_FIELD", "mail") if self.auth_type == AUTH_OID: self.oid = OpenID(app) if self.auth_type == AUTH_OAUTH: from flask_oauthlib.client import OAuth self.oauth = OAuth() self.oauth_remotes = dict() for _provider in self.oauth_providers: provider_name = _provider["name"] log.debug("OAuth providers init {0}".format(provider_name)) obj_provider = self.oauth.remote_app( provider_name, **_provider["remote_app"] ) obj_provider._tokengetter = self.oauth_tokengetter if not self.oauth_user_info: self.oauth_user_info = self.get_oauth_user_info # Whitelist only users with matching emails if "whitelist" in _provider: self.oauth_whitelists[provider_name] = _provider["whitelist"] self.oauth_remotes[provider_name] = obj_provider # Setup Flask-Login self.lm = LoginManager(app) self.lm.login_view = "login" self.lm.user_loader(self.load_user) # Setup Flask-Jwt-Extended self.jwt_manager = JWTManager() self.jwt_manager.init_app(app) self.jwt_manager.user_loader_callback_loader(self.load_user)
def app(): app = Flask(__name__) app.config['JWT_SECRET_KEY'] = 'foobarbaz' app.config['JWT_TOKEN_LOCATION'] = ['cookies'] JWTManager(app) @app.route('/access_token', methods=['GET']) def access_token(): resp = jsonify(login=True) access_token = create_access_token('username') set_access_cookies(resp, access_token) return resp @app.route('/refresh_token', methods=['GET']) def refresh_token(): resp = jsonify(login=True) refresh_token = create_refresh_token('username') set_refresh_cookies(resp, refresh_token) return resp @app.route('/delete_tokens', methods=['GET']) def delete_tokens(): resp = jsonify(logout=True) unset_jwt_cookies(resp) return resp @app.route('/delete_access_tokens', methods=['GET']) def delete_access_tokens(): resp = jsonify(access_revoked=True) unset_access_cookies(resp) return resp @app.route('/delete_refresh_tokens', methods=['GET']) def delete_refresh_tokens(): resp = jsonify(refresh_revoked=True) unset_refresh_cookies(resp) return resp @app.route('/protected', methods=['GET']) @jwt_required def protected(): return jsonify(foo='bar') @app.route('/post_protected', methods=['POST']) @jwt_required def post_protected(): return jsonify(foo='bar') @app.route('/refresh_protected', methods=['GET']) @jwt_refresh_token_required def refresh_protected(): return jsonify(foo='bar') @app.route('/post_refresh_protected', methods=['POST']) @jwt_refresh_token_required def post_refresh_protected(): return jsonify(foo='bar') @app.route('/optional_post_protected', methods=['POST']) @jwt_optional def optional_post_protected(): return jsonify(foo='bar') return app
from flask import Flask from flask_bcrypt import Bcrypt from flask_sqlalchemy import SQLAlchemy from flask_restful import Api from flask_cors import CORS from flask_jwt_extended import JWTManager from app.videos.resources import Videos from app.authentication.resources import Login, Register, RefreshToken, LogoutAccess, LogoutRefresh, Account, ApiKey flask_app = Flask(__name__) bcrypt = Bcrypt(flask_app) config.configure_app(flask_app) db = SQLAlchemy(flask_app) jwt = JWTManager(flask_app) CORS(flask_app) recaptcha = ReCaptcha(app=flask_app) api = Api(flask_app, catch_all_404s=True) api.add_resource(Videos, '/videos') api.add_resource(Login, '/login') api.add_resource(Account, '/account') api.add_resource(LogoutAccess, '/logout-access') api.add_resource(LogoutRefresh, '/logout-refresh') api.add_resource(RefreshToken, '/refresh-token') api.add_resource(Register, '/register') api.add_resource(ApiKey, '/api-key') blacklist = set()
import functools from api_gateway.classes.user import User from werkzeug.local import LocalProxy from flask_jwt_extended import jwt_required, JWTManager, current_user, jwt_optional, get_jwt_identity, verify_jwt_in_request_optional from flask import redirect, url_for, make_response, request jwt_manager = JWTManager() currently_logged_in = {} current_user = LocalProxy(lambda: _get_jwt_user()) class AnonymousUser(): pass @jwt_optional def _get_jwt_user(): usr = currently_logged_in.get(str(get_jwt_identity())) return (usr if isinstance(usr, User) else None) @jwt_manager.unauthorized_loader def unauthorized(error_description): # TODO: return stuff return "Unauthorized " + error_description, 401 @jwt_manager.user_loader_callback_loader def loader(user_id): if not currently_logged_in.get(str(user_id)):
app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False app.config['PROPAGATE_EXCEPTIONS'] = True app.config['JWT_BLOCKLIST_TOKEN_CHECKS'] = ['access', 'refresh'] app.secret_key = 'cris' # app.config['JWT_SCREET_KEY'] api = Api(app) @app.before_first_request def create_tables(): db.create_all() jwt = JWTManager(app) # not creating /auth @jwt.additional_claims_loader def add_claims_to_jwt(identity): if identity == 1: # Instead of hard-coding you should read from a config file or a db return {'is_admin': True} return {'is_admin': False} @jwt.token_in_blocklist_loader def check_if_token_in_blocklist(decrypted_token): return decrypted_token['jti'] in BLOCKLIST @jwt.expired_token_loader
from reddit.user.models import User from flask_jwt_extended import JWTManager def jwt_identity(payload): id = payload['id'] return User.query.get(id) def identity_loader(user): return {'id': user.id, 'username': user.username} jwt = JWTManager() jwt.user_loader_callback_loader(jwt_identity) jwt.user_identity_loader(identity_loader)
def create_app(test_config=None): app=Flask(__name__,static_url_path='/static') app.config.from_mapping( SECRET_KEY='noobhashspoiler123654789', ) app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0 #Config MongoDB using pymongo package app.config["MONGO_URI"] = "mongodb://*****:*****@ds143326.mlab.com:43326/metagene" 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) try: os.makedirs(app.instance_path) except OSError: pass #setup bcrypt and jwt encryption schemas bcrypt=Bcrypt(app) jwt=JWTManager(app) #Trigger middleware CORS(app) #Routes------------------------------------------------------------------ #Generates plots @app.route('/users/plot',methods=['POST','GET']) def plot(): if(request.get_json()['accnum']!=None and request.get_json()['gtype']!=None): details={'acnum':request.get_json()['accnum'],'gtype':request.get_json()['gtype'],'genes':request.get_json()['genes'],'sample':request.get_json()['sample'],'number':request.get_json()['number']} #obtain the javascript script, HTML DOM element and description corresponding to the plot script,div,description=visualize(details) #assemble to be sent as a json object data={ 'div':div, 'description':description, 'script':script } print(data) #write the new script in the file in the client assets folder fwrite(script) return jsonify(data) else: result={"error:Invalid Accession Number"} return jsonify(result) #returns metadata of the dataset @app.route('/users/meta',methods=['POST']) def meta(): if(request.get_json()!=None): if(request.get_json()['accnum']!=None): details={'acnum':request.get_json()['accnum'],'gtype':'' ,'genes':'','number':''} #obtain description of the dataset, list of samples(time point) and the dataset description={} description,genes,dataset=getMeta(details) #assemble the data to be sent data={ 'genes':genes, 'description':description } return jsonify(data) else: result={'error':"Invalid Accession Number"} return jsonify(result) else: result={'error':"Invalid Accession Number"} return jsonify(result) #register @app.route('/users/register',methods=['POST']) def register(): #hook up with the monho db users collection global app #make a db connection dbctrl=DBCtrl(app) #prepare the user details to be sent name=request.get_json()['name'] email=request.get_json()['email'] password=bcrypt.generate_password_hash(request.get_json()['password']).decode('utf-8') created=datetime.utcnow() user={ 'name':name, 'email':email, 'password':password, 'created':created } #insert the new user to db user_id=dbctrl.insert(user) #make sure that new user has been registered properly new_user=dbctrl.read({'_id':user_id}) if(new_user): result={'email':new_user['email']+"registered"} return jsonify({'result':result}) else: result={'stat':"Unsuccessful"} return jsonify({'result':result}) #login @app.route('/users/login',methods=['POST']) def login(): email=request.get_json()['email'] password=request.get_json()['password'] dbctrl=DBCtrl(app) #find the user having corresponding credentails response=dbctrl.read({'email':email}) if response: #If a user exists ,authenticate the user if bcrypt.check_password_hash(response['password'],password): expires = timedelta(days=1) access_token=create_access_token(identity={ 'name':response['name'], 'email':response['email'] },expires_delta=expires) result=jsonify({"token":access_token,'email':response['email']}) else: result=jsonify({'error':"Invalid password"}) else: result=jsonify({'result':"Invalid email"}) return result @app.route('/users/feedback',methods=['POST']) def feedback(): dbctrl=DBCtrl(app) ticket=request.get_json() feedback={ 'titile':ticket['title'], 'description':ticket['description'], 'datetime': datetime.now() } id_feedback=dbctrl.insertFeedback(feedback) if(id_feedback): return jsonify({'result':'success'}) else: return jsonify({'result':'failed'}) @app.route('/users/support',methods=['POST']) def support(): dbctrl=DBCtrl(app) ticket=request.get_json() supticket={ 'titile':ticket['title'], 'description':ticket['description'], 'user':ticket['email'], 'datetime': datetime.now() } id_sup=dbctrl.insertSupTicket(supticket) if(id_sup): return jsonify({'result':'success'}) else: return jsonify({'result':'failed'}) @app.route('/users/savetofav',methods=['POST']) def savefav(): dbctrl=DBCtrl(app) data=request.get_json() graph={ 'id':str(datetime.now()), 'user':data['email'], 'description':data['desc'], 'div':data['div'], 'script':data['script'], 'datetime': datetime.now(), 'title':data['title'], 'accession':data['accession'] } id_=dbctrl.insertFav(graph) if(id_): return jsonify({'result':'success'}) else: return jsonify({'result':'failed'}) @app.route('/users/getfavs',methods=['POST']) def getfav(): dbctrl=DBCtrl(app) user=request.get_json()['user'] data=dbctrl.readfavs(user) if(data): result=[] for document in data: time_stamp=document['_id'].generation_time id_=str(document['id']) title=document['title'] accession=document['accession'] result.append([time_stamp,id_,title,accession[0]]) return jsonify({'result':'success','data':result}) else: return jsonify({'result':'failed'}) @app.route('/users/viewfav',methods=['POST']) def viewfav(): dbctrl=DBCtrl(app) _id=str(request.get_json()['_id']) data=dbctrl.readfav(_id) if(data): script=data['script'] div=data['div'] description=data['description'] script=data['script'] fwrite(str(script)) return jsonify({'result':'success','div':div,'description':description,'script':script}) else: return jsonify({'result':'failed'}) @app.route('/') def home(): return render_template('index.html') @app.route('/<path:path>') def catch_all(path): return render_template('index.html') return app
logger = set_logger(entity_mgmt_app) manager = Manager(entity_mgmt_app) # migrate = Migrate(app, db) # manager.add_command('db', MigrateCommand) # jwt manager init ACCESS_EXPIRES = timedelta(hours=24) REFRESH_EXPIRES = timedelta(days=30) entity_mgmt_app.config['JWT_ACCESS_TOKEN_EXPIRES'] = ACCESS_EXPIRES entity_mgmt_app.config['JWT_REFRESH_TOKEN_EXPIRES'] = REFRESH_EXPIRES entity_mgmt_app.config['JWT_SECRET_KEY'] = entity_mgmt_app.config.get( 'SECRET_KEY') entity_mgmt_app.config['JWT_BLACKLIST_ENABLED'] = True entity_mgmt_app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['access', 'refresh'] jwt_flask = JWTManager(entity_mgmt_app) @jwt_flask.token_in_blacklist_loader def check_if_token_in_blacklist(decrypted_token): key = f"{decrypted_token['identity']['_id']}_{decrypted_token['type']}" entry = redis_conn.get(key) if entry is None or entry == 'None': return True @api.errorhandler(Exception) def handle_error(e): if isinstance(e, jwt.DecodeError): code = 401 message = "Invalid token"
from flask_jwt_extended import JWTManager from .services import is_token_revoked jwt = JWTManager() jwt.token_in_blacklist_loader(is_token_revoked)
app.config['PROPAGATE_EXCEPTIONS'] = True app.secret_key = 'dwellingly' #Replace with Random Hash #allow cross-origin (CORS) CORS(app) api = Api(app) db.init_app(app) #need to solve this @app.before_first_request def create_tables(): db.create_all() jwt = JWTManager(app) # /authorization @jwt.user_claims_loader #check if user role == admin def role_loader(identity): #idenity = user.id in JWT user = UserModel.find_by_id(identity) if user.role == 'admin': return {'is_admin': True} return {'is_admin': False} api.add_resource(UserRegister, '/register') api.add_resource(Property, '/properties/<string:name>') api.add_resource(Properties, '/properties') api.add_resource(User, '/user/<int:user_id>')
mongo_db = mongo_conn[application.config['DB_NAME']] # Create Logger object FORMAT = '%(asctime)s %(module)s %(funcName)s %(message)s' logging.basicConfig(filename="app.log", format=FORMAT, filemode='w') logger = logging.getLogger() #Create api object for flask restplus api = Api(application, title='Inventory App', description='Inventory App', version=1.0) #Create JWT object from flask_jwt_extended import JWTManager jwt = JWTManager(application) from redis import StrictRedis #Redis DB object redis_store = StrictRedis(host=application.config['REDIS_HOST'], port=application.config['REDIS_PORT'], db=application.config['REDIS_DB'], decode_responses=True) @jwt.token_in_blacklist_loader def check_if_token_is_revoked(decrypted_token): jti = decrypted_token['jti'] entry = redis_store.get(jti) if entry is None: return True
def create_app(): app = Flask(__name__, instance_relative_config=True) if app.config['ENV'] == 'development': app.config.from_object(config.DevelopmentConfig) elif app.config['ENV'] == 'testing': app.config.from_object(config.TestingConfig) elif app.config['ENV'] == 'production': app.config.from_object(config.ProductionConfig) else: raise ValueError('Check FLASK_ENV') app.config.from_pyfile('application.cfg') mongo.init_app(app) jwt = JWTManager(app) # ref. https://github.com/flask-restful/flask-restful/issues/280 handle_exception = app.handle_exception handle_user_exception = app.handle_user_exception @app.route('/') def hello_world(): print('hello called') return 'Hello, World!' @app.route("/telegram_listen", methods=['POST']) def telegram_listen(): print('telegram called webhook post') payload = request.get_json() print('payload =', payload) # payload = {'update_id': 280974475, 'message': {'message_id': 31, 'from': {'id': 43446854, 'is_bot': False, 'first_name': 'Roy', 'last_name': 'Cho', 'username': '******', 'language_code': 'ko'}, 'chat': {'id': 43446854, 'first_name': 'Roy', 'last_name': 'Cho', 'username': '******', 'type': 'private'}, 'date': 1606571726, 'text': 'hi'}} # payload = {'update_id': 280974479, 'edited_message': {'message_id': 40, 'from': {'id': 43446854, 'is_bot': False, 'first_name': 'Roy', 'last_name': 'Cho', 'username': '******', 'language_code': 'ko'}, 'chat': {'id': 43446854, 'first_name': 'Roy', 'last_name': 'Cho', 'username': '******', 'type': 'private'}, 'date': 1606572265, 'edit_date': 1606572312, 'text': 'hello'}} message = payload.get('message', None) if message is None: message = payload.get('edited_message', None) print('message = ', message) chatMsg = message['text'] print('chatMsg =', chatMsg) url = "http://localhost:5001/bot?chat=" + chatMsg response = requests.get(url) url = "https://api.telegram.org/bot" + telelgram_token + "/sendMessage?chat_id=43446854&text=" + response.text print('url=', url) response = requests.get(url) print(response.status_code) return "ok" from .resources.foo import ( foo_bp, Hello, HelloSecret, ) api_foo = Api(foo_bp) api_foo.add_resource(Hello, '/hello') api_foo.add_resource(HelloSecret, '/secret') app.register_blueprint(foo_bp) # ref. https://github.com/flask-restful/flask-restful/issues/280 app.handle_exception = handle_exception app.handle_user_exception = handle_user_exception return app
from flask import Flask from flask_sqlalchemy import SQLAlchemy from flask_jwt_extended import JWTManager import datetime # initializing application object app = Flask(__name__) # app configuration app.config['SECRET_KEY'] = 'THISISHIDDEN' app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.db' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # time duration after which the JWT access token expire app.config['JWT_ACCESS_TOKEN_EXPIRES'] = datetime.timedelta(minutes=5) # initializing database object db = SQLAlchemy(app) # initializing jwt object jwt_obj = JWTManager(app) # routes import from project.routes import Routes
DB: SQLAlchemy DB = SQLAlchemy(APP, metadata=MetaData( naming_convention={ 'pk': 'pk_%(table_name)s', 'fk': 'fk_%(table_name)s_%(column_0_name)s', 'ix': 'ix_%(table_name)s_%(column_0_name)s', 'uq': 'uq_%(table_name)s_%(column_0_name)s', 'ck': 'ck_%(table_name)s_%(column_0_name)s', })) MIGRATE: Migrate = Migrate(APP, DB) BCRYPT: Bcrypt = Bcrypt(APP) # Setup JWT JWT: JWTManager = JWTManager(APP) # Setup Headers CORS(APP) # Setup Celery # pylint: disable=C0413 from .tasks import make_celery celery = make_celery(APP) # Import LoginProviders # pylint: disable=C0413 from . import auth_providers # pylint: disable=C0413 from . import db_models
def create_app(config_filename): app = Flask(__name__) app.config.from_object(configurations[config_filename]) b_crypt.init_app(app) api.init_app(app) db.init_app(app) jwt = JWTManager(app) # workaround... jwt._set_error_handler_callbacks(api) migrate = Migrate(app, db) from flask_cookbook.app.model.auth import UserModel, RevokedTokenModel from flask_cookbook.app.model.cookbook import UnitModel, IngredientModel, RecipeIngredientModel, RecipeModel @app.cli.command("create-data") def create_data(): db.drop_all() db.create_all() db.session.commit() ingredients = [ IngredientModel(name="Milk"), IngredientModel(name="Flour"), IngredientModel(name="Water"), IngredientModel(name="Salt"), IngredientModel(name="White sugar"), IngredientModel(name="Brown sugar"), IngredientModel(name="Butter"), IngredientModel(name="Egg"), IngredientModel(name="Baking powder"), IngredientModel(name="Heavy cream"), IngredientModel(name="Vanilla extract"), IngredientModel(name="Cookies"), ] db.session.bulk_save_objects(ingredients) units = [ UnitModel(description="ml"), UnitModel(description="l"), UnitModel(description="oz"), UnitModel(description="tablespoon"), UnitModel(description="teaspoon"), UnitModel(description="cup"), UnitModel(description="g"), UnitModel(description="kg"), ] db.session.bulk_save_objects(units) icecream_ingredients = [ RecipeIngredientModel(ingredient=IngredientModel.find_by_name("Heavy cream"), quantity=2, unit=UnitModel.find_by_desc("cup")), RecipeIngredientModel(ingredient=IngredientModel.find_by_name("Milk"), quantity=1.5, unit=UnitModel.find_by_desc("cup")), RecipeIngredientModel(ingredient=IngredientModel.find_by_name("White sugar"), quantity=1, unit=UnitModel.find_by_desc("cup")), RecipeIngredientModel(ingredient=IngredientModel.find_by_name("Salt"), quantity=0.2, unit=UnitModel.find_by_desc("tablespoon")), RecipeIngredientModel(ingredient=IngredientModel.find_by_name("Cookies"), quantity=2, unit=UnitModel.find_by_desc("cup")), ] icecream_recipe = RecipeModel(name="Ice Cream", description="How to make homemade Ice Cream in 5 minutes.", prep_time=5) icecream_recipe.ingredients.extend(icecream_ingredients) db.session.add(icecream_recipe) pancake_ingredients = [ RecipeIngredientModel(ingredient=IngredientModel.find_by_name("Flour"), quantity=1.5, unit=UnitModel.find_by_desc("cup")), RecipeIngredientModel(ingredient=IngredientModel.find_by_name("Baking powder"), quantity=3.5, unit=UnitModel.find_by_desc("teaspoon")), RecipeIngredientModel(ingredient=IngredientModel.find_by_name("Salt"), quantity=1, unit=UnitModel.find_by_desc("teaspoon")), RecipeIngredientModel(ingredient=IngredientModel.find_by_name("White sugar"), quantity=1, unit=UnitModel.find_by_desc("tablespoon")), RecipeIngredientModel(ingredient=IngredientModel.find_by_name("Milk"), quantity=1.5, unit=UnitModel.find_by_desc("cup")), RecipeIngredientModel(ingredient=IngredientModel.find_by_name("Egg"), quantity=1), RecipeIngredientModel(ingredient=IngredientModel.find_by_name("Butter"), quantity=3, unit=UnitModel.find_by_desc("tablespoon")), ] pancakes_recipe = RecipeModel(name="Pancakes", description="How to make delicious pancakes", prep_time=15) pancakes_recipe.ingredients.extend(pancake_ingredients) db.session.add(pancakes_recipe) db.session.commit() return app
def user(app): # Setup the Flask-JWT-Extended extension app.config['JWT_SECRET_KEY'] = 'super-secret' # Change this! app.config["MONGO_URI"] = Config.MONGO app.config['JWT_ACCESS_COOKIE_PATH'] = '/api/' app.config['JWT_REFRESH_COOKIE_PATH'] = '/token/refresh' app.config['JWT_COOKIE_CSRF_PROTECT'] = False app.config['JWT_TOKEN_LOCATION'] = ['cookies', 'headers'] jwt = JWTManager(app) mongo = PyMongo(app) # Provide a method to create access tokens. The create_access_token() # function is used to actually generate the token, and you can return # it to the caller however you choose. @app.route('/login', methods=['POST']) def login(): if not request.is_json: return jsonify({"msg": "Missing JSON in request"}), 400 username = request.json.get('username', None) password = request.json.get('password', None) if not username: return jsonify({"msg": "Missing username parameter"}), 400 if not password: return jsonify({"msg": "Missing password parameter"}), 400 users = User.user(mongo, username, password) if users == None: return jsonify({"msg": "Usuario o contraseña invalidas"}) # Identity can be any data that is json serializable expires = datetime.timedelta(hours=Config.TOKEN_TIME) access_token = create_access_token(identity=username, expires_delta=expires) refresh_token = create_refresh_token(identity=username) login = jsonify({'login': True}) set_access_cookies(login, access_token) set_refresh_cookies(login, refresh_token) ret = { 'access_token': create_access_token(identity=username), 'refresh_token': create_refresh_token(identity=username) } return jsonify(ret), 200 @app.route('/token/remove', methods=['POST']) def logout(): resp = jsonify({'logout': True}) unset_jwt_cookies(resp) return resp, 200 @app.route('/token/refresh', methods=['POST']) @jwt_refresh_token_required def refresh(): # Create the new access token current_user = get_jwt_identity() access_token = create_access_token(identity=current_user) # Set the JWT access cookie in the response resp = jsonify({'refresh': True}) set_access_cookies(resp, access_token) return resp, 200 # Protect a view with jwt_required, which requires a valid access token # in the request to access. @app.route('/protected', methods=['GET']) @jwt_required def protected(): # Access the identity of the current user with get_jwt_identity current_user = get_jwt_identity() return jsonify(logged_in_as=current_user), 200
from flask import Blueprint, request, url_for, redirect, session, current_app, jsonify from werkzeug.wrappers import Response from flask_cors import cross_origin from flask_jwt_extended import (JWTManager, create_access_token, create_refresh_token, jwt_required, get_jwt_identity, jwt_refresh_token_required, get_raw_jwt) from flask_bcrypt import Bcrypt import datetime from ..db import mongo bcrypt = Bcrypt(current_app) jwt = JWTManager(current_app) blacklist = set() auth_route = Blueprint('auth_route', __name__) @auth_route.route('/signup', methods=(['POST'])) def signup(): # Receive the form info username = request.form['username'] password = request.form['password'] email = request.form['email'] name = request.form['name'] surname = request.form['surname'] # Get the users collection users = mongo.userInformation.db.users
from productmanagement.alert.controller.alertupdatecontroller import AlertUpdateController from productmanagement.product.controller.productcontroller import ProductController from productmanagement.product.controller.productsearchcontroller import ProductSearchController from productmanagement.product.controller.productupdatecontroller import ProductUpdateController from productmanagement.product.controller.productscrapecontroller import ProductScrapeController from productmanagement.product.controller.productstatuscountcontroller import ProductStatusCountController APP = Flask(__name__) CORS(APP) API = Api(APP) APP.config['JWT_SECRET_KEY'] = 'notsoeasy2break' APP.config['JWT_ACCESS_TOKEN_EXPIRES'] = datetime.timedelta(days=2) APP.config['JWT_REFRESH_TOKEN_EXPIRES'] = datetime.timedelta(days=30) jwt = JWTManager(APP) API.add_resource(ProductController, '/api/product') API.add_resource(ProductSearchController, '/api/productsearch') API.add_resource(ProductUpdateController, '/api/productupdate') API.add_resource(ProductScrapeController, '/api/productscrape') API.add_resource(UserController, '/api/user') API.add_resource(LoginController, '/api/user/login') API.add_resource(UserUpdateController, '/api/user/update') API.add_resource(PasswordUpdateController, '/api/user/password/update') API.add_resource(AlertController, '/api/alert') API.add_resource(ProductStatusCountController, '/api/product/statuscount') API.add_resource(AlertUpdateController, '/api/alertupdate') @jwt.user_identity_loader
app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///data.db' app.config['SQLALCHEMY_TRACK_MODIFIACTIONS'] = False app.config['PROPAGATE_EXCEPTIONS'] = True app.config['JWT_BLACKLIST_ENABLED'] = True app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['access','refresh'] api = Api(app) app.secret_key = "jose" db.init_app(app) @app.before_first_request def create_table(): db.create_all() jwt = JWTManager(app) # /auth @jwt.user_claims_loader def add_claims_to_identity(identity): if identity == 1: return {"is_admin":True} return {"is_admin":False} @jwt.token_in_blacklist_loader def check_if_token_in_blacklist(decrypted_token): return decrypted_token['jti'] in BLACKLIST @jwt.invalid_token_loader def invalid_token_callback(error): return jsonify({"description":"Signature verification failed","error":"invalid_token"}),401 @jwt.unauthorized_loader
import os import config from flask import Flask from models.base_model import db from flask_wtf.csrf import CSRFProtect from flask_login import LoginManager from models.user import User from flask_jwt_extended import JWTManager web_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'instagram_web') app = Flask('NEXTAGRAM', root_path=web_dir) csrf = CSRFProtect(app) JWTManager(app) login_manager = LoginManager() login_manager.init_app(app) login_manager.login_view = "sessions.new" login_manager.login_message = "Please login to continue" if os.getenv('FLASK_ENV') == 'production': app.config.from_object("config.ProductionConfig") else: app.config.from_object("config.DevelopmentConfig") @login_manager.user_loader def load_user(user_id): return User.get_or_none(id=user_id)
logger = get_logger(__name__) config_name = os.environ.get("ENVIRONMENT", "development") app = Flask('Questions', static_folder=None) app.config.from_object(config_by_name[config_name]) cors = FlaskCors(app) api = Api(**swagger_config) api.init_app(app) auth_parser = api.parser() auth_parser.add_argument('Authorization', location='headers') # Setup the Flask-JWT-Extended extension jwt = JWTManager(app) jwt._set_error_handler_callbacks(api) generic_error = api.model( 'GenericError', { 'message': fields.String(required=True, description='A description of the error') }) @app.before_request def before_request(): if request.method == "OPTIONS": return '', 200
def setUp(self): app = create_app('config.TestConfig') self.app = JWTManager(app) self.client = app.test_client() db.app = app db.create_all()
def create_app(): app = Flask(__name__) if os.environ.get('FLASK_ENV') == 'production': from project.api.config.config import ProductionConfig app.config.from_object(ProductionConfig()) elif os.environ.get('FLASK_ENV') == 'testing': from project.api.config.config import TestingConfig app.config.from_object(TestingConfig()) elif os.environ.get('FLASK_ENV') == 'staging': from project.api.config.config import StagingConfig app.config.from_object(StagingConfig()) else: from project.api.config.config import DevelopmentConfig app.config.from_object(DevelopmentConfig()) print("=> DEBUG: ", app.config) app.register_blueprint(author_routes, url_prefix=app.config['URL_PREFIX'] + 'authors') app.register_blueprint(book_routes, url_prefix=app.config['URL_PREFIX'] + 'books') app.register_blueprint(user_routes, url_prefix=app.config['URL_PREFIX'] + 'users') @app.after_request def add_header(response): return response @app.errorhandler(400) def bad_request(err): logging.error(err) return response_with(resp.BAD_REQUEST_400) @app.errorhandler(404) def not_found(err): logging.error(err) return response_with(resp.SERVER_ERROR_404) @app.errorhandler(500) def server_error(err): logging.error(e) return response_with(resp.SERVER_ERROR_500) @app.route("/api/spec") def spec(): swag = swagger(app, prefix=app.config['URL_PREFIX']) swag['info']['base'] = request.host_url # "http://localhost:5000" swag['info']['version'] = app.config['API_VER'] swag['info']['title'] = app.config['APP_NAME'] return jsonify(swag) jwt = JWTManager(app) mail.init_app(app) swaggerui_blueprint = get_swaggerui_blueprint( '/api/docs', '/api/spec', config={'app_name': app.config['APP_NAME']}) app.register_blueprint( swaggerui_blueprint, url_prefix='/api/docs') # SWAGGER_URL) # where is it define? if os.environ.get('FLASK_ENV') != 'testing': db.init_app(app) with app.app_context(): db.create_all() ## Using the expired_token_loader decorator, we will now call ## this function whenever an expired but otherwise valid access ## token attempts to access an endpoint @jwt.expired_token_loader def expired_token_callback(expired_token): token_type = expired_token['type'] value = { 'sub_status': 666, 'msg': f'The {token_type} token has expired' } return response_with(resp.UNAUTHORIZED_401, value) app.shell_context_processor({'app': app, 'db': db}) return app
class BaseSecurityManager(AbstractSecurityManager): auth_view = None """ The obj instance for authentication view """ user_view = None """ The obj instance for user view """ registeruser_view = None """ The obj instance for registering user view """ lm = None """ Flask-Login LoginManager """ oid = None """ Flask-OpenID OpenID """ oauth = None """ Flask-OAuth """ oauth_remotes = None """ OAuth email whitelists """ oauth_whitelists = {} """ Initialized (remote_app) providers dict {'provider_name', OBJ } """ oauth_tokengetter = _oauth_tokengetter """ OAuth tokengetter function override to implement your own tokengetter method """ oauth_user_info = None user_model = None """ Override to set your own User Model """ role_model = None """ Override to set your own Role Model """ permission_model = None """ Override to set your own Permission Model """ viewmenu_model = None """ Override to set your own ViewMenu Model """ permissionview_model = None """ Override to set your own PermissionView Model """ registeruser_model = None """ Override to set your own RegisterUser Model """ userdbmodelview = UserDBModelView """ Override if you want your own user db view """ userldapmodelview = UserLDAPModelView """ Override if you want your own user ldap view """ useroidmodelview = UserOIDModelView """ Override if you want your own user OID view """ useroauthmodelview = UserOAuthModelView """ Override if you want your own user OAuth view """ userremoteusermodelview = UserRemoteUserModelView """ Override if you want your own user REMOTE_USER view """ registerusermodelview = RegisterUserModelView authdbview = AuthDBView """ Override if you want your own Authentication DB view """ authldapview = AuthLDAPView """ Override if you want your own Authentication LDAP view """ authoidview = AuthOIDView """ Override if you want your own Authentication OID view """ authoauthview = AuthOAuthView """ Override if you want your own Authentication OAuth view """ authremoteuserview = AuthRemoteUserView """ Override if you want your own Authentication REMOTE_USER view """ registeruserdbview = RegisterUserDBView """ Override if you want your own register user db view """ registeruseroidview = RegisterUserOIDView """ Override if you want your own register user OpenID view """ registeruseroauthview = RegisterUserOAuthView """ Override if you want your own register user OAuth view """ resetmypasswordview = ResetMyPasswordView """ Override if you want your own reset my password view """ resetpasswordview = ResetPasswordView """ Override if you want your own reset password view """ userinfoeditview = UserInfoEditView """ Override if you want your own User information edit view """ # API security_api = SecurityApi """ Override if you want your own Security API login endpoint """ rolemodelview = RoleModelView permissionmodelview = PermissionModelView userstatschartview = UserStatsChartView viewmenumodelview = ViewMenuModelView permissionviewmodelview = PermissionViewModelView def __init__(self, appbuilder): super(BaseSecurityManager, self).__init__(appbuilder) app = self.appbuilder.get_app # Base Security Config app.config.setdefault("AUTH_ROLE_ADMIN", "Admin") app.config.setdefault("AUTH_ROLE_PUBLIC", "Public") app.config.setdefault("AUTH_TYPE", AUTH_DB) # Self Registration app.config.setdefault("AUTH_USER_REGISTRATION", False) app.config.setdefault("AUTH_USER_REGISTRATION_ROLE", self.auth_role_public) # LDAP Config if self.auth_type == AUTH_LDAP: if "AUTH_LDAP_SERVER" not in app.config: raise Exception( "No AUTH_LDAP_SERVER defined on config" " with AUTH_LDAP authentication type." ) app.config.setdefault("AUTH_LDAP_SEARCH", "") app.config.setdefault("AUTH_LDAP_SEARCH_FILTER", "") app.config.setdefault("AUTH_LDAP_BIND_USER", "") app.config.setdefault("AUTH_LDAP_APPEND_DOMAIN", "") app.config.setdefault("AUTH_LDAP_USERNAME_FORMAT", "") app.config.setdefault("AUTH_LDAP_BIND_PASSWORD", "") # TLS options app.config.setdefault("AUTH_LDAP_USE_TLS", False) app.config.setdefault("AUTH_LDAP_ALLOW_SELF_SIGNED", False) app.config.setdefault("AUTH_LDAP_TLS_DEMAND", False) app.config.setdefault("AUTH_LDAP_TLS_CACERTDIR", "") app.config.setdefault("AUTH_LDAP_TLS_CACERTFILE", "") app.config.setdefault("AUTH_LDAP_TLS_CERTFILE", "") app.config.setdefault("AUTH_LDAP_TLS_KEYFILE", "") # Mapping options app.config.setdefault("AUTH_LDAP_UID_FIELD", "uid") app.config.setdefault("AUTH_LDAP_FIRSTNAME_FIELD", "givenName") app.config.setdefault("AUTH_LDAP_LASTNAME_FIELD", "sn") app.config.setdefault("AUTH_LDAP_EMAIL_FIELD", "mail") if self.auth_type == AUTH_OID: self.oid = OpenID(app) if self.auth_type == AUTH_OAUTH: from flask_oauthlib.client import OAuth self.oauth = OAuth() self.oauth_remotes = dict() for _provider in self.oauth_providers: provider_name = _provider["name"] log.debug("OAuth providers init {0}".format(provider_name)) obj_provider = self.oauth.remote_app( provider_name, **_provider["remote_app"] ) obj_provider._tokengetter = self.oauth_tokengetter if not self.oauth_user_info: self.oauth_user_info = self.get_oauth_user_info # Whitelist only users with matching emails if "whitelist" in _provider: self.oauth_whitelists[provider_name] = _provider["whitelist"] self.oauth_remotes[provider_name] = obj_provider # Setup Flask-Login self.lm = LoginManager(app) self.lm.login_view = "login" self.lm.user_loader(self.load_user) # Setup Flask-Jwt-Extended self.jwt_manager = JWTManager() self.jwt_manager.init_app(app) self.jwt_manager.user_loader_callback_loader(self.load_user) @property def get_url_for_registeruser(self): return url_for( "%s.%s" % (self.registeruser_view.endpoint, self.registeruser_view.default_view) ) @property def get_user_datamodel(self): return self.user_view.datamodel @property def get_register_user_datamodel(self): return self.registerusermodelview.datamodel @property def auth_type(self): return self.appbuilder.get_app.config["AUTH_TYPE"] @property def auth_role_admin(self): return self.appbuilder.get_app.config["AUTH_ROLE_ADMIN"] @property def auth_role_public(self): return self.appbuilder.get_app.config["AUTH_ROLE_PUBLIC"] @property def auth_ldap_server(self): return self.appbuilder.get_app.config["AUTH_LDAP_SERVER"] @property def auth_ldap_use_tls(self): return self.appbuilder.get_app.config["AUTH_LDAP_USE_TLS"] @property def auth_user_registration(self): return self.appbuilder.get_app.config["AUTH_USER_REGISTRATION"] @property def auth_user_registration_role(self): return self.appbuilder.get_app.config["AUTH_USER_REGISTRATION_ROLE"] @property def auth_ldap_search(self): return self.appbuilder.get_app.config["AUTH_LDAP_SEARCH"] @property def auth_ldap_search_filter(self): return self.appbuilder.get_app.config["AUTH_LDAP_SEARCH_FILTER"] @property def auth_ldap_bind_user(self): return self.appbuilder.get_app.config["AUTH_LDAP_BIND_USER"] @property def auth_ldap_bind_password(self): return self.appbuilder.get_app.config["AUTH_LDAP_BIND_PASSWORD"] @property def auth_ldap_append_domain(self): return self.appbuilder.get_app.config["AUTH_LDAP_APPEND_DOMAIN"] @property def auth_ldap_username_format(self): return self.appbuilder.get_app.config["AUTH_LDAP_USERNAME_FORMAT"] @property def auth_ldap_uid_field(self): return self.appbuilder.get_app.config["AUTH_LDAP_UID_FIELD"] @property def auth_ldap_firstname_field(self): return self.appbuilder.get_app.config["AUTH_LDAP_FIRSTNAME_FIELD"] @property def auth_ldap_lastname_field(self): return self.appbuilder.get_app.config["AUTH_LDAP_LASTNAME_FIELD"] @property def auth_ldap_email_field(self): return self.appbuilder.get_app.config["AUTH_LDAP_EMAIL_FIELD"] @property def auth_ldap_bind_first(self): return self.appbuilder.get_app.config["AUTH_LDAP_BIND_FIRST"] @property def auth_ldap_allow_self_signed(self): return self.appbuilder.get_app.config["AUTH_LDAP_ALLOW_SELF_SIGNED"] @property def auth_ldap_tls_demand(self): return self.appbuilder.get_app.config["AUTH_LDAP_TLS_DEMAND"] @property def auth_ldap_tls_cacertdir(self): return self.appbuilder.get_app.config["AUTH_LDAP_TLS_CACERTDIR"] @property def auth_ldap_tls_cacertfile(self): return self.appbuilder.get_app.config["AUTH_LDAP_TLS_CACERTFILE"] @property def auth_ldap_tls_certfile(self): return self.appbuilder.get_app.config["AUTH_LDAP_TLS_CERTFILE"] @property def auth_ldap_tls_keyfile(self): return self.appbuilder.get_app.config["AUTH_LDAP_TLS_KEYFILE"] @property def openid_providers(self): return self.appbuilder.get_app.config["OPENID_PROVIDERS"] @property def oauth_providers(self): return self.appbuilder.get_app.config["OAUTH_PROVIDERS"] def oauth_user_info_getter(self, f): """ Decorator function to be the OAuth user info getter for all the providers, receives provider and response return a dict with the information returned from the provider. The returned user info dict should have it's keys with the same name as the User Model. Use it like this an example for GitHub :: @appbuilder.sm.oauth_user_info_getter def my_oauth_user_info(sm, provider, response=None): if provider == 'github': me = sm.oauth_remotes[provider].get('user') return {'username': me.data.get('login')} else: return {} """ def wraps(provider, response=None): ret = f(self, provider, response=response) # Checks if decorator is well behaved and returns a dict as supposed. if not type(ret) == dict: log.error( "OAuth user info decorated function " "did not returned a dict, but: {0}".format( type(ret) ) ) return {} return ret self.oauth_user_info = wraps return wraps def get_oauth_token_key_name(self, provider): """ Returns the token_key name for the oauth provider if none is configured defaults to oauth_token this is configured using OAUTH_PROVIDERS and token_key key. """ for _provider in self.oauth_providers: if _provider["name"] == provider: return _provider.get("token_key", "oauth_token") def get_oauth_token_secret_name(self, provider): """ Returns the token_secret name for the oauth provider if none is configured defaults to oauth_secret this is configured using OAUTH_PROVIDERS and token_secret """ for _provider in self.oauth_providers: if _provider["name"] == provider: return _provider.get("token_secret", "oauth_token_secret") def set_oauth_session(self, provider, oauth_response): """ Set the current session with OAuth user secrets """ # Get this provider key names for token_key and token_secret token_key = self.appbuilder.sm.get_oauth_token_key_name(provider) token_secret = self.appbuilder.sm.get_oauth_token_secret_name(provider) # Save users token on encrypted session cookie session["oauth"] = ( oauth_response[token_key], oauth_response.get(token_secret, ""), ) session["oauth_provider"] = provider def get_oauth_user_info(self, provider, resp): """ Since there are different OAuth API's with different ways to retrieve user info """ # for GITHUB if provider == "github" or provider == "githublocal": me = self.appbuilder.sm.oauth_remotes[provider].get("user") log.debug("User info from Github: {0}".format(me.data)) return {"username": "******" + me.data.get("login")} # for twitter if provider == "twitter": me = self.appbuilder.sm.oauth_remotes[provider].get("account/settings.json") log.debug("User info from Twitter: {0}".format(me.data)) return {"username": "******" + me.data.get("screen_name", "")} # for linkedin if provider == "linkedin": me = self.appbuilder.sm.oauth_remotes[provider].get( "people/~:(id,email-address,first-name,last-name)?format=json" ) log.debug("User info from Linkedin: {0}".format(me.data)) return { "username": "******" + me.data.get("id", ""), "email": me.data.get("email-address", ""), "first_name": me.data.get("firstName", ""), "last_name": me.data.get("lastName", ""), } # for Google if provider == "google": me = self.appbuilder.sm.oauth_remotes[provider].get("userinfo") log.debug("User info from Google: {0}".format(me.data)) return { "username": "******" + me.data.get("id", ""), "first_name": me.data.get("given_name", ""), "last_name": me.data.get("family_name", ""), "email": me.data.get("email", ""), } # for Azure AD Tenant. Azure OAuth response contains # JWT token which has user info. # JWT token needs to be base64 decoded. # https://docs.microsoft.com/en-us/azure/active-directory/develop/ # active-directory-protocols-oauth-code if provider == "azure": log.debug("Azure response received : {0}".format(resp)) id_token = resp["id_token"] log.debug(str(id_token)) me = self._azure_jwt_token_parse(id_token) log.debug("Parse JWT token : {0}".format(me)) return { "name": me["name"], "email": me["upn"], "first_name": me["given_name"], "last_name": me["family_name"], "id": me["oid"], "username": me["oid"], } else: return {} def _azure_parse_jwt(self, id_token): jwt_token_parts = r"^([^\.\s]*)\.([^\.\s]+)\.([^\.\s]*)$" matches = re.search(jwt_token_parts, id_token) if not matches or len(matches.groups()) < 3: log.error("Unable to parse token.") return {} return { "header": matches.group(1), "Payload": matches.group(2), "Sig": matches.group(3), } def _azure_jwt_token_parse(self, id_token): jwt_split_token = self._azure_parse_jwt(id_token) if not jwt_split_token: return jwt_payload = jwt_split_token["Payload"] # Prepare for base64 decoding payload_b64_string = jwt_payload payload_b64_string += "=" * (4 - ((len(jwt_payload) % 4))) decoded_payload = base64.urlsafe_b64decode(payload_b64_string.encode("ascii")) if not decoded_payload: log.error("Payload of id_token could not be base64 url decoded.") return jwt_decoded_payload = json.loads(decoded_payload.decode("utf-8")) return jwt_decoded_payload def register_views(self): # Security APIs self.appbuilder.add_api(self.security_api) if self.auth_user_registration: if self.auth_type == AUTH_DB: self.registeruser_view = self.registeruserdbview() elif self.auth_type == AUTH_OID: self.registeruser_view = self.registeruseroidview() elif self.auth_type == AUTH_OAUTH: self.registeruser_view = self.registeruseroauthview() if self.registeruser_view: self.appbuilder.add_view_no_menu(self.registeruser_view) self.appbuilder.add_view_no_menu(self.resetpasswordview()) self.appbuilder.add_view_no_menu(self.resetmypasswordview()) self.appbuilder.add_view_no_menu(self.userinfoeditview()) if self.auth_type == AUTH_DB: self.user_view = self.userdbmodelview self.auth_view = self.authdbview() elif self.auth_type == AUTH_LDAP: self.user_view = self.userldapmodelview self.auth_view = self.authldapview() elif self.auth_type == AUTH_OAUTH: self.user_view = self.useroauthmodelview self.auth_view = self.authoauthview() elif self.auth_type == AUTH_REMOTE_USER: self.user_view = self.userremoteusermodelview self.auth_view = self.authremoteuserview() else: self.user_view = self.useroidmodelview self.auth_view = self.authoidview() if self.auth_user_registration: pass # self.registeruser_view = self.registeruseroidview() # self.appbuilder.add_view_no_menu(self.registeruser_view) self.appbuilder.add_view_no_menu(self.auth_view) self.user_view = self.appbuilder.add_view( self.user_view, "List Users", icon="fa-user", label=_("List Users"), category="Security", category_icon="fa-cogs", category_label=_("Security"), ) role_view = self.appbuilder.add_view( self.rolemodelview, "List Roles", icon="fa-group", label=_("List Roles"), category="Security", category_icon="fa-cogs", ) role_view.related_views = [self.user_view.__class__] self.appbuilder.add_view( self.userstatschartview, "User's Statistics", icon="fa-bar-chart-o", label=_("User's Statistics"), category="Security", ) if self.auth_user_registration: self.appbuilder.add_view( self.registerusermodelview, "User's Statistics", icon="fa-user-plus", label=_("User Registrations"), category="Security", ) self.appbuilder.menu.add_separator("Security") self.appbuilder.add_view( self.permissionmodelview, "Base Permissions", icon="fa-lock", label=_("Base Permissions"), category="Security", ) self.appbuilder.add_view( self.viewmenumodelview, "Views/Menus", icon="fa-list-alt", label=_("Views/Menus"), category="Security", ) self.appbuilder.add_view( self.permissionviewmodelview, "Permission on Views/Menus", icon="fa-link", label=_("Permission on Views/Menus"), category="Security", ) def create_db(self): """ Setups the DB, creates admin and public roles if they don't exist. """ self.add_role(self.auth_role_admin) self.add_role(self.auth_role_public) if self.count_users() == 0: log.warning(LOGMSG_WAR_SEC_NO_USER) def reset_password(self, userid, password): """ Change/Reset a user's password for authdb. Password will be hashed and saved. :param userid: the user.id to reset the password :param password: The clear text password to reset and save hashed on the db """ user = self.get_user_by_id(userid) user.password = generate_password_hash(password) self.update_user(user) def update_user_auth_stat(self, user, success=True): """ Update authentication successful to user. :param user: The authenticated user model :param success: Default to true, if false increments fail_login_count on user model """ if not user.login_count: user.login_count = 0 if not user.fail_login_count: user.fail_login_count = 0 if success: user.login_count += 1 user.fail_login_count = 0 else: user.fail_login_count += 1 user.last_login = datetime.datetime.now() self.update_user(user) def auth_user_db(self, username, password): """ Method for authenticating user, auth db style :param username: The username or registered email address :param password: The password, will be tested against hashed password on db """ if username is None or username == "": return None user = self.find_user(username=username) if user is None: user = self.find_user(email=username) if user is None or (not user.is_active): log.info(LOGMSG_WAR_SEC_LOGIN_FAILED.format(username)) return None elif check_password_hash(user.password, password): self.update_user_auth_stat(user, True) return user else: self.update_user_auth_stat(user, False) log.info(LOGMSG_WAR_SEC_LOGIN_FAILED.format(username)) return None def _search_ldap(self, ldap, con, username): """ Searches LDAP for user, assumes ldap_search is set. :param ldap: The ldap module reference :param con: The ldap connection :param username: username to match with auth_ldap_uid_field :return: ldap object array """ if self.auth_ldap_append_domain: username = username + "@" + self.auth_ldap_append_domain if self.auth_ldap_search_filter: filter_str = "(&%s(%s=%s))" % ( self.auth_ldap_search_filter, self.auth_ldap_uid_field, username, ) else: filter_str = "(%s=%s)" % (self.auth_ldap_uid_field, username) user = con.search_s( self.auth_ldap_search, ldap.SCOPE_SUBTREE, filter_str, [ self.auth_ldap_firstname_field, self.auth_ldap_lastname_field, self.auth_ldap_email_field, ], ) if user: if not user[0][0]: return None return user def _bind_indirect_user(self, ldap, con): """ If using AUTH_LDAP_BIND_USER bind this user before performing search :param ldap: The ldap module reference :param con: The ldap connection """ indirect_user = self.auth_ldap_bind_user if indirect_user: indirect_password = self.auth_ldap_bind_password log.debug("LDAP indirect bind with: {0}".format(indirect_user)) con.bind_s(indirect_user, indirect_password) log.debug("LDAP BIND indirect OK") def _bind_ldap(self, ldap, con, username, password): """ Private to bind/Authenticate a user. If AUTH_LDAP_BIND_USER exists then it will bind first with it, next will search the LDAP server using the username with UID and try to bind to it (OpenLDAP). If AUTH_LDAP_BIND_USER does not exit, will bind with username/password """ try: if self.auth_ldap_bind_user: self._bind_indirect_user(ldap, con) user = self._search_ldap(ldap, con, username) if user: log.debug("LDAP got User {0}".format(user)) # username = DN from search username = user[0][0] else: return False log.debug("LDAP bind with: {0} {1}".format(username, "XXXXXX")) if self.auth_ldap_username_format: username = self.auth_ldap_username_format % username if self.auth_ldap_append_domain: username = username + "@" + self.auth_ldap_append_domain con.bind_s(username, password) log.debug("LDAP bind OK: {0}".format(username)) return True except ldap.INVALID_CREDENTIALS: return False @staticmethod def ldap_extract(ldap_dict, field, fallback): if not ldap_dict.get(field): return fallback return ldap_dict[field][0].decode("utf-8") or fallback def auth_user_ldap(self, username, password): """ Method for authenticating user, auth LDAP style. depends on ldap module that is not mandatory requirement for F.A.B. :param username: The username :param password: The password """ if username is None or username == "": return None user = self.find_user(username=username) if user is not None and (not user.is_active): return None else: try: import ldap except Exception: raise Exception("No ldap library for python.") try: if self.auth_ldap_allow_self_signed: ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW) ldap.set_option(ldap.OPT_X_TLS_NEWCTX, 0) elif self.auth_ldap_tls_demand: ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND) ldap.set_option(ldap.OPT_X_TLS_NEWCTX, 0) if self.auth_ldap_tls_cacertdir: ldap.set_option( ldap.OPT_X_TLS_CACERTDIR, self.auth_ldap_tls_cacertdir ) if self.auth_ldap_tls_cacertfile: ldap.set_option( ldap.OPT_X_TLS_CACERTFILE, self.auth_ldap_tls_cacertfile ) if self.auth_ldap_tls_certfile and self.auth_ldap_tls_keyfile: ldap.set_option( ldap.OPT_X_TLS_CERTFILE, self.auth_ldap_tls_certfile ) ldap.set_option(ldap.OPT_X_TLS_KEYFILE, self.auth_ldap_tls_keyfile) con = ldap.initialize(self.auth_ldap_server) con.set_option(ldap.OPT_REFERRALS, 0) if self.auth_ldap_use_tls: try: con.start_tls_s() except Exception: log.info( LOGMSG_ERR_SEC_AUTH_LDAP_TLS.format(self.auth_ldap_server) ) return None # Authenticate user if not self._bind_ldap(ldap, con, username, password): if user: self.update_user_auth_stat(user, False) log.info(LOGMSG_WAR_SEC_LOGIN_FAILED.format(username)) return None # If user does not exist on the DB and not self user registration, go away if not user and not self.auth_user_registration: return None # User does not exist, create one if self registration. elif not user and self.auth_user_registration: self._bind_indirect_user(ldap, con) new_user = self._search_ldap(ldap, con, username) if not new_user: log.warning(LOGMSG_WAR_SEC_NOLDAP_OBJ.format(username)) return None ldap_user_info = new_user[0][1] if self.auth_user_registration and user is None: user = self.add_user( username=username, first_name=self.ldap_extract( ldap_user_info, self.auth_ldap_firstname_field, username ), last_name=self.ldap_extract( ldap_user_info, self.auth_ldap_lastname_field, username ), email=self.ldap_extract( ldap_user_info, self.auth_ldap_email_field, username + "@email.notfound", ), role=self.find_role(self.auth_user_registration_role), ) self.update_user_auth_stat(user) return user except ldap.LDAPError as e: if type(e.message) == dict and "desc" in e.message: log.error(LOGMSG_ERR_SEC_AUTH_LDAP.format(e.message["desc"])) return None else: log.error(e) return None def auth_user_oid(self, email): """ OpenID user Authentication :param email: user's email to authenticate :type self: User model """ user = self.find_user(email=email) if user is None or (not user.is_active): log.info(LOGMSG_WAR_SEC_LOGIN_FAILED.format(email)) return None else: self.update_user_auth_stat(user) return user def auth_user_remote_user(self, username): """ REMOTE_USER user Authentication :param username: user's username for remote auth :type self: User model """ user = self.find_user(username=username) # User does not exist, create one if auto user registration. if user is None and self.auth_user_registration: user = self.add_user( # All we have is REMOTE_USER, so we set # the other fields to blank. username=username, first_name=username, last_name="-", email="-", role=self.find_role(self.auth_user_registration_role), ) # If user does not exist on the DB and not auto user registration, # or user is inactive, go away. elif user is None or (not user.is_active): log.info(LOGMSG_WAR_SEC_LOGIN_FAILED.format(username)) return None self.update_user_auth_stat(user) return user def auth_user_oauth(self, userinfo): """ OAuth user Authentication :userinfo: dict with user information the keys have the same name as User model columns. """ if "username" in userinfo: user = self.find_user(username=userinfo["username"]) elif "email" in userinfo: user = self.find_user(email=userinfo["email"]) else: log.error("User info does not have username or email {0}".format(userinfo)) return None # User is disabled if user and not user.is_active: log.info(LOGMSG_WAR_SEC_LOGIN_FAILED.format(userinfo)) return None # If user does not exist on the DB and not self user registration, go away if not user and not self.auth_user_registration: return None # User does not exist, create one if self registration. if not user: user = self.add_user( username=userinfo["username"], first_name=userinfo.get("first_name", ""), last_name=userinfo.get("last_name", ""), email=userinfo.get("email", ""), role=self.find_role(self.auth_user_registration_role), ) if not user: log.error("Error creating a new OAuth user %s" % userinfo["username"]) return None self.update_user_auth_stat(user) return user """ ---------------------------------------- PERMISSION ACCESS CHECK ---------------------------------------- """ def is_item_public(self, permission_name, view_name): """ Check if view has public permissions :param permission_name: the permission: can_show, can_edit... :param view_name: the name of the class view (child of BaseView) """ permissions = self.get_public_permissions() if permissions: for i in permissions: if (view_name == i.view_menu.name) and ( permission_name == i.permission.name ): return True return False else: return False def _has_view_access(self, user, permission_name, view_name): roles = user.roles for role in roles: permissions = role.permissions if permissions: for permission in permissions: if (view_name == permission.view_menu.name) and ( permission_name == permission.permission.name ): return True return False def has_access(self, permission_name, view_name): """ Check if current user or public has access to view or menu """ if current_user.is_authenticated: return self._has_view_access(g.user, permission_name, view_name) elif current_user_jwt: return self._has_view_access(current_user_jwt, permission_name, view_name) else: return self.is_item_public(permission_name, view_name) @staticmethod def get_user_permissions_on_view(view_name): """ Returns all current user permissions on a certain view/resource :param view_name: The name of the view/resource/menu :return: (list) with permissions """ _ret = list() if current_user.is_authenticated: _current_user = current_user elif current_user_jwt: _current_user = current_user_jwt else: return _ret for role in _current_user.roles: if role.permissions: for permission in role.permissions: if permission.view_menu.name == view_name: _ret.append(permission.permission.name) return _ret def add_permissions_view(self, base_permissions, view_menu): """ Adds a permission on a view menu to the backend :param base_permissions: list of permissions from view (all exposed methods): 'can_add','can_edit' etc... :param view_menu: name of the view or menu to add """ view_menu_db = self.add_view_menu(view_menu) perm_views = self.find_permissions_view_menu(view_menu_db) if not perm_views: # No permissions yet on this view for permission in base_permissions: pv = self.add_permission_view_menu(permission, view_menu) role_admin = self.find_role(self.auth_role_admin) self.add_permission_role(role_admin, pv) else: # Permissions on this view exist but.... role_admin = self.find_role(self.auth_role_admin) for permission in base_permissions: # Check if base view permissions exist if not self.exist_permission_on_views(perm_views, permission): pv = self.add_permission_view_menu(permission, view_menu) self.add_permission_role(role_admin, pv) for perm_view in perm_views: if perm_view.permission.name not in base_permissions: # perm to delete roles = self.get_all_roles() perm = self.find_permission(perm_view.permission.name) # del permission from all roles for role in roles: self.del_permission_role(role, perm) self.del_permission_view_menu(perm_view.permission.name, view_menu) elif perm_view not in role_admin.permissions: # Role Admin must have all permissions self.add_permission_role(role_admin, perm_view) def add_permissions_menu(self, view_menu_name): """ Adds menu_access to menu on permission_view_menu :param view_menu_name: The menu name """ self.add_view_menu(view_menu_name) pv = self.find_permission_view_menu("menu_access", view_menu_name) if not pv: pv = self.add_permission_view_menu("menu_access", view_menu_name) role_admin = self.find_role(self.auth_role_admin) self.add_permission_role(role_admin, pv) def security_cleanup(self, baseviews, menus): """ Will cleanup all unused permissions from the database :param baseviews: A list of BaseViews class :param menus: Menu class """ viewsmenus = self.get_all_view_menu() roles = self.get_all_roles() for viewmenu in viewsmenus: found = False for baseview in baseviews: if viewmenu.name == baseview.__class__.__name__: found = True break if menus.find(viewmenu.name): found = True if not found: permissions = self.find_permissions_view_menu(viewmenu) for permission in permissions: for role in roles: self.del_permission_role(role, permission) self.del_permission_view_menu( permission.permission.name, viewmenu.name ) self.del_view_menu(viewmenu.name) """ --------------------------- INTERFACE ABSTRACT METHODS --------------------------- --------------------- PRIMITIVES FOR USERS ---------------------- """ def find_register_user(self, registration_hash): """ Generic function to return user registration """ raise NotImplementedError def add_register_user( self, username, first_name, last_name, email, password="", hashed_password="" ): """ Generic function to add user registration """ raise NotImplementedError def del_register_user(self, register_user): """ Generic function to delete user registration """ raise NotImplementedError def get_user_by_id(self, pk): """ Generic function to return user by it's id (pk) """ raise NotImplementedError def find_user(self, username=None, email=None): """ Generic function find a user by it's username or email """ raise NotImplementedError def get_all_users(self): """ Generic function that returns all exsiting users """ raise NotImplementedError def add_user(self, username, first_name, last_name, email, role, password=""): """ Generic function to create user """ raise NotImplementedError def update_user(self, user): """ Generic function to update user :param user: User model to update to database """ raise NotImplementedError def count_users(self): """ Generic function to count the existing users """ raise NotImplementedError """ ---------------------- PRIMITIVES FOR ROLES ---------------------- """ def find_role(self, name): raise NotImplementedError def add_role(self, name): raise NotImplementedError def get_all_roles(self): raise NotImplementedError """ ---------------------------- PRIMITIVES FOR PERMISSIONS ---------------------------- """ def get_public_permissions(self): """ returns all permissions from public role """ raise NotImplementedError def find_permission(self, name): """ Finds and returns a Permission by name """ raise NotImplementedError def add_permission(self, name): """ Adds a permission to the backend, model permission :param name: name of the permission: 'can_add','can_edit' etc... """ raise NotImplementedError def del_permission(self, name): """ Deletes a permission from the backend, model permission :param name: name of the permission: 'can_add','can_edit' etc... """ raise NotImplementedError """ ---------------------- PRIMITIVES VIEW MENU ---------------------- """ def find_view_menu(self, name): """ Finds and returns a ViewMenu by name """ raise NotImplementedError def get_all_view_menu(self): raise NotImplementedError def add_view_menu(self, name): """ Adds a view or menu to the backend, model view_menu param name: name of the view menu to add """ raise NotImplementedError def del_view_menu(self, name): """ Deletes a ViewMenu from the backend :param name: name of the ViewMenu """ raise NotImplementedError """ ---------------------- PERMISSION VIEW MENU ---------------------- """ def find_permission_view_menu(self, permission_name, view_menu_name): """ Finds and returns a PermissionView by names """ raise NotImplementedError def find_permissions_view_menu(self, view_menu): """ Finds all permissions from ViewMenu, returns list of PermissionView :param view_menu: ViewMenu object :return: list of PermissionView objects """ raise NotImplementedError def add_permission_view_menu(self, permission_name, view_menu_name): """ Adds a permission on a view or menu to the backend :param permission_name: name of the permission to add: 'can_add','can_edit' etc... :param view_menu_name: name of the view menu to add """ raise NotImplementedError def del_permission_view_menu(self, permission_name, view_menu_name): raise NotImplementedError def exist_permission_on_views(self, lst, item): raise NotImplementedError def exist_permission_on_view(self, lst, permission, view_menu): raise NotImplementedError def add_permission_role(self, role, perm_view): """ Add permission-ViewMenu object to Role :param role: The role object :param perm_view: The PermissionViewMenu object """ raise NotImplementedError def del_permission_role(self, role, perm_view): """ Remove permission-ViewMenu object to Role :param role: The role object :param perm_view: The PermissionViewMenu object """ raise NotImplementedError def load_user(self, pk): return self.get_user_by_id(int(pk)) @staticmethod def before_request(): g.user = current_user
import os from typing import Optional import flask_jwt_extended from flask_jwt_extended import JWTManager from werkzeug.security import generate_password_hash, check_password_hash # werkzeug.security provides salting internally, which is amazing import config from loguru import logger jwt_instance = JWTManager() def check_if_jwt_secret_key_is_too_short(sigkill_on_problem=True): if config.FlaskConfig.JWT_ALGORITHM == "HS512": min_chars = 90 if config.FlaskConfig.JWT_SECRET_KEY is None or len( config.FlaskConfig.JWT_SECRET_KEY) < min_chars: logger.exception( f"JW0001 JWT_SECRET_KEY is shorter than {min_chars}. Long enough key is needed for security reasons." ) if sigkill_on_problem: os.kill(os.getpid(), 9) # sigkill else: logger.warning( "JW0002 Using different algorithm for JWT than HS512." "Check for min key length for sufficient entropy is not implemented here." ) def hash_password(password: str) -> str:
from flask_cors import CORS from flask_jwt_extended import JWTManager from flask_sqlalchemy import SQLAlchemy db = SQLAlchemy() jwt = JWTManager() cors = CORS()
def create_app(): global app_created if not app_created: BlueprintsManager.register(app) Migrate(app, db) app.config.from_object(env('APP_CONFIG', default='config.ProductionConfig')) if not app.config['SECRET_KEY']: if app.config['PRODUCTION']: app.logger.error( 'SECRET_KEY must be set in .env or environment variables in production' ) exit(1) else: random_secret = secrets.token_hex() app.logger.warning( f'Using random secret "{ random_secret }" for development server. ' 'This is NOT recommended. Set proper SECRET_KEY in .env or environment variables' ) app.config['SECRET_KEY'] = random_secret db.init_app(app) if app.config['CACHING']: cache.init_app(app, config={'CACHE_TYPE': 'simple'}) else: cache.init_app(app, config={'CACHE_TYPE': 'null'}) stripe.api_key = 'SomeStripeKey' app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False app.config['FILE_SYSTEM_STORAGE_FILE_VIEW'] = 'static' app.logger.addHandler(logging.StreamHandler(sys.stdout)) app.logger.setLevel(logging.ERROR) # set up jwt app.config['JWT_HEADER_TYPE'] = 'JWT' app.config['JWT_ACCESS_TOKEN_EXPIRES'] = timedelta(days=1) app.config['JWT_REFRESH_TOKEN_EXPIRES'] = timedelta(days=365) app.config['JWT_ERROR_MESSAGE_KEY'] = 'error' app.config['JWT_TOKEN_LOCATION'] = ['cookies', 'headers'] app.config['JWT_REFRESH_COOKIE_PATH'] = '/v1/auth/token/refresh' app.config['JWT_SESSION_COOKIE'] = False app.config['JWT_BLACKLIST_ENABLED'] = True app.config['JWT_BLACKLIST_TOKEN_CHECKS'] = ['refresh'] _jwt = JWTManager(app) _jwt.user_loader_callback_loader(jwt_user_loader) _jwt.token_in_blacklist_loader(is_token_blacklisted) # setup celery app.config['CELERY_BROKER_URL'] = app.config['REDIS_URL'] app.config['CELERY_RESULT_BACKEND'] = app.config['CELERY_BROKER_URL'] app.config['CELERY_ACCEPT_CONTENT'] = ['json', 'application/text'] CORS(app, resources={r"/*": {"origins": "*"}}) AuthManager.init_login(app) if app.config['TESTING'] and app.config['PROFILE']: # Profiling app.wsgi_app = ProfilerMiddleware(app.wsgi_app, restrictions=[30]) # development api with app.app_context(): from app.api.admin_statistics_api.events import event_statistics from app.api.auth import auth_routes from app.api.custom.attendees import attendee_blueprint from app.api.bootstrap import api_v1 from app.api.celery_tasks import celery_routes from app.api.event_copy import event_copy from app.api.exports import export_routes from app.api.imports import import_routes from app.api.uploads import upload_routes from app.api.users import user_misc_routes from app.api.orders import order_misc_routes from app.api.role_invites import role_invites_misc_routes from app.api.auth import authorised_blueprint from app.api.admin_translations import admin_blueprint from app.api.orders import alipay_blueprint from app.api.settings import admin_misc_routes from app.api.server_version import info_route from app.api.custom.orders import ticket_blueprint from app.api.custom.orders import order_blueprint from app.api.custom.invoices import event_blueprint app.register_blueprint(api_v1) app.register_blueprint(event_copy) app.register_blueprint(upload_routes) app.register_blueprint(export_routes) app.register_blueprint(import_routes) app.register_blueprint(celery_routes) app.register_blueprint(auth_routes) app.register_blueprint(event_statistics) app.register_blueprint(user_misc_routes) app.register_blueprint(attendee_blueprint) app.register_blueprint(order_misc_routes) app.register_blueprint(role_invites_misc_routes) app.register_blueprint(authorised_blueprint) app.register_blueprint(admin_blueprint) app.register_blueprint(alipay_blueprint) app.register_blueprint(admin_misc_routes) app.register_blueprint(info_route) app.register_blueprint(ticket_blueprint) app.register_blueprint(order_blueprint) app.register_blueprint(event_blueprint) add_engine_pidguard(db.engine) if app.config['SQLALCHEMY_DATABASE_URI'].startswith("sqlite://"): sqlite_datetime_fix() sa.orm.configure_mappers() if app.config['SERVE_STATIC']: app.add_url_rule('/static/<path:filename>', endpoint='static', view_func=app.send_static_file) # sentry if not app_created and 'SENTRY_DSN' in app.config: sentry_sdk.init(app.config['SENTRY_DSN'], integrations=[ FlaskIntegration(), RedisIntegration(), CeleryIntegration(), SqlalchemyIntegration() ]) # redis redis_store.init_app(app) # Initialize Extensions shell.init_app(app) limiter.init_app(app) app_created = True return app
from flask import Flask, jsonify, request from flask_sqlalchemy import SQLAlchemy from sqlalchemy import Column, Integer, String, Float import os from flask_marshmallow import Marshmallow from flask_jwt_extended import JWTManager, jwt_required, create_access_token app = Flask(__name__) basedir = os.path.abspath(os.path.dirname(__file__)) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///' + os.path.join( basedir, 'planets.db') app.config['JWT_SECRET_KEY'] = 'super-secret' # change this uri db = SQLAlchemy(app) ma = Marshmallow(app) jwt = JWTManager(app) @app.cli.command('db_create') def db_create(): db.create_all() print('Database created!') @app.cli.command('db_drop') def db_drop(): db.drop_all() print('Database dropped!') @app.cli.command('db_seed') def db_seed():
def create_app(test_config=None, provided_transformer_manager=None, provided_rabbit_adaptor=None, provided_object_store=None, provided_elasticsearch_adapter=None, provided_code_gen_service=None, provided_lookup_result_processor=None, provided_docker_repo_adapter=None): """Create and configure an instance of the Flask application.""" app = Flask(__name__, instance_relative_config=True) JWTManager(app) if not test_config: app.config.from_envvar('APP_CONFIG_FILE') else: app.config.from_mapping(test_config) print("Transformer enabled: ", test_config['TRANSFORMER_MANAGER_ENABLED']) with app.app_context(): if app.config['OBJECT_STORE_ENABLED']: if not provided_object_store: object_store = ObjectStoreManager( app.config['MINIO_URL'], username=app.config['MINIO_ACCESS_KEY'], password=app.config['MINIO_SECRET_KEY']) else: object_store = provided_object_store else: object_store = None if app.config[ 'TRANSFORMER_MANAGER_ENABLED'] and not provided_transformer_manager: transformer_manager = TransformerManager( app.config['TRANSFORMER_MANAGER_MODE']) else: transformer_manager = provided_transformer_manager if not provided_rabbit_adaptor: rabbit_adaptor = _init_rabbit_mq( app.config['RABBIT_MQ_URL'], app.config['RABBIT_RETRIES'], app.config['RABBIT_RETRY_INTERVAL']) else: rabbit_adaptor = provided_rabbit_adaptor if not provided_code_gen_service: code_gen_service = CodeGenAdapter( app.config['CODE_GEN_SERVICE_URL'], transformer_manager) else: code_gen_service = provided_code_gen_service if 'ELASTIC_SEARCH_LOGGING_ENABLED' in app.config \ and app.config['ELASTIC_SEARCH_LOGGING_ENABLED']\ and not provided_elasticsearch_adapter: elasticsearch_adaptor = ElasticSearchAdapter( app.config['ES_HOST'], app.config['ES_PORT'], app.config['ES_USER'], app.config['ES_PASS']) else: elasticsearch_adaptor = provided_elasticsearch_adapter if not provided_lookup_result_processor: lookup_result_processor = LookupResultProcessor( rabbit_adaptor, elasticsearch_adaptor, "http://" + app.config['ADVERTISED_HOSTNAME'] + "/") else: lookup_result_processor = provided_lookup_result_processor if not provided_docker_repo_adapter: docker_repo_adapter = DockerRepoAdapter() else: docker_repo_adapter = provided_docker_repo_adapter api = Api(app) # ensure the instance folder exists try: os.makedirs(app.instance_path) except OSError: pass @app.before_first_request def create_tables(): from servicex.models import db, UserModel from flask_jwt_extended import (create_refresh_token, create_access_token) db.init_app(app) db.create_all() if not UserModel.find_by_email(app.config['JWT_ADMIN']): try: new_user = UserModel(email=app.config['JWT_ADMIN'], full_name="Administrator", key=UserModel.generate_hash( app.config['JWT_PASS']), admin=True, pending=False) new_user.save_to_db() create_access_token(identity=app.config['JWT_ADMIN']) create_refresh_token(identity=app.config['JWT_PASS']) except Exception: exc_type, exc_value, exc_traceback = sys.exc_info() traceback.print_tb(exc_traceback, limit=20, file=sys.stdout) print(exc_value) add_routes(api, transformer_manager, rabbit_adaptor, object_store, elasticsearch_adaptor, code_gen_service, lookup_result_processor, docker_repo_adapter) app.add_url_rule("/", "index", index) return app