rollbar.init( # access token for the demo app: https://rollbar.com/demo access_token, # environment name _env, # server root directory, makes tracebacks prettier root=os.path.dirname(os.path.realpath(__file__)), # flask already sets up logging allow_logging_basic_config=False) def emit(self, record): if record.exc_info: rollbar.report_exc_info(record.exc_info) else: request = None rollbar.report_message(record.msg, record.levelname, request=request) def rollbar_init_app(app): got_request_exception.connect(rollbar.contrib.flask.report_exception, app) # Init app init_app(rollbar_init_app)
Requirements: config: APPLICATION_NAME NEWRELIC_LICENSE_KEY """ from webportfolio import init_app, get_env import newrelic.agent newrelic.agent.initialize() settings = newrelic.agent.global_settings() class NewRelicAPM(object): _app = None _app_name = "www" def init_app(self, app): wp_application_name = app.config.get("APPLICATION_NAME") env_name = get_env().lower() app_name = "%s/%s:%s" % (wp_application_name, self._app_name, env_name) settings.app_name = app_name settings.license_key = app.config.get("NEWRELIC_LICENSE_KEY") def set_name(self, app_name): self._app_name = app_name apm = NewRelicAPM() init_app(apm.init_app)
def account(view, **kwargs): """ This view is extendable kwargs: - on_signin_view - on_signout_view - template_dir """ view_name = view.__name__ model = kwargs.pop("model") User = model.User.User nav_menu_context = dict(module_=view.__module__, class_=view.__name__) login_view = "UserAccount:login" on_signin_view = kwargs["on_signin_view"] if "on_signin_view" in kwargs else "Index:index" on_signout_view = kwargs["on_signout_view"] if "on_signout_view" in kwargs else "Index:index" template_dir = kwargs["template_dir"] if "template_dir" in kwargs else "WebPortfolio/Package/User/Account" template_page = template_dir + "/%s.html" login_manager = LoginManager() login_manager.login_view = login_view login_manager.login_message_category = "error" init_app(login_manager.init_app) @login_manager.user_loader def load_user(userid): return User.get(userid) class Account(object): decorators = view.decorators + [login_required] SESSION_KEY_SET_EMAIL_DATA = "set_email_tmp_data" TEMP_DATA_KEY = "login_tmp_data" @property def tmp_data(self): return session[self.TEMP_DATA_KEY] @tmp_data.setter def tmp_data(self, data): session[self.TEMP_DATA_KEY] = data @classmethod def _login_enabled(cls): if not cls.config_("MODULE_USER_ACCOUNT_ENABLE_LOGIN"): abort(403) @classmethod def _signup_enabled(cls): if not cls.config_("MODULE_USER_ACCOUNT_ENABLE_SIGNUP"): abort(403) @classmethod def login_user(cls, user): login_user(user) now = datetime.datetime.now() user.update(last_login=now, last_visited=now) @classmethod def _oauth_enabled(cls): if not cls.config_("MODULE_USER_ACCOUNT_ENABLE_OAUTH_LOGIN"): abort(403) @nav_menu("Login", endpoint="UserAccount:login", show=user_not_authenticated, **nav_menu_context) @route("login/", methods=["GET", "POST"], endpoint="UserAccount:login") @no_login_required def login(self): """ Login page """ self._login_enabled() logout_user() self.tmp_data = None self.meta_(title="Login") if request.method == "POST": email = request.form.get("email").strip() password = request.form.get("password").strip() if not email or not password: flash_error("Email or Password is empty") return redirect(url_for(login_view, next=request.form.get("next"))) user = User.get_by_email(email) if user and user.password_hash and user.password_matched(password): self.login_user(user) return redirect(request.form.get("next") or url_for(on_signin_view)) else: flash_error("Email or Password is invalid") return redirect(url_for(login_view, next=request.form.get("next"))) return self.render_( login_url_next=request.args.get("next", ""), login_url_default=url_for(on_signin_view), signup_enabled=self.config_("MODULE_USER_ACCOUNT_ENABLE_SIGNUP"), oauth_enabled=self.config_("MODULE_USER_ACCOUNT_ENABLE_OAUTH_LOGIN"), view_template_=template_page % "login", ) @nav_menu("Logout", endpoint="UserAccount:logout", show=user_authenticated, order=100, **nav_menu_context) @route("logout/", endpoint="UserAccount:logout") @no_login_required def logout(self): logout_user() return redirect(url_for(on_signout_view or login_view)) @nav_menu("Signup", endpoint="UserAccount:signup", show=[user_not_authenticated], **nav_menu_context) @route("signup/", methods=["GET", "POST"], endpoint="UserAccount:signup") @no_login_required def signup(self): """ For Email Signup :return: """ self._login_enabled() self._signup_enabled() self.meta_(title="Signup") if request.method == "POST": # reCaptcha if not recaptcha.verify(): flash_error("Invalid Security code") return redirect(url_for("UserAccount:signup", next=request.form.get("next"))) try: name = request.form.get("name") email = request.form.get("email") password = request.form.get("password") password2 = request.form.get("password2") profile_image_url = request.form.get("profile_image_url", None) if not name: raise ViewError("Name is required") elif not utils.is_valid_email(email): raise ViewError("Invalid email address '%s'" % email) elif not password.strip() or password.strip() != password2.strip(): raise ViewError("Passwords don't match") elif not utils.is_valid_password(password): raise ViewError("Invalid password") else: new_account = User.new( email=email, password=password.strip(), first_name=name, profile_image_url=profile_image_url, signup_method="email", ) self.login_user(new_account) return redirect(request.form.get("next") or url_for(on_signin_view)) except Exception as ex: flash_error(ex.message) return redirect(url_for("UserAccount:signup", next=request.form.get("next"))) logout_user() return self.render_(login_url_next=request.args.get("next", ""), view_template_=template_page % "signup") @route("lost-password/", methods=["GET", "POST"], endpoint="UserAccount:lost_password") @no_login_required def lost_password(self): self._login_enabled() logout_user() self.meta_(title="Lost Password") if request.method == "POST": email = request.form.get("email") user = User.get_by_email(email) if user: delivery = self.config_("MODULE_USER_ACCOUNT_RESET_PASSWORD_METHOD") new_password = None if delivery.upper() == "TOKEN": token = user.set_temp_login() url = url_for("UserAccount:reset_password", token=token, _external=True) else: new_password = user.set_password(password=None, random=True) url = url_for("UserAccount:login", _external=True) mailer.send_template( "reset-password.txt", method_=delivery, to=user.email, name=user.email, url=url, new_password=new_password, ) flash_success("A new password has been sent to '%s'" % email) else: flash_error("Invalid email address") return redirect(url_for(login_view)) else: return self.render_(view_template_=template_page % "lost_password") @nav_menu( "Account Settings", endpoint="UserAccount:account_settings", order=99, show=user_authenticated, **nav_menu_context ) @route("account-settings", methods=["GET", "POST"], endpoint="UserAccount:account_settings") @fresh_login_required def account_settings(self): self.meta_(title="Account Settings") if request.method == "POST": action = request.form.get("action") try: action = action.lower() # if action == "info": first_name = request.form.get("first_name").strip() last_name = request.form.get("last_name", "").strip() data = {"first_name": first_name, "last_name": last_name} current_user.update(**data) flash_success("Account info updated successfully!") # elif action == "login": confirm_password = request.form.get("confirm-password").strip() if current_user.password_matched(confirm_password): self.change_login_handler() flash_success("Login Info updated successfully!") else: flash_error("Invalid password") # elif action == "password": confirm_password = request.form.get("confirm-password").strip() if current_user.password_matched(confirm_password): self.change_password_handler() flash_success("Password updated successfully!") else: flash_error("Invalid password") elif action == "profile-photo": file = request.files.get("file") if file: prefix = "profile-photos/%s/" % current_user.id extensions = ["jpg", "jpeg", "png", "gif"] my_photo = storage.upload(file, prefix=prefix, allowed_extensions=extensions) if my_photo: url = my_photo.url current_user.update(profile_image_url=url) flash_success("Profile Image updated successfully!") else: raise ViewError("Invalid action") except Exception as e: flash_error(e.message) return redirect(url_for("UserAccount:account_settings")) return self.render_(view_template_=template_page % "account_settings") @classmethod def change_login_handler(cls, user_context=None, email=None): if not user_context: user_context = current_user if not email: email = request.form.get("email").strip() if not utils.is_valid_email(email): raise UserWarning("Invalid email address '%s'" % email) else: if email != user_context.email and User.get_by_email(email): raise UserWarning("Email exists already '%s'" % email) elif email != user_context.email: user_context.update(email=email) return True return False @classmethod def change_password_handler(cls, user_context=None, password=None, password2=None): if not user_context: user_context = current_user if not password: password = request.form.get("password").strip() if not password2: password2 = request.form.get("password2").strip() if password: if password != password2: raise UserWarning("Password don't match") elif not utils.is_valid_password(password): raise UserWarning("Invalid password") else: user_context.set_password(password) return True else: raise UserWarning("Password is empty") # OAUTH Login @route("oauth-login/<provider>", methods=["GET", "POST"], endpoint="UserAccount:oauth_login") @no_login_required def oauth_login(self, provider): """ Login via oauth providers """ self._login_enabled() self._oauth_enabled() provider = provider.lower() result = oauth.login(provider) response = oauth.response popup_js_custom = {"action": "", "url": ""} if result: if result.error: pass elif result.user: result.user.update() oauth_user = result.user user = User.get_by_oauth(provider=provider, provider_user_id=oauth_user.id) if not user: if oauth_user.email and User.get_by_email(oauth_user.email): flash_error( "Account already exists with this email '%s'. " "Try to login or retrieve your password " % oauth_user.email ) popup_js_custom.update( {"action": "redirect", "url": url_for(login_view, next=request.form.get("next"))} ) else: tmp_data = { "is_oauth": True, "provider": provider, "id": oauth_user.id, "name": oauth_user.name, "picture": oauth_user.picture, "first_name": oauth_user.first_name, "last_name": oauth_user.last_name, "email": oauth_user.email, "link": oauth_user.link, } if not oauth_user.email: self.tmp_data = tmp_data popup_js_custom.update( {"action": "redirect", "url": url_for("UserAccount:setup_login")} ) else: try: picture = oauth_user.picture user = User.new( email=oauth_user.email, name=oauth_user.name, signup_method=provider, profile_image_url=picture, ) user.add_oauth( provider, oauth_user.provider_id, name=oauth_user.name, email=oauth_user.email, profile_image_url=oauth_user.picture, link=oauth_user.link, ) except ModelError as e: flash_error(e.message) popup_js_custom.update({"action": "redirect", "url": url_for("UserAccount:login")}) if user: self.login_user(user) return self.render_( popup_js=result.popup_js(custom=popup_js_custom), view_template_=template_page % "oauth_login" ) return response @route("setup-login/", methods=["GET", "POST"], endpoint="UserAccount:setup_login") def setup_login(self): """ Allows to setup a email password if it's not provided specially coming from oauth-login :return: """ self._login_enabled() self.meta_(title="Setup Login") # Only user without email can set email if current_user.is_authenticated() and current_user.email: return redirect(url_for("%s:account_settings" % view_name)) if self.tmp_data: if request.method == "POST": if not self.tmp_data["is_oauth"]: return redirect("UserAccount:login") try: email = request.form.get("email") password = request.form.get("password") password2 = request.form.get("password2") if not utils.is_valid_email(email): raise ViewError("Invalid email address '%s'" % email) elif User.get_by_email(email): raise ViewError("An account exists already with this email address '%s' " % email) elif not password.strip() or password.strip() != password2.strip(): raise ViewError("Passwords don't match") elif not utils.is_valid_password(password): raise ViewError("Invalid password") else: user = User.new( email=email, password=password.strip(), name=self.tmp_data["name"], profile_image_url=self.tmp_data["picture"], signup_method=self.tmp_data["provider"], ) user.add_oauth( self.tmp_data["provider"], self.tmp_data["id"], name=self.tmp_data["name"], email=email, profile_image_url=self.tmp_data["picture"], link=self.tmp_data["link"], ) self.login_user(user) self.tmp_data = None return redirect(request.form.get("next") or url_for(on_signin_view)) except Exception as ex: flash_error(ex.message) return redirect(url_for("UserAccount:setup_login")) return self.render_(provider=self.tmp_data, view_template_=template_page % "setup_login") else: return redirect(url_for("UserAccount:login")) @route("reset-password/<token>", methods=["GET", "POST"], endpoint="UserAccount:reset_password") @no_login_required def reset_password(self, token): self._login_enabled() logout_user() self.meta_(title="Reset Password") user = User.get_by_temp_login(token) if user: if not user.has_temp_login: return redirect(url_for(on_signin_view)) if request.method == "POST": try: self.change_password_handler(user_context=user) user.clear_temp_login() flash_success("Password updated successfully!") return redirect(url_for(on_signin_view)) except Exception as ex: flash_error("Error: %s" % ex.message) return redirect(url_for("UserAccount:reset_password", token=token)) else: return self.render_(token=token, view_template_=template_page % "reset_password") else: abort(404, "Invalid token") @route("oauth-connect", methods=["POST"], endpoint="UserAccount:oauth_connect") def oauth_connect(self): """ To login via social """ email = request.form.get("email").strip() name = request.form.get("name").strip() provider = request.form.get("provider").strip() provider_user_id = request.form.get("provider_user_id").strip() image_url = request.form.get("image_url").strip() next = request.form.get("next", "") try: current_user.oauth_connect( provider=provider, provider_user_id=provider_user_id, email=email, name=name, image_url=image_url ) except Exception as ex: flash_error("Unable to link your account") return redirect(url_for("%s:account_settings" % view_name)) return Account
You may place your models here. """ from active_alchemy import SQLAlchemy import config from webportfolio import init_app, get_env_config from webportfolio.packages import user, cms # The config conf = get_env_config(config) # Connect the DB db = SQLAlchemy(conf.SQL_URI) # Attach the Active SQLAlchemy init_app(db.init_app) # ------------------------------------------------------------------------------ # User Model User = user.model(db) # Post Model Cms = cms.model(User) # A simple my_note table example class MyNote(db.Model): user_id = db.Column(db.Integer, db.ForeignKey(User.User.id)) title = db.Column(db.String(255)) content = db.Column(db.Text) user = db.relationship(User.User, backref="notes")