def register_handlers(app: Flask) -> Flask: """A function to register global request handlers. To register a handler add them like the example Example usage: def fn(request: Request): pass app.before_request(fn) Args: app (Flask): Flask Application instance Returns: Flask: Flask Application instance """ identity_loaded.connect_via(app)(on_identity_loaded) app.errorhandler(PermissionDenied)(permission_denied) app.errorhandler(CSRFError)(invalid_csrf) app.errorhandler(NoAuthorizationError)(invalid_csrf) app.errorhandler(InvalidUsage)(invalid_error_handler) app.errorhandler(Exception)(normalize_errors) return app
def create_app(config_class=Config): app = Flask(__name__) app.config.from_object(config_class) # initialize plugins db.init_app(app) ma.init_app(app) migrate.init_app(app, db) login.init_app(app) login.login_view = 'user_views.login' login.login_message = 'Please log in to access this page.' login.session_protection = "strong" sess.init_app(app) bootstrap.init_app(app) admin.init_app(app) principal.init_app(app) excel.init_excel(app) register_blueprints(app) register_dashapps(app) # connect listener for identity loaded signal from app.user.roles import on_identity_loaded identity_loaded.connect_via(app)(on_identity_loaded) # custom overrides app.json_encoder = CustomJSONEncoder # App is behind https proxy from werkzeug.middleware.proxy_fix import ProxyFix app.wsgi_app = ProxyFix(app.wsgi_app) return app
def init_app(self, app, entry_point_actions='invenio_access.actions', entry_point_system_roles='invenio_access.system_roles', **kwargs): """Flask application initialization. :param app: The Flask application. :param entry_point_actions: The entrypoint for actions extensions. (Default: ``'invenio_access.actions'``) :param entry_point_system_roles: The entrypoint for system roles extensions. (Default: ``'invenio_access.system_roles'``) :param cache: The cache system. (Default: ``None``) """ self.init_config(app) state = _AccessState( app, entry_point_actions=entry_point_actions, entry_point_system_roles=entry_point_system_roles, cache=kwargs.get('cache')) app.extensions['invenio-access'] = state if app.config.get('ACCESS_LOAD_SYSTEM_ROLE_NEEDS', True): identity_loaded.connect_via(app)( load_permissions_on_identity_loaded ) return state
def init_app(self, app): """Flask application initialization.""" self.init_config(app) state = _OARepoCommunitiesState(app) app.extensions['oarepo-communities'] = state identity_loaded.connect_via(app)(on_identity_loaded)
def init_app(self, app, datastore=None, register_blueprint=True, login_form=None, confirm_register_form=None, register_form=None, forgot_password_form=None, reset_password_form=None, change_password_form=None, send_confirmation_form=None, passwordless_login_form=None, anonymous_user=None): """Initializes the Flask-Security extension for the specified application and datastore implentation. :param app: The application. :param datastore: An instance of a user datastore. :param register_blueprint: to register the Security blueprint or not. """ self.app = app self.datastore = datastore for key, value in _default_config.items(): app.config.setdefault('SECURITY_' + key, value) for key, value in _default_messages.items(): app.config.setdefault('SECURITY_MSG_' + key, value) identity_loaded.connect_via(app)(_on_identity_loaded) state = _get_state(app, self.datastore, login_form=login_form, confirm_register_form=confirm_register_form, register_form=register_form, forgot_password_form=forgot_password_form, reset_password_form=reset_password_form, change_password_form=change_password_form, send_confirmation_form=send_confirmation_form, passwordless_login_form=passwordless_login_form, anonymous_user=anonymous_user) if register_blueprint: app.register_blueprint(create_blueprint(state, __name__)) app.context_processor(_context_processor) state.render_template = self.render_template app.extensions['security'] = state if hasattr(app, 'cli'): from .cli import users, roles if state.cli_users_name: app.cli.add_command(users, state.cli_users_name) if state.cli_roles_name: app.cli.add_command(roles, state.cli_roles_name) return state
def init_app(self, app, datastore=None, register_blueprint=True, login_form=None, confirm_register_form=None, register_form=None, forgot_password_form=None, reset_password_form=None, change_password_form=None, send_confirmation_form=None, passwordless_login_form=None, anonymous_user=None): """Initializes the Flask-Security extension for the specified application and datastore implentation. :param app: The application. :param datastore: An instance of a user datastore. :param register_blueprint: to register the Security blueprint or not. """ self.app = app self.datastore = datastore for key, value in _default_config.items(): app.config.setdefault('SECURITY_' + key, value) for key, value in _default_messages.items(): app.config.setdefault('SECURITY_MSG_' + key, value) identity_loaded.connect_via(app)(_on_identity_loaded) state = _get_state(app, self.datastore, login_form=login_form, confirm_register_form=confirm_register_form, register_form=register_form, forgot_password_form=forgot_password_form, reset_password_form=reset_password_form, change_password_form=change_password_form, send_confirmation_form=send_confirmation_form, passwordless_login_form=passwordless_login_form, anonymous_user=anonymous_user) if register_blueprint: app.register_blueprint(create_blueprint(state, __name__)) app.context_processor(_context_processor) @app.before_first_request def _register_i18n(): if '_' not in app.jinja_env.globals: app.jinja_env.globals['_'] = state.i18n_domain.gettext state.render_template = self.render_template app.extensions['security'] = state if hasattr(app, 'cli'): from .cli import users, roles if state.cli_users_name: app.cli.add_command(users, state.cli_users_name) if state.cli_roles_name: app.cli.add_command(roles, state.cli_roles_name) return state
def init_app(self, app, datastore=None, register_blueprint=None, **kwargs): """Initializes the Flask-Security extension for the specified application and datastore implementation. :param app: The application. :param datastore: An instance of a user datastore. :param register_blueprint: to register the Security blueprint or not. """ self.app = app if datastore is None: datastore = self._datastore if register_blueprint is None: register_blueprint = self._register_blueprint for key, value in self._kwargs.items(): kwargs.setdefault(key, value) if 'render_template' not in kwargs: kwargs.setdefault('render_template', self.render_template) if 'send_mail' not in kwargs: kwargs.setdefault('send_mail', self.send_mail) for key, value in _default_config.items(): app.config.setdefault('SECURITY_' + key, value) for key, value in _default_messages.items(): app.config.setdefault('SECURITY_MSG_' + key, value) identity_loaded.connect_via(app)(_on_identity_loaded) self._state = state = _get_state(app, datastore, **kwargs) if register_blueprint: app.register_blueprint(create_blueprint(state, __name__)) app.context_processor(_context_processor) @app.before_first_request def _register_i18n(): if '_' not in app.jinja_env.globals: app.jinja_env.globals['_'] = state.i18n_domain.gettext app.extensions['security'] = state if hasattr(app, 'cli'): from .cli import users, roles if state.cli_users_name: app.cli.add_command(users, state.cli_users_name) if state.cli_roles_name: app.cli.add_command(roles, state.cli_roles_name) return state
def create(): app = Flask(__name__) app.config.from_object(Config) from ayeauth.loader import ( user_loader, # request_loader, identity_loader, on_identity_loaded, unauthorized_handler, ) from ayeauth.models.user import AnonymousUser lm.login_view = "auth_bp.login" lm.anonymous_user = AnonymousUser lm.user_loader(user_loader) # lm.request_loader(request_loader) lm.unauthorized_handler(unauthorized_handler) pr.identity_loader(identity_loader) db.init_app(app) lm.init_app(app) pr.init_app(app) identity_loaded.connect_via(app)(on_identity_loaded) from ayeauth.models.user import User # noqa: F401 from ayeauth.models.role import Role # noqa: F401 from ayeauth.models.user_role import UserRole # noqa: F401 from ayeauth.models.user_authorized_application import ( # noqa: F401 UserAuthorizedApplication, ) from ayeauth.models.application import Application # noqa: F401 from ayeauth.models.scope import Scope # noqa: F401 from ayeauth.models.application_scope import ApplicationScope # noqa: F401 from ayeauth.models.authorization_code import AuthorizationCode # noqa: F401 from ayeauth.home.routes import home_bp from ayeauth.auth.routes import auth_bp from ayeauth.oauth.routes import oauth_bp from ayeauth.user.routes import user_bp from ayeauth.application.routes import application_bp app.register_blueprint(home_bp, url_prefix="/") app.register_blueprint(auth_bp, url_prefix="/") app.register_blueprint(oauth_bp, url_prefix="/oauth") app.register_blueprint(user_bp, url_prefix="/user") app.register_blueprint(application_bp, url_prefix="/application") return app
def init_app(self, app, datastore=None, register_blueprint=True, login_form=None, confirm_register_form=None, register_form=None, forgot_password_form=None, reset_password_form=None, change_password_form=None, send_confirmation_form=None, passwordless_login_form=None, anonymous_user=None): """Initializes the Flask-Security extension for the specified application and datastore implentation. :param app: The application. :param datastore: An instance of a user datastore. :param register_blueprint: to register the Security blueprint or not. """ datastore = datastore or self.datastore for key, value in _default_config.items(): if key == 'EMAIL_SENDER' and app.config.get('MAIL_DEFAULT_SENDER'): app.config.setdefault( 'SECURITY_' + key, app.config.get('MAIL_DEFAULT_SENDER') ) app.config.setdefault('SECURITY_' + key, value) for key, value in _default_messages.items(): app.config.setdefault('SECURITY_MSG_' + key, value) identity_loaded.connect_via(app)(_on_identity_loaded) state = _get_state(app, datastore, login_form=login_form, confirm_register_form=confirm_register_form, register_form=register_form, forgot_password_form=forgot_password_form, reset_password_form=reset_password_form, change_password_form=change_password_form, send_confirmation_form=send_confirmation_form, passwordless_login_form=passwordless_login_form, anonymous_user=anonymous_user) if register_blueprint: app.register_blueprint(create_blueprint(state, __name__)) app.context_processor(_context_processor) state.render_template = self.render_template app.extensions['security'] = state return state
def AccessToken(app): try: if not app.secret_key: app.secret_key = os.environ['FLASK_SECRET_KEY'] except KeyError: print("app.secret_key or FLASK_SECRET_KEY environ variable should be defined") # add _require_access_token decorator into /<repo>/* urls app.add_url_rule("/invitation", "invitation", view_func=_InvitationView.as_view('invitation')) # A hack to move /invitation url rule before /<repo> url rule invt_rule = app.url_map._rules.pop() app.url_map._rules.insert(0, invt_rule) app.url_map._remap = True app.url_map.update() Principal(app) app.before_request(_on_before_request_access_token) identity_loaded.connect_via(app)(_on_identity_loaded)
def create_app(): templates = os.path.join(os.path.dirname(__file__), '../../', 'templates') settings = os.path.join(os.path.dirname(__file__), '../../', 'etc/local.py') static_folder = os.path.join(os.path.dirname(__file__), '../../', 'assets/static') app = Flask( __name__, template_folder=templates, ) app.config.from_pyfile(settings) app.static_folder = static_folder app.config.update({'SITE_TIME': datetime.datetime.now()}) app.config.update({'SQLALCHEMY_ECHO': False}) app.config.setdefault('SQLALCHEMY_TRACK_MODIFICATIONS', True) admin_test = Admin(app, name='中瑞通航机务维修管理系统', base_template='layout.html', template_mode='bootstrap3', index_view=IndexView()) sec = Security(app, user_datastore) mysqldb.init_app(app) # mongodb.init_app(app) @sec.context_processor def security_context_processor(): return dict(admin_base_template=admin_test.base_template, admin_view=admin_test.index_view, h=helpers, get_url=url_for) identity_loaded.connect_via(app)(_on_identity_loaded) register_jinja(app) with app.app_context(): init_mxp_view(admin_test, mongodb, category='维修方案管理') admin_test.add_view(UserAdminView(mysqldb.session)) admin_test.add_view(RoleAdminView(mysqldb.session)) return app
def init_app(self, app, datastore=None, register_blueprint=True, login_form=None, confirm_register_form=None, register_form=None, forgot_password_form=None, reset_password_form=None, change_password_form=None, send_confirmation_form=None, passwordless_login_form=None, anonymous_user=None): """Initializes the Flask-Security extension for the specified application and datastore implentation. :param app: The application. :param datastore: An instance of a user datastore. :param register_blueprint: to register the Security blueprint or not. """ self.app = app self.datastore = datastore for key, value in _default_config.items(): app.config.setdefault('SECURITY_' + key, value) for key, value in _default_messages.items(): app.config.setdefault('SECURITY_MSG_' + key, value) identity_loaded.connect_via(app)(_on_identity_loaded) state = _get_state(app, self.datastore, login_form=login_form, confirm_register_form=confirm_register_form, register_form=register_form, forgot_password_form=forgot_password_form, reset_password_form=reset_password_form, change_password_form=change_password_form, send_confirmation_form=send_confirmation_form, passwordless_login_form=passwordless_login_form, anonymous_user=anonymous_user) if register_blueprint: app.register_blueprint(create_blueprint(state, __name__)) app.context_processor(_context_processor) state.render_template = self.render_template app.extensions['security'] = state return state
def init_app(self, app: FlaskUnchained): # NOTE: the order of these `self.get_*` calls is important! self.confirm_serializer = self._get_serializer(app, 'confirm') self.hashing_context = self._get_hashing_context(app) self.login_manager = self._get_login_manager( app, app.config.SECURITY_ANONYMOUS_USER) self.login_serializer = self._get_serializer(app, 'login') self.principal = self._get_principal(app) self.pwd_context = self._get_pwd_context(app) self.remember_token_serializer = self._get_serializer(app, 'remember') self.reset_serializer = self._get_serializer(app, 'reset') self.context_processor( lambda: dict(security=_SecurityConfigProperties())) # FIXME: should this be easier to customize for end users, perhaps by making # FIXME: the function come from a config setting? identity_loaded.connect_via(app)(self._on_identity_loaded) app.extensions['security'] = self
def setup_security(app, project): options = { "login_form": MeltanoLoginForm, "register_form": MeltanoRegisterFrom, "confirm_register_form": MeltanoConfirmRegisterForm, } if not app.config["MELTANO_AUTHENTICATION"]: # the FreeUser is free to do everything and has all # roles and permissions automatically. options["anonymous_user"] = FreeUser security.init_app(app, users, **options) security.unauthorized_handler(unauthorized_callback) identity_loaded.connect_via(app)(_identity_loaded_hook) jwt = JWTManager(app) @jwt.user_loader_callback_loader def jwt_user_load(identity): user = users.find_user(id=identity["id"]) login_user(user) # sets `flask_security` current_user return user bp = app.blueprints["security"] @bp.route("/bootstrap") @login_required def bootstrap_app(): """Fire off the application with the current user logged in""" uri = app.config["MELTANO_UI_URL"] if not app.config["MELTANO_AUTHENTICATION"]: return redirect(uri) auth_identity = {"id": current_user.id, "username": current_user.username} access_token = create_access_token(identity=auth_identity) return redirect(uri + f"?auth_token={access_token}") app.register_blueprint(bp)
def setup_security(app, project): options = { "login_form": MeltanoLoginForm, "register_form": MeltanoRegisterFrom, "confirm_register_form": MeltanoConfirmRegisterForm, } if not app.config["MELTANO_AUTHENTICATION"] and not app.config["MELTANO_READONLY"]: # the FreeUser is free to do everything and has all # roles and permissions automatically. options["anonymous_user"] = FreeUser else: # Use Flask's built-in AnonymousUser which is not deemed to be authenticated # and has no roles pass security.init_app(app, users, **options) security.unauthorized_handler(unauthorized_callback) user_logged_in.connect_via(app)(_user_logged_in_hook) identity_loaded.connect_via(app)(_identity_loaded_hook)
def init_app(self, app): self._state = super().init_app(app, self.datastore, **self._kwargs) # override the unauthorized action to use abort(401) instead of returning HTML self._state.unauthorized_handler(unauthorized_handler) # register a celery task to send emails asynchronously self._state.send_mail_task(send_mail_async) # load user's role hierarchy identity_loaded.connect_via(app)(on_identity_loaded) # only activate users after they've been confirmed if self.confirmable: user_confirmed.connect_via(app)(_on_user_confirmed) if not self._kwargs['register_blueprint']: app.context_processor(_context_processor) app.extensions['security'] = self
def init_app(self, app, provider=None): """Initialize app.""" app.config.setdefault('CARAFE_AUTH_ENABLED', True) app.config.setdefault('CARAFE_AUTH_SESSION_ID_KEY', 'user_id') app.config.setdefault('CARAFE_AUTH_IDENTITY_ID_KEY', 'id') app.config.setdefault('CARAFE_AUTH_IDENTITY_ROLES_KEY', 'roles') if not app.config['CARAFE_AUTH_ENABLED']: # pragma: no cover return if not hasattr(app, 'extensions'): # pragma: no cover app.extensions = {} app.extensions[self._extension_name] = {'provider': provider} # NOTE: Instead of having principal use it's session loader, we'll use # ours. self.principal.init_app(app) self.principal.identity_loader(self.session_identity_loader) identity_loaded.connect_via(app)(self.on_identity_loaded)
def setup_security(app, project): options = { "login_form": MeltanoLoginForm, "register_form": MeltanoRegisterFrom, "confirm_register_form": MeltanoConfirmRegisterForm, } settings_service = ProjectSettingsService(project) if not settings_service.get("ui.authentication"): # the FreeUser is free to do everything and has all # roles and permissions automatically. options["anonymous_user"] = FreeUser else: # Use Flask's built-in AnonymousUser which is not deemed to be authenticated # and has no roles pass security.init_app(app, users, **options) security.unauthorized_handler(unauthorized_callback) user_logged_in.connect_via(app)(_user_logged_in_hook) identity_loaded.connect_via(app)(_identity_loaded_hook)
def create_app(): app = Flask(__name__) app.config.from_object(Config) # flask_sqlalchemy # import ipdb; ipdb.set_trace() db.init_app(app) # flask_redis redis_cli.init_app(app) # flask_migrate Migrate(app, db) # flask_debug if app.config.get('DEBUG'): DebugToolbarExtension(app) # flask_login login_manager = LoginManager(app) login_manager.user_loader(load_user) login_manager.login_view = 'user_view.login' # flask_principal Principal(app) identity_loaded.connect_via(app)(_on_identity_loaded) # flask_wtf csrf csrf = CsrfProtect() csrf.init_app(app) app.before_request(check_csrf(csrf)) # flask_babel Babel(app) # flask_limiter limiter.init_app(app) # flask_qiniu qiniu.init_app(app) # flask_admin admin.init_app(app) # register blueprint app.register_blueprint(content_bp) app.register_blueprint(user_bp) app.register_blueprint(user_api_bp) # import ipdb; ipdb.set_trace() app.register_blueprint(book_bp) app.register_blueprint(book_api_bp) app.register_blueprint(user_util_api_bp) app.register_blueprint(media_bp) app.register_blueprint(online_course_bp) # register subscriber user_connect(app) # register home page app.add_url_rule('/', 'index', index) with open(os.path.join(os.getcwd(), 'youjiao/static/assets.json.py'), 'r') as assets: app.assets = json.load(assets) return app
def register_permissions_loader(app): """Register the permissions loader.""" identity_loaded.connect_via(app)(_load_permissions_on_identity_loaded) app.before_first_request(_register_anonymous_loader)
def create_app(): app = Flask(__name__) app.config.from_object(youjiao_config) # flask_sqlalchemy # import ipdb; ipdb.set_trace() db.init_app(app) # flask_redis redis_cli.init_app(app) # flask_debug if app.config.get('DEBUG'): DebugToolbarExtension(app) # flask_login login_manager.user_loader(load_user) login_manager.login_view = 'user_view.login' login_manager.init_app(app) # flask_jwt jwt.init_app(app) # flask_principal Principal(app) identity_loaded.connect_via(app)(_on_identity_loaded) # flask_wtf csrf csrf = CsrfProtect() csrf.init_app(app) app.before_request(check_csrf(csrf)) # flask_babel Babel(app) # flask_limiter limiter.init_app(app) # flask_qiniu flask_qiniu.init_app(app) # flask_admin admin.init_app(app) # register blueprint app.register_blueprint(content_bp) app.register_blueprint(user_bp) app.register_blueprint(user_api_bp) # import ipdb; ipdb.set_trace() app.register_blueprint(book_bp) app.register_blueprint(book_api_bp) app.register_blueprint(user_util_api_bp) app.register_blueprint(media_bp) app.register_blueprint(online_course_bp) # register subscriber user_connect(app) # register home page app.add_url_rule('/', 'index', index) with open(os.path.join(os.getcwd(), 'youjiao/static/assets.json.py'), 'r') as assets: app.assets = json.load(assets) return app
def init_app(self, app, datastore=None, register_blueprint=None, **kwargs): """Initializes the Flask-Security extension for the specified application and datastore implementation. :param app: The application. :param datastore: An instance of a user datastore. :param register_blueprint: to register the Security blueprint or not. """ self.app = app if datastore is None: datastore = self._datastore if register_blueprint is None: register_blueprint = self._register_blueprint for key, value in self._kwargs.items(): kwargs.setdefault(key, value) if "render_template" not in kwargs: kwargs.setdefault("render_template", self.render_template) if "json_encoder_cls" not in kwargs: kwargs.setdefault("json_encoder_cls", FsJsonEncoder) if "totp_cls" not in kwargs: kwargs.setdefault("totp_cls", Totp) if "phone_util_cls" not in kwargs: kwargs.setdefault("phone_util_cls", PhoneUtil) if "mail_util_cls" not in kwargs: kwargs.setdefault("mail_util_cls", MailUtil) for key, value in _default_config.items(): app.config.setdefault("SECURITY_" + key, value) for key, value in _default_messages.items(): app.config.setdefault("SECURITY_MSG_" + key, value) identity_loaded.connect_via(app)(_on_identity_loaded) self._state = state = _get_state(app, datastore, **kwargs) if hasattr(datastore, "user_model") and not hasattr( datastore.user_model, "fs_uniquifier"): # pragma: no cover raise ValueError( "User model must contain fs_uniquifier as of 4.0.0") if register_blueprint: bp = create_blueprint(app, state, __name__, json_encoder=kwargs["json_encoder_cls"]) app.register_blueprint(bp) app.context_processor(_context_processor) @app.before_first_request def _register_i18n(): # N.B. as of jinja 2.9 '_' is always registered # http://jinja.pocoo.org/docs/2.10/extensions/#i18n-extension if "_" not in app.jinja_env.globals: current_app.jinja_env.globals["_"] = state.i18n_domain.gettext # Register so other packages can reference our translations. current_app.jinja_env.globals[ "_fsdomain"] = state.i18n_domain.gettext @app.before_first_request def _csrf_init(): # various config checks - some of these are opinionated in that there # could be a reason for some of these combinations - but in general # they cause strange behavior. # WTF_CSRF_ENABLED defaults to True if not set in Flask-WTF if not current_app.config.get("WTF_CSRF_ENABLED", True): return csrf = current_app.extensions.get("csrf", None) # If they don't want ALL mechanisms protected, then they must # set WTF_CSRF_CHECK_DEFAULT=False so that our decorators get control. if cv("CSRF_PROTECT_MECHANISMS") != AUTHN_MECHANISMS: if not csrf: # This isn't good. raise ValueError("CSRF_PROTECT_MECHANISMS defined but" " CsrfProtect not part of application") if current_app.config.get("WTF_CSRF_CHECK_DEFAULT", True): raise ValueError( "WTF_CSRF_CHECK_DEFAULT must be set to False if" " CSRF_PROTECT_MECHANISMS is set") # We don't get control unless they turn off WTF_CSRF_CHECK_DEFAULT if # they have enabled global CSRFProtect. if (cv("CSRF_IGNORE_UNAUTH_ENDPOINTS") and csrf and current_app.config.get( "WTF_CSRF_CHECK_DEFAULT", False)): raise ValueError( "To ignore unauth endpoints you must set WTF_CSRF_CHECK_DEFAULT" " to False") csrf_cookie = cv("CSRF_COOKIE") if csrf_cookie and csrf_cookie["key"] and not csrf: # Common use case is for cookie value to be used as contents for header # which is only looked at when CsrfProtect is initialized. # Yes, this is opinionated - they can always get CSRF token via: # 'get /login' raise ValueError( "CSRF_COOKIE defined however CsrfProtect not part of application" ) if csrf: csrf.exempt("flask_security.views.logout") if csrf_cookie and csrf_cookie["key"]: current_app.after_request(csrf_cookie_handler) # Add configured header to WTF_CSRF_HEADERS current_app.config["WTF_CSRF_HEADERS"].append( cv("CSRF_HEADER")) state._phone_util = state.phone_util_cls(app) state._mail_util = state.mail_util_cls(app) app.extensions["security"] = state if hasattr(app, "cli"): from .cli import users, roles if state.cli_users_name: app.cli.add_command(users, state.cli_users_name) if state.cli_roles_name: app.cli.add_command(roles, state.cli_roles_name) # Migrate from TWO_FACTOR config to generic config. for newc, oldc in [ ("SECURITY_SMS_SERVICE", "SECURITY_TWO_FACTOR_SMS_SERVICE"), ("SECURITY_SMS_SERVICE_CONFIG", "SECURITY_TWO_FACTOR_SMS_SERVICE_CONFIG"), ("SECURITY_TOTP_SECRETS", "SECURITY_TWO_FACTOR_SECRET"), ("SECURITY_TOTP_ISSUER", "SECURITY_TWO_FACTOR_URI_SERVICE_NAME"), ]: if not app.config.get(newc, None): app.config[newc] = app.config.get(oldc, None) # Check for pre-4.0 SECURITY_USER_IDENTITY_ATTRIBUTES format for uia in cv("USER_IDENTITY_ATTRIBUTES", app=app): # pragma: no cover if not isinstance(uia, dict): raise ValueError( "SECURITY_USER_IDENTITY_ATTRIBUTES changed semantics" " in 4.0 - please see release notes.") if len(list(uia.keys())) != 1: raise ValueError( "Each element in SECURITY_USER_IDENTITY_ATTRIBUTES" " must have one and only one key.") # Two factor configuration checks and setup multi_factor = False if cv("UNIFIED_SIGNIN", app=app): multi_factor = True if len(cv("US_ENABLED_METHODS", app=app)) < 1: raise ValueError("Must configure some US_ENABLED_METHODS") if "sms" in cv("US_ENABLED_METHODS", app=app) and not get_identity_attribute( "us_phone_number", app=app): warnings.warn( "'sms' was enabled in SECURITY_US_ENABLED_METHODS;" " however 'us_phone_number' not configured in" " SECURITY_USER_IDENTITY_ATTRIBUTES") if cv("TWO_FACTOR", app=app): multi_factor = True if len(cv("TWO_FACTOR_ENABLED_METHODS", app=app)) < 1: raise ValueError( "Must configure some TWO_FACTOR_ENABLED_METHODS") if multi_factor: self._check_modules("pyqrcode", "TWO_FACTOR or UNIFIED_SIGNIN") self._check_modules("cryptography", "TWO_FACTOR or UNIFIED_SIGNIN") need_sms = (cv("UNIFIED_SIGNIN", app=app) and "sms" in cv("US_ENABLED_METHODS", app=app)) or (cv( "TWO_FACTOR", app=app) and "sms" in cv( "TWO_FACTOR_ENABLED_METHODS", app=app)) if need_sms: sms_service = cv("SMS_SERVICE", app=app) if sms_service == "Twilio": # pragma: no cover self._check_modules("twilio", "SMS") if state.phone_util_cls == PhoneUtil: self._check_modules("phonenumbers", "SMS") secrets = cv("TOTP_SECRETS", app=app) issuer = cv("TOTP_ISSUER", app=app) if not secrets or not issuer: raise ValueError( "Both TOTP_SECRETS and TOTP_ISSUER must be set") state.totp_factory(state.totp_cls(secrets, issuer)) if cv("PASSWORD_COMPLEXITY_CHECKER", app=app) == "zxcvbn": self._check_modules("zxcvbn", "PASSWORD_COMPLEXITY_CHECKER") return state
def init_app(app): db = init_db(app) mongo = PyMongo(app) sec = init_model(app) app.__version__ = __version__ admin_obj = admin.Admin(app, name=app.config['SITE_TITLE'], translations_path=os.path.join( app.root_path, 'translations'), base_template='layout.html', template_mode='bootstrap3', index_view=IndexView( name='首页', menu_icon_type='fa', menu_icon_value='fa-home')) # WUJG: 针对不同公司的实现,其权限或角色名可能会不同,通过下述机制可以针对不同的公司进行配置 # 类级的权限配置,该优先级高于用户配置的内容,如果不需要,就无需设置 # CustomView.view_accept_roles = role_management_dict # MongoCustomView.view_accept_roles = role_management_dict # Flask-Security 使用Flask-Admin的相关样式 @sec.context_processor def security_context_processor(): return dict(admin_base_template=admin_obj.base_template, admin_view=admin_obj.index_view, h=admin_helpers, get_url=url_for) @sec.login_context_processor def security_login_processor(): year = datetime.datetime.now().year return dict(copy_right=app.config['COPYRIGHT_STR'].format(year)) # 需要处理一些额外的与操作相关的权限设置 identity_loaded.connect_via(app)(_on_identity_loaded) # 机务维修管理配置 maintain_list = [ RoutineWorkView, TechMaterialView, TrainingArchiveView, TrainigMaterialView, TrainingPlanView, AirworthinessView, EngineeringOrderView, MaintenanceRecordView, FaultReportsView, TroubleShootingView, ExamineRepairRecordView, RetainView, ReservedFaultView, ] navigational_list = [ FlightLogView, CompanyDayRecordView, FlightlogStatisticsView, FormulaStatisticsView, ] quality_list = [] # 航材管理配置 airmaterial_list = [ AirmaterialCategoryView, PurchaseApplicationView, LendApplicationView, ReturnMaterialOrderView, StorageView, DisassembleOrderView, BorrowingInReturnView, PutOutStoreView, AssembleApplicationView, AssembleView, LoanReturnOrderView, LoanApplicationOrderView, RepairApplicationView, RepairReturnOrderView, ManufacturerView, ScrapView, AirMaterialStorageListView, SupplierView, RepairSupplierView, ExpireWarningView, StockWarningView, CheckWarningView ] with app.app_context(): app.mongodb = mongo.db admin_obj.add_view(Y5BView( mongo.db, 'y5b', name='维修方案', category=MAINTAINANCE_MANAGEMENT)) register_view_by_category( admin_obj, db.session, maintain_list, MAINTAINANCE_MANAGEMENT) register_view_by_category( admin_obj, db.session, navigational_list, NAVIGATIONAL_MANAGEMENT) register_view_by_category( admin_obj, db.session, quality_list, Quality_MANAGEMENT) register_view_by_category( admin_obj, db.session, airmaterial_list, AIRMATERIAL_MANAGEMENT) custom_category_style(admin_obj, MAINTAINANCE_MANAGEMENT, 'fa', 'fa-book') with app.app_context(): admin_obj.add_view(AircraftInformationView( mongo.db, AIRCRAFT_COL, 'aircraft', name='机队管理', category=MAINTAINANCE_MANAGEMENT)) # 系统管理配置 admin_obj.add_view(UserAdminView(db.session, category=SYSTEM_MANAGEMENT)) admin_obj.add_view(RoleAdminView(db.session, category=SYSTEM_MANAGEMENT)) admin_obj.add_view(NoticeView(db.session, category=SYSTEM_MANAGEMENT)) admin_obj.add_view(AnnouncementView( db.session, category=SYSTEM_MANAGEMENT)) admin_obj.add_view(ConfigurationView(category=SYSTEM_MANAGEMENT)) admin_obj.add_view( CheckWaringConfigurationView(category=SYSTEM_MANAGEMENT)) admin_obj.add_view( StockWaringConfigurationView(category=SYSTEM_MANAGEMENT)) admin_obj.add_view( ExpireWaringConfigurationView(category=SYSTEM_MANAGEMENT)) register_view_by_category( admin_obj, db.session, basic_data_views, category=SYSTEM_MANAGEMENT) custom_category_style(admin_obj, SYSTEM_MANAGEMENT, 'fa', 'fa-cog') custom_category_style(admin_obj, NAVIGATIONAL_MANAGEMENT, 'fa', 'fa-plane') custom_category_style(admin_obj, Quality_MANAGEMENT, 'fa', 'fa-sliders') custom_category_style(admin_obj, AIRMATERIAL_MANAGEMENT, 'fa', 'fa-cog') retrieve_unread_notifies(app) flight_log_notice(app) return db
def setup_permissions(state): identity_loaded.connect_via(state.app)(grant_permissions)
def create_app(package_name, package_path, settings_override=None, register_security_blueprint=True): """ Create Flask application. Currently used modules that need to init includes: * `Flask-SQLAlchemy <https://pythonhosted.org/Flask-SQLAlchemy>`_ * `Flask-Mail <http://pythonhosted.org/Flask-Mail/>`_ * `Flask-Babel <http://pythonhosted.org/Flask-Babel/>`_ * `Flask-Security <http://pythonhosted.org/Flask-Security/>`_ * `Flask-Amdin(only init from the frontend) <http://flask-admin.readthedocs.org/en/latest/index.html>`_ :param package_name: package name of the dxc. :param package_path: package path of the dxc. :param settings_override: setting that will override the existed setting items. :param register_security_blueprint: flag to specify if the Flask-Security to register blueprint or not. """ app = Flask(package_name, instance_relative_config=True) # 增加matrix转换器 app.url_map.converters['matrix'] = MatrixConverter # principal identity_loaded.connect_via(app)(_app_on_identity_loaded) # 公共配置 app.config.from_object(setting) # 可以被覆盖的配置,如在测试情况里 app.config.from_object(settings_override) # 加载security翻译配置 if app.config.has_key('SECURITY_TRANSLATION_PATH'): import importlib security_translate = importlib.import_module(app.config['SECURITY_TRANSLATION_PATH']) app.config.from_object(security_translate) # 使用这样的方式init,不能调用db.create_all() db.init_app(app) mail.init_app(app) # init babel babel.init_app(app) # init Flask-Security security_datastore = SQLAlchemyUserDatastore(db, User, Role) security.init_app(app, security_datastore, register_blueprint=register_security_blueprint) # 注册view register_blueprints(app, package_name, package_path) # 邮件log if not app.debug and not app.testing: import logging from logging.handlers import RotatingFileHandler mail_handler = SslSTMPHandler((app.config['MAIL_SERVER'], app.config['MAIL_PORT']), app.config['MAIL_DEFAULT_SENDER'], app.config['ADMINS'], 'kinoris.com failed!', credentials=(app.config['MAIL_USERNAME'], app.config['MAIL_PASSWORD'])) mail_handler.setLevel(logging.ERROR) mail_handler.setFormatter( logging.Formatter('%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]')) app.logger.addHandler(mail_handler) # 文件log import os if not os.path.exists(app.config['LOGGING_DIR']): os.makedirs(app.config['LOGGING_DIR']) # 一般日志 file_handler = RotatingFileHandler(os.path.join(app.config['LOGGING_DIR'], 'app.log'), mode='a', maxBytes=5 * 1024 * 1024, backupCount=10, encoding='utf-8') file_handler.setFormatter( logging.Formatter('%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]')) file_handler.setLevel(logging.INFO) app.logger.addHandler(file_handler) # 错误日志 file_handler_error = RotatingFileHandler(os.path.join(app.config['LOGGING_DIR'], 'app_error.log'), mode='a', maxBytes=5 * 1024 * 1024, backupCount=10, encoding='utf-8') file_handler_error.setFormatter( logging.Formatter('%(asctime)s %(levelname)s: %(message)s [in %(pathname)s:%(lineno)d]')) file_handler_error.setLevel(logging.ERROR) app.logger.addHandler(file_handler_error) # 默认log app.logger.setLevel(logging.INFO) app.logger.info(str.format('{0} startup.', app.name)) return app
def _init_principal(self): self.principal = Principal(self.app, use_sessions=False) self.principal.identity_loader = self._identity_loader identity_loaded.connect_via(self.app)(self._on_identity_loaded)
def init_app(self, app, datastore=None, register_blueprint=None, **kwargs): """Initializes the Flask-Security extension for the specified application and datastore implementation. :param app: The application. :param datastore: An instance of a user datastore. :param register_blueprint: to register the Security blueprint or not. """ self.app = app if datastore is None: datastore = self._datastore if register_blueprint is None: register_blueprint = self._register_blueprint for key, value in self._kwargs.items(): kwargs.setdefault(key, value) if "render_template" not in kwargs: kwargs.setdefault("render_template", self.render_template) if "send_mail" not in kwargs: kwargs.setdefault("send_mail", self.send_mail) for key, value in _default_config.items(): app.config.setdefault("SECURITY_" + key, value) for key, value in _default_messages.items(): app.config.setdefault("SECURITY_MSG_" + key, value) identity_loaded.connect_via(app)(_on_identity_loaded) self._state = state = _get_state(app, datastore, **kwargs) if register_blueprint: app.register_blueprint(create_blueprint(state, __name__)) app.context_processor(_context_processor) @app.before_first_request def _register_i18n(): if "_" not in app.jinja_env.globals: app.jinja_env.globals["_"] = state.i18n_domain.gettext app.extensions["security"] = state if hasattr(app, "cli"): from .cli import users, roles if state.cli_users_name: app.cli.add_command(users, state.cli_users_name) if state.cli_roles_name: app.cli.add_command(roles, state.cli_roles_name) # Two factor configuration checks and setup if cv("TWO_FACTOR", app=app): if len(cv("TWO_FACTOR_ENABLED_METHODS", app=app)) < 1: raise ValueError( "Must configure some TWO_FACTOR_ENABLED_METHODS") self.check_two_factor_modules("pyqrcode", "TWO_FACTOR", cv("TWO_FACTOR", app=app)) self.check_two_factor_modules("cryptography", "TWO_FACTOR_SECRET", "has been set") if cv("TWO_FACTOR_SMS_SERVICE", app=app) == "Twilio": # pragma: no cover self.check_two_factor_modules( "twilio", "TWO_FACTOR_SMS_SERVICE", cv("TWO_FACTOR_SMS_SERVICE", app=app), ) state.totp_factory(tf_setup(app)) return state
def init_app(self, app, datastore=None, register_blueprint=None, **kwargs): """Initializes the Flask-Security extension for the specified application and datastore implementation. :param app: The application. :param datastore: An instance of a user datastore. :param register_blueprint: to register the Security blueprint or not. """ self.app = app if datastore is None: datastore = self._datastore if register_blueprint is None: register_blueprint = self._register_blueprint for key, value in self._kwargs.items(): kwargs.setdefault(key, value) if "render_template" not in kwargs: kwargs.setdefault("render_template", self.render_template) if "json_encoder_cls" not in kwargs: kwargs.setdefault("json_encoder_cls", FsJsonEncoder) if "totp_cls" not in kwargs: kwargs.setdefault("totp_cls", Totp) for key, value in _default_config.items(): app.config.setdefault("SECURITY_" + key, value) for key, value in _default_messages.items(): app.config.setdefault("SECURITY_MSG_" + key, value) identity_loaded.connect_via(app)(_on_identity_loaded) self._state = state = _get_state(app, datastore, **kwargs) if register_blueprint: bp = create_blueprint(state, __name__, json_encoder=kwargs["json_encoder_cls"]) app.register_blueprint(bp) app.context_processor(_context_processor) @app.before_first_request def _register_i18n(): # N.B. as of jinja 2.9 '_' is always registered # http://jinja.pocoo.org/docs/2.10/extensions/#i18n-extension if "_" not in app.jinja_env.globals: current_app.jinja_env.globals["_"] = state.i18n_domain.gettext # Register so other packages can reference our translations. current_app.jinja_env.globals[ "_fsdomain"] = state.i18n_domain.gettext @app.before_first_request def _csrf_init(): # various config checks - some of these are opinionated in that there # could be a reason for some of these combinations - but in general # they cause strange behavior. # WTF_CSRF_ENABLED defaults to True if not set in Flask-WTF if not current_app.config.get("WTF_CSRF_ENABLED", True): return csrf = current_app.extensions.get("csrf", None) # If they don't want ALL mechanisms protected, then they must # set WTF_CSRF_CHECK_DEFAULT=False so that our decorators get control. if cv("CSRF_PROTECT_MECHANISMS") != AUTHN_MECHANISMS: if not csrf: # This isn't good. raise ValueError("CSRF_PROTECT_MECHANISMS defined but" " CsrfProtect not part of application") if current_app.config.get("WTF_CSRF_CHECK_DEFAULT", True): raise ValueError( "WTF_CSRF_CHECK_DEFAULT must be set to False if" " CSRF_PROTECT_MECHANISMS is set") # We don't get control unless they turn off WTF_CSRF_CHECK_DEFAULT if # they have enabled global CSRFProtect. if (cv("CSRF_IGNORE_UNAUTH_ENDPOINTS") and csrf and current_app.config.get( "WTF_CSRF_CHECK_DEFAULT", False)): raise ValueError( "To ignore unauth endpoints you must set WTF_CSRF_CHECK_DEFAULT" " to False") csrf_cookie = cv("CSRF_COOKIE") if csrf_cookie and csrf_cookie["key"] and not csrf: # Common use case is for cookie value to be used as contents for header # which is only looked at when CsrfProtect is initialized. # Yes, this is opinionated - they can always get CSRF token via: # 'get /login' raise ValueError( "CSRF_COOKIE defined however CsrfProtect not part of application" ) if csrf: csrf.exempt("flask_security.views.logout") if csrf_cookie and csrf_cookie["key"]: current_app.after_request(csrf_cookie_handler) # Add configured header to WTF_CSRF_HEADERS current_app.config["WTF_CSRF_HEADERS"].append( cv("CSRF_HEADER")) app.extensions["security"] = state if hasattr(app, "cli"): from .cli import users, roles if state.cli_users_name: app.cli.add_command(users, state.cli_users_name) if state.cli_roles_name: app.cli.add_command(roles, state.cli_roles_name) # Two factor configuration checks and setup if cv("TWO_FACTOR", app=app): if len(cv("TWO_FACTOR_ENABLED_METHODS", app=app)) < 1: raise ValueError( "Must configure some TWO_FACTOR_ENABLED_METHODS") self._check_modules("pyqrcode", "TWO_FACTOR", cv("TWO_FACTOR", app=app)) self._check_modules("cryptography", "TWO_FACTOR_SECRET", "has been set") if cv("TWO_FACTOR_SMS_SERVICE", app=app) == "Twilio": # pragma: no cover self._check_modules( "twilio", "TWO_FACTOR_SMS_SERVICE", cv("TWO_FACTOR_SMS_SERVICE", app=app), ) secrets = cv("TWO_FACTOR_SECRET", app=app) issuer = cv("TWO_FACTOR_URI_SERVICE_NAME", app=app) state.totp_factory(state.totp_cls(secrets, issuer)) if cv("USE_VERIFY_PASSWORD_CACHE", app=app): self._check_modules("cachetools", "USE_VERIFY_PASSWORD_CACHE", True) return state
def create_app(test_config=None): from flowauth.config import get_config from flowauth.models import db from flowauth.cli import ( init_db_command, add_admin_command, make_flowauth_fernet_key, demo_data, ) from .admin import blueprint as admin_blueprint from .users import blueprint as users_blueprint from .groups import blueprint as groups_blueprint from .servers import blueprint as servers_blueprint from .token_management import blueprint as token_management_blueprint from .login import blueprint as login_blueprint from .user_settings import blueprint as user_settings_blueprint from .version import blueprint as version_blueprint app = Flask(__name__) app.config.from_mapping(get_config()) # Connect the logger app.before_first_request(connect_logger) if test_config is not None: # load the test config if passed in app.config.update(test_config) # Connect the db db.init_app(app) # Set up flask-login login_manager = LoginManager() login_manager.init_app(app) # Set up flask-principal for roles management principals = Principal() principals.init_app(app) # Set up csrf protection csrf = CSRFProtect() csrf.init_app(app) csrf.exempt(login_blueprint) csrf.exempt(version_blueprint) app.register_blueprint(login_blueprint) app.register_blueprint(admin_blueprint, url_prefix="/admin") app.register_blueprint(groups_blueprint, url_prefix="/admin") app.register_blueprint(servers_blueprint, url_prefix="/admin") app.register_blueprint(users_blueprint, url_prefix="/admin") app.register_blueprint(token_management_blueprint, url_prefix="/tokens") app.register_blueprint(user_settings_blueprint, url_prefix="/user") app.register_blueprint(version_blueprint) if app.config["DEMO_MODE"]: # Create demo data from flowauth.models import make_demodata app.before_first_request(make_demodata) else: # Initialise the database from flowauth.models import init_db from flowauth.models import add_admin app.before_first_request(lock(partial(init_db, force=app.config["RESET_DB"]))) # Create an admin user app.before_first_request( lock( partial( add_admin, username=app.config["ADMIN_USER"], password=app.config["ADMIN_PASSWORD"], ) ) ) app.before_first_request( app.config["DB_IS_SET_UP"].wait ) # Cause workers to wait for db to set up app.after_request(set_xsrf_cookie) app.errorhandler(CSRFError)(handle_csrf_error) app.errorhandler(InvalidUsage)(handle_invalid_usage) app.before_request(before_request) login_manager.user_loader(load_user) identity_loaded.connect_via(app)(on_identity_loaded) # Add flask <command> CLI commands app.cli.add_command(demo_data) app.cli.add_command(init_db_command) app.cli.add_command(add_admin_command) app.cli.add_command(make_flowauth_fernet_key) return app