def init_app(app): db.init_app(app) cache.init_app(app) debug_toolbar.init_app(app) app.template_folder = os.path.join(os.path.dirname(__file__), 'templates/') migrate = Migrate(app, db) # Import and register the different asset bundles assets_env = Environment(app) assets_env.load_path = [os.path.join(os.path.dirname(__file__), 'static')] assets_env.directory = os.path.join(os.path.dirname(__file__), 'static') assets_env.url = '/admin/static/' # assets_env.register('js_all', js) print("directory ", assets_env.directory, os.path.join(os.path.dirname(__file__), 'static/')) assets_loader = PythonAssetsLoader(assets) for name, bundle in list(assets_loader.load_bundles().items()): assets_env.register(name, bundle) # Setup user handling from silverflask.models import User user_adapter = SQLAlchemyAdapter(db, User) user_manager = UserManager(user_adapter) user_manager.init_app(app) ### # SILVERFLASK ### upload_path = os.path.join(app.instance_path, app.config["SILVERFLASK_UPLOAD_PATH"]) app.config["SILVERFLASK_ABSOLUTE_UPLOAD_PATH"] = upload_path app.storage_backend = LocalFileStorageBackend(upload_path) from silverflask.controllers.page_controller import SiteTreeController app.register_blueprint(SiteTreeController.create_blueprint(app)) from silverflask.core.dev_controller import DevController app.register_blueprint(DevController.create_blueprint(app)) from silverflask.controllers.cms_controller import CMSController, PagesCMSController, FilesCMSController, \ DataObjectCMSController app.register_blueprint(CMSController.create_blueprint(app)) app.register_blueprint(DataObjectCMSController.create_blueprint(app)) app.register_blueprint(PagesCMSController.create_blueprint(app)) app.register_blueprint(FilesCMSController.create_blueprint(app)) from silverflask.controllers.security_controller import SecurityController app.register_blueprint(SecurityController.create_blueprint(app)) from silverflask.core.theme import init_themes init_themes(app) from silverflask.controllers.main import setup_processors, init_blueprint from silverflask.controllers.cms import bp as cms_bp setup_processors(app) main = init_blueprint(app) app.register_blueprint(main) app.register_blueprint(cms_bp, url_prefix='/admin') # for rule in app.url_map.iter_rules(): # print(rule) return app
def init_user_manager(app): from flask_user import SQLAlchemyAdapter, UserManager from ..core import db from ..model import User from ..service import userService from .. import signals db_adapter = SQLAlchemyAdapter(db, User) user_manager = UserManager(db_adapter) user_manager.init_app(app) import hashlib def hash_password(self, password): _md5 = hashlib.md5() _md5.update(password) return _md5.hexdigest() def generate_password_hash(self, password): _md5 = hashlib.md5() _md5.update(password) return _md5.hexdigest() def verify_password(self, password, user): return self.hash_password(password) == user.password def login_manager_usercallback(user_id): user_id = int(user_id) if isinstance(user_id, basestring) else int(user_id) user_dict = userService.user_by_id(user_id) return User(**user_dict) user_manager.hash_password = hash_password.__get__(user_manager, UserManager) user_manager.generate_password_hash = generate_password_hash.__get__( user_manager, UserManager) user_manager.verify_password = verify_password.__get__( user_manager, UserManager) user_manager.login_manager.user_callback = login_manager_usercallback
def create_app(config=None): """ Application factory - this is used so that we can create a dev|test|prod application instance based on parameter :param config: :return: """ app = Flask(__name__) if not config: config = 'development' config = config_factory.get(config) app.config.from_object(config) # override config with env file cfg app.config.update(os.environ) # initialize extensions from store.database import User db_adapter = SQLAlchemyAdapter(db, User) user_manager = UserManager(db_adapter) db.init_app(app) migrate.init_app(app, db) celery.init_app(app) user_manager.init_app(app) csrf.init_app(app) # configure_uploads(app, (review_images, )) # patch_request_class(app, Constants.MAX_FILE_SIZE) # register blueprints from webapp.client import client app.register_blueprint(client) from webapp.media import media app.register_blueprint(media, url_prefix='/media') return app
def init_user_manager(app): from flask_user import SQLAlchemyAdapter, UserManager from ..core import db, FromCache from ..models import Account from .user_login import login from .user_register import register from .user_forgot_password import forgot_password from ..tasks import send_email import hashlib from flask.ext.wtf import Form from wtforms import BooleanField, HiddenField, PasswordField, SubmitField, StringField from wtforms import validators, ValidationError def hash_password(self, password): _md5 = hashlib.md5() _md5.update(password) return _md5.hexdigest() def generate_password_hash(self, password): _md5 = hashlib.md5() _md5.update(password) return _md5.hexdigest() def verify_password(self, password, user): return self.hash_password(password) == user.password def login_manager_usercallback(account_id): account_id = int(account_id) if isinstance(account_id, basestring) else account_id account = db.session.query(Account). \ options(FromCache('model', 'account:%d' % account_id)). \ filter(Account.id == account_id).first() return account def password_validator(form, field): """ Password must have one lowercase letter, one uppercase letter and one digit.""" # Convert string to list of characters password = list(field.data) password_length = len(password) # Count lowercase, uppercase and numbers lowers = uppers = digits = 0 for ch in password: if ch.islower(): lowers += 1 if ch.isupper(): uppers += 1 if ch.isdigit(): digits += 1 # Password must have one lowercase letter, one uppercase letter and one digit is_valid = password_length >= 6 and lowers and uppers and digits if not is_valid: raise ValidationError(u'密码至少超过6位,其中要求包含一个大写字母,一个小写字母和一个数字') class ResetPasswordForm(Form): new_password = PasswordField(u'新密码', validators=[validators.Required(u'新密码不能为空')]) retype_password = PasswordField(u'再次输入新密码', validators=[ validators.EqualTo('new_password', message=u'两次输入的新密码匹配')]) next = HiddenField() submit = SubmitField(u'修改密码') def validate(self): # Use feature config to remove unused form fields user_manager = current_app.user_manager if not user_manager.enable_retype_password: delattr(self, 'retype_password') # Add custom password validator if needed has_been_added = False for v in self.new_password.validators: if v == user_manager.password_validator: has_been_added = True if not has_been_added: self.new_password.validators.append(user_manager.password_validator) # Validate field-validators if not super(ResetPasswordForm, self).validate(): return False # All is well return True def async_send_email(recipient, subject, html_message, text_message): send_email.delay(recipient, subject, html_message, text_message) db_adapter = SQLAlchemyAdapter(db, Account) user_manager = UserManager(db_adapter, login_view_function=login, register_view_function=register, forgot_password_view_function=forgot_password, reset_password_form=ResetPasswordForm, password_validator=password_validator, send_email_function=async_send_email) user_manager.init_app(app) user_manager.hash_password = hash_password.__get__(user_manager, UserManager) user_manager.generate_password_hash = generate_password_hash.__get__(user_manager, UserManager) user_manager.verify_password = verify_password.__get__(user_manager, UserManager) user_manager.login_manager.user_callback = login_manager_usercallback orig_unauthenticated_view_function = user_manager.unauthenticated_view_function def unauthenticated_view_function(): if request.is_xhr: return jsonify({'success': False, 'error_code': errors.user_unauthenticated}) else: return orig_unauthenticated_view_function() setattr(user_manager, 'unauthenticated_view_function', unauthenticated_view_function) orig_unauthorized_view_function = user_manager.unauthorized_view_function def unauthorized_view_function(): if request.is_xhr: return jsonify({'success': False, 'error_code': errors.operation_unauthorized}) else: return orig_unauthorized_view_function() setattr(user_manager, 'unauthorized_view_function', unauthorized_view_function)
def init_user_manager(app, login_view, forgot_password_view=None): if forgot_password_view is None: forgot_password_view = forgot_password def hash_password(self, password): _md5 = hashlib.md5() _md5.update(password) return _md5.hexdigest() def generate_password_hash(self, password): _md5 = hashlib.md5() _md5.update(password) return _md5.hexdigest() def verify_password(self, password, user): auth_method = getattr(request, 'auth_method', None) if auth_method == 'basic': return self.hash_password(password) == user.password else: return False def login_manager_usercallback(account_id): account_id = int(account_id) if isinstance(account_id, basestring) else account_id return Account.from_cache_by_id(account_id) def password_validator(form, field): """ Password must have one lowercase letter, one uppercase letter and one digit.""" # Convert string to list of characters password = list(field.data) password_length = len(password) # Count lowercase, uppercase and numbers lowers = uppers = digits = 0 for ch in password: if ch.islower(): lowers += 1 if ch.isupper(): uppers += 1 if ch.isdigit(): digits += 1 # Password must have one lowercase letter, one uppercase letter and one digit is_valid = password_length >= 6 and lowers and uppers and digits if not is_valid: raise ValidationError(u'密码至少超过6位,其中要求包含一个大写字母,一个小写字母和一个数字') class ResetPasswordForm(Form): new_password = PasswordField( u'新密码', validators=[validators.DataRequired(u'新密码不能为空')]) retype_password = PasswordField(u'再次输入新密码', validators=[ validators.EqualTo( 'new_password', message=u'两次输入的新密码匹配') ]) next = HiddenField() submit = SubmitField(u'修改密码') def validate(self): # Use feature config to remove unused form fields user_manager = current_app.user_manager if not user_manager.enable_retype_password: delattr(self, 'retype_password') # Add custom password validator if needed has_been_added = False for v in self.new_password.validators: if v == user_manager.password_validator: has_been_added = True if not has_been_added: self.new_password.validators.append( user_manager.password_validator) # Validate field-validators if not super(ResetPasswordForm, self).validate(): return False # All is well return True from .tasks import send_email def async_send_email(recipient, subject, html_message, text_message): send_email.delay(recipient, subject, html_message, text_message) db_adapter = SQLAlchemyAdapter(db, Account, UserAuthClass=AccountBasicAuth) user_manager = UserManager( db_adapter, login_view_function=login_view, forgot_password_view_function=forgot_password_view, reset_password_form=ResetPasswordForm, password_validator=password_validator, send_email_function=async_send_email) user_manager.init_app(app) user_manager.hash_password = hash_password.__get__(user_manager, UserManager) user_manager.generate_password_hash = generate_password_hash.__get__( user_manager, UserManager) user_manager.verify_password = verify_password.__get__( user_manager, UserManager) user_manager.login_manager.user_callback = login_manager_usercallback orig_unauthenticated_view_function = user_manager.unauthenticated_view_function def unauthenticated_view_function(): if request.is_xhr: return jsonify({ 'success': False, 'error_code': errors.user_unauthenticated }) else: return orig_unauthenticated_view_function() setattr(user_manager, 'unauthenticated_view_function', unauthenticated_view_function) orig_unauthorized_view_function = user_manager.unauthorized_view_function def unauthorized_view_function(): if request.is_xhr: return jsonify({ 'success': False, 'error_code': errors.operation_unauthorized }) else: return orig_unauthorized_view_function() setattr(user_manager, 'unauthorized_view_function', unauthorized_view_function)
def create_app(): """ Flask application factory """ # Setup Flask app and app.config app = Flask(__name__) app.config.from_object(__name__+'.ConfigClass') app.config['SQLALCHEMY_DATABASE_URI'] = "sqlite:///" + app.instance_path + os.sep + "users.sqlite" print(app.config['SQLALCHEMY_DATABASE_URI']) install_secret_key(app) # Initialize Flask extensions mail = Mail(app) # Initialize Flask-Mail db, user_db_adapter, User, Role = init_db(app) # Setup Flask-User def password_validator(form, field): password = field.data if len(password) < 6: raise ValidationError(('Password must have at least 6 characters')) def username_validator(form, field): """ Username must cont at least 3 alphanumeric characters long""" username = field.data if len(username) < 1: raise ValidationError(('Username must be at least 1 characters long')) user_manager = UserManager(user_db_adapter, password_validator=password_validator, username_validator=username_validator) user_manager.init_app(app) # Initialize Flask-User # A flask/sqlalchemy/python bug? anyway sqlalchemy complains in a weird error without this line User.query # The Home page is accessible to anyone @app.route('/') @login_required def home_page(): return render_template("index.html", current_user=current_user) # The Home page is accessible to anyone @app.route('/keyring/<name>') @login_required def keyring(name): found = False for r in current_user.roles: found = found or r.name == name if not found: return "Not authorized" return render_template("keyring.html", keyring=name) @app.route('/grid', methods=["POST", "GET"]) @login_required @roles_required('hacker') def grid(): if request.method == "POST": user = db.session.query(User).filter(User.id==request.form["user"]).first() role = db.session.query(Role).filter(Role.id==request.form["role"]).first() if "val" in request.form and request.form["val"] == "on": user.roles.append(role) else: if role in user.roles: user.roles.remove(role) db.session.commit() return render_template("grid.html", users=db.session.query(User), roles=db.session.query(Role), user_reset_id = "-1", newpass = "") @app.route('/grid/reset/<user_id>') @login_required @roles_required('hacker') def reset_grid(user_id): user = db.session.query(User).filter(User.id==int(user_id)).first() newpass = id_generator() user.password = user_manager.hash_password(newpass) db.session.commit() return render_template("grid.html", users=db.session.query(User), roles=db.session.query(Role), newpass=newpass, user_reset_id=user_id) @app.route('/new', methods=["POST", "GET"]) @login_required @roles_required('hacker') def new(): if request.method == "POST": rolename = request.form["role"] if not db.session.query(Role).filter(Role.name==rolename).first(): new_role = Role(name=rolename) db.session.add(new_role) current_user.roles.append(new_role) db.session.commit() save(rolename, True) return redirect("/grid") return render_template("create.html", users=db.session.query(User), roles=db.session.query(Role)) @app.route('/save/<name>', methods=["POST"]) @login_required def save(name, initial = False): found = False for r in current_user.roles: found = found or r.name == name if not found: return "Not authorized" if initial: if subprocess.call(["touch", name + ".txt"], cwd="db/") != 0: print("Keyring already exists??") return "error" if subprocess.call(["git", "add", name + ".txt"], cwd="db/") != 0: print("git error") return "error" subprocess.call(["git", "commit", "-m", "commit pre-web-update"], cwd="db/") with open("db/" + name + ".txt", "w") as f: f.write(request.form["data"]) f.close() if subprocess.call(["git", "add", name + ".txt"], cwd="db/") != 0: print("git error") return "error" if subprocess.call(["git", "commit", "-m", "Web update"], cwd="db/") != 0: print("git error") return "error" return "done" @app.route('/get/<name>') @login_required def get(name): found = False for r in current_user.roles: found = found or r.name == name if not found: return "Not authorized" try: with open("db/" + name + ".txt", "r") as f: return f.read() except FileNotFoundError: return "{}" return app,db, user_db_adapter, User, Role, user_manager