Ejemplo n.º 1
0
You may place your models here.
"""

from active_alchemy import SQLAlchemy
import config
from juice import init_app, get_env_config
from juice.plugins import user, publisher

# 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
Publisher = publisher.model(User.User)
"""
# A Table schema example. The table name will automatically be 'my_note'
# To change the table, set the property: __tablename__
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)
Ejemplo n.º 2
0
        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)


Ejemplo n.º 3
0
def auth(view, **kwargs):
    """
    This plugin allow user to login to application

    kwargs:
        - signin_view
        - signout_view
        - template_dir
        - menu:
            - name
            - group_name
            - ...

        @plugin(user.login, model=model.User)
        class MyAccount(Juice):
            pass

    """

    endpoint_namespace = view.__name__ + ":%s"
    view_name = view.__name__
    UserModel = kwargs.pop("model")
    User = UserModel.User

    login_view = endpoint_namespace % "login"
    on_signin_view = kwargs.get("signin_view", "Index:index")
    on_signout_view = kwargs.get("signout_view", "Index:index")
    template_dir = kwargs.get("template_dir", "Juice/Plugin/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)

    menu_context = view
    _menu = kwargs.get("menu", {})
    if _menu:

        @menu(**_menu)
        class UserAccountMenu(object):
            pass

        menu_context = UserAccountMenu

    @login_manager.user_loader
    def load_user(userid):
        return User.get(userid)

    View.g(__USER_AUTH_ENABLED__=True)

    class Auth(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

        def _login_enabled(self):
            if self.get_config("USER_AUTH_ALLOW_LOGIN") is not True:
                abort("UserLoginDisabledError")

        def _signup_enabled(self):
            if self.get_config("USER_AUTH_ALLOW_SIGNUP") is not True:
                abort("UserSignupDisabledError")

        def _oauth_enabled(self):
            if self.get_config("USER_AUTH_ALLOW_OAUTH") is not True:
                abort("UserOAuthDisabledError")

        def _send_reset_password(self, user):
            delivery = self.get_config("USER_AUTH_PASSWORD_RESET_METHOD")
            token_reset_ttl = self.get_config("USER_AUTH_TOKEN_RESET_TTL", 60)
            new_password = None
            if delivery.upper() == "TOKEN":
                token = user.set_temp_login(token_reset_ttl)
                url = url_for(endpoint_namespace % "reset_password",
                              token=token,
                              _external=True)
            else:
                new_password = user.set_password(password=None, random=True)
                url = url_for(endpoint_namespace % "login", _external=True)

            mail.send(template="reset-password.txt",
                      method_=delivery,
                      to=user.email,
                      name=user.email,
                      url=url,
                      new_password=new_password)

        @classmethod
        def login_user(cls, user):
            login_user(user)
            now = datetime.datetime.now()
            user.update(last_login=now, last_visited=now)

        @menu("Login",
              endpoint=endpoint_namespace % "login",
              visible_with_auth_user=False,
              extends=menu_context)
        @template(template_page % "login",
                  endpoint_namespace=endpoint_namespace)
        @route("login/",
               methods=["GET", "POST"],
               endpoint=endpoint_namespace % "login")
        @no_login_required
        def login(self):
            """ Login page """

            self._login_enabled()
            logout_user()
            self.tmp_data = None
            self.meta_tags(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("Email or Password is empty", "error")
                    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("Email or Password is invalid", "error")
                    return redirect(
                        url_for(login_view, next=request.form.get("next")))

            return dict(
                login_url_next=request.args.get("next", ""),
                login_url_default=url_for(on_signin_view),
                signup_enabled=self.get_config("USER_AUTH_ALLOW_SIGNUP"),
                oauth_enabled=self.get_config("USER_AUTH_ALLOW_LOGIN"))

        @menu("Logout",
              endpoint=endpoint_namespace % "logout",
              visible_with_auth_user=True,
              order=100,
              extends=menu_context)
        @route("logout/", endpoint=endpoint_namespace % "logout")
        @no_login_required
        def logout(self):
            logout_user()
            return redirect(url_for(on_signout_view or login_view))

        @menu("Signup",
              endpoint=endpoint_namespace % "signup",
              visible_with_auth_user=False,
              extends=menu_context)
        @template(template_page % "signup",
                  endpoint_namespace=endpoint_namespace)
        @route("signup/",
               methods=["GET", "POST"],
               endpoint=endpoint_namespace % "signup")
        @no_login_required
        def signup(self):
            """
            For Email Signup
            :return:
            """
            self._login_enabled()
            self._signup_enabled()
            self.meta_tags(title="Signup")

            if request.method == "POST":
                # reCaptcha
                if not recaptcha.verify():
                    flash("Invalid Security code", "error")
                    return redirect(
                        url_for(endpoint_namespace % "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 UserError("Name is required")
                    elif not utils.is_valid_email(email):
                        raise UserError("Invalid email address '%s'" % email)
                    elif not password.strip(
                    ) or password.strip() != password2.strip():
                        raise UserError("Passwords don't match")
                    elif not utils.is_valid_password(password):
                        raise UserError("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 ApplicationError as ex:
                    flash(ex.message, "error")
                return redirect(
                    url_for(endpoint_namespace % "signup",
                            next=request.form.get("next")))

            logout_user()
            return dict(login_url_next=request.args.get("next", ""))

        @route("lost-password/",
               methods=["GET", "POST"],
               endpoint=endpoint_namespace % "lost_password")
        @template(template_page % "lost_password",
                  endpoint_namespace=endpoint_namespace)
        @no_login_required
        def lost_password(self):
            self._login_enabled()
            logout_user()

            self.meta_tags(title="Lost Password")

            if request.method == "POST":
                email = request.form.get("email")
                user = User.get_by_email(email)
                if user:
                    self._send_reset_password(user)
                    flash("A new password has been sent to '%s'" % email,
                          "success")
                else:
                    flash("Invalid email address", "error")
                return redirect(url_for(login_view))
            else:
                return {}

        @menu("Account Settings",
              endpoint=endpoint_namespace % "account_settings",
              order=99,
              visible_with_auth_user=True,
              extends=menu_context)
        @template(template_page % "account_settings",
                  endpoint_namespace=endpoint_namespace)
        @route("account-settings",
               methods=["GET", "POST"],
               endpoint=endpoint_namespace % "account_settings")
        @fresh_login_required
        def account_settings(self):
            self.meta_tags(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("Account info updated successfully!", "success")
                    #
                    elif action == "login":
                        confirm_password = request.form.get(
                            "confirm-password").strip()
                        if current_user.password_matched(confirm_password):
                            self.change_login_handler()
                            flash("Login Info updated successfully!",
                                  "success")
                        else:
                            flash("Invalid password", "error")
                    #
                    elif action == "password":
                        confirm_password = request.form.get(
                            "confirm-password").strip()
                        if current_user.password_matched(confirm_password):
                            self.change_password_handler()
                            flash("Password updated successfully!", "success")
                        else:
                            flash("Invalid password", "error")

                    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("Profile Image updated successfully!",
                                      "success")
                    else:
                        raise UserError("Invalid action")

                except Exception as e:
                    flash(e.message, "error")

                return redirect(
                    url_for(endpoint_namespace % "account_settings"))

            return {}

        @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=endpoint_namespace % "oauth_login")
        @template(template_page % "oauth_login",
                  endpoint_namespace=endpoint_namespace)
        @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(
                                "Account already exists with this email '%s'. "
                                "Try to login or retrieve your password " %
                                oauth_user.email, "error")

                            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(endpoint_namespace % "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(e.message, "error")
                                    popup_js_custom.update({
                                        "action":
                                        "redirect",
                                        "url":
                                        url_for(endpoint_namespace % "login")
                                    })
                    if user:
                        self.login_user(user)

                    return dict(
                        popup_js=result.popup_js(custom=popup_js_custom),
                        template_=template_page % "oauth_login")
            return response

        @template(template_page % "setup_login",
                  endpoint_namespace=endpoint_namespace)
        @route("setup-login/",
               methods=["GET", "POST"],
               endpoint=endpoint_namespace % "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_tags(title="Setup  Login")

            # Only user without email can set email
            if current_user.is_authenticated() and current_user.email:
                return redirect(
                    url_for(endpoint_namespace % "account_settings"))

            if self.tmp_data:
                if request.method == "POST":
                    if not self.tmp_data["is_oauth"]:
                        return redirect(endpoint_namespace % "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 UserError("Invalid email address '%s'" %
                                            email)
                        elif User.get_by_email(email):
                            raise UserError(
                                "An account exists already with this email address '%s' "
                                % email)
                        elif not password.strip(
                        ) or password.strip() != password2.strip():
                            raise UserError("Passwords don't match")
                        elif not utils.is_valid_password(password):
                            raise UserError("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 ApplicationError as ex:
                        flash(ex.message, "error")
                        return redirect(url_for(endpoint_namespace % "login"))

                return dict(provider=self.tmp_data)

            else:
                return redirect(url_for(endpoint_namespace % "login"))

        @route("reset-password/<token>",
               methods=["GET", "POST"],
               endpoint=endpoint_namespace % "reset_password")
        @template(template_page % "reset_password",
                  endpoint_namespace=endpoint_namespace)
        @no_login_required
        def reset_password(self, token):
            self._login_enabled()
            logout_user()

            self.meta_tags(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("Password updated successfully!", "success")
                        return redirect(url_for(on_signin_view))
                    except Exception as ex:
                        flash("Error: %s" % ex.message, "error")
                        return redirect(
                            url_for(endpoint_namespace % "reset_password",
                                    token=token))
                else:
                    return dict(token=token)
            else:
                abort(404, "Invalid token")

        @route("oauth-connect",
               methods=["POST"],
               endpoint="%s:oauth_connect" % endpoint_namespace)
        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("Unable to link your account", "error")

            return redirect(url_for(endpoint_namespace % "account_settings"))

    return Auth
Ejemplo n.º 4
0
def auth(view, **kwargs):
    """
    This plugin allow user to login to application

    kwargs:
        - signin_view
        - signout_view
        - template_dir
        - menu:
            - name
            - group_name
            - ...

        @plugin(user.login, model=model.User)
        class MyAccount(Juice):
            pass

    """

    endpoint_namespace = view.__name__ + ":%s"
    view_name = view.__name__
    UserModel = kwargs.pop("model")
    User = UserModel.User

    login_view = endpoint_namespace % "login"
    on_signin_view = kwargs.get("signin_view", "Index:index")
    on_signout_view = kwargs.get("signout_view", "Index:index")
    template_dir = kwargs.get("template_dir", "Juice/Plugin/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)

    menu_context = view
    _menu = kwargs.get("menu", {})
    if _menu:
        @menu(**_menu)
        class UserAccountMenu(object): pass
        menu_context = UserAccountMenu

    @login_manager.user_loader
    def load_user(userid):
        return User.get(userid)

    View.g(__USER_AUTH_ENABLED__=True)

    class Auth(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

        def _login_enabled(self):
            if self.get_config("USER_AUTH_ALLOW_LOGIN") is not True:
                abort("UserLoginDisabledError")

        def _signup_enabled(self):
            if self.get_config("USER_AUTH_ALLOW_SIGNUP") is not True:
                abort("UserSignupDisabledError")

        def _oauth_enabled(self):
            if self.get_config("USER_AUTH_ALLOW_OAUTH") is not True:
                abort("UserOAuthDisabledError")

        def _send_reset_password(self, user):
            delivery = self.get_config("USER_AUTH_PASSWORD_RESET_METHOD")
            token_reset_ttl = self.get_config("USER_AUTH_TOKEN_RESET_TTL", 60)
            new_password = None
            if delivery.upper() == "TOKEN":
                token = user.set_temp_login(token_reset_ttl)
                url = url_for(endpoint_namespace % "reset_password",
                              token=token,
                              _external=True)
            else:
                new_password = user.set_password(password=None, random=True)
                url = url_for(endpoint_namespace % "login", _external=True)

            mail.send(template="reset-password.txt",
                         method_=delivery,
                         to=user.email,
                         name=user.email,
                         url=url,
                         new_password=new_password)


        @classmethod
        def login_user(cls, user):
            login_user(user)
            now = datetime.datetime.now()
            user.update(last_login=now, last_visited=now)

        @menu("Login",
              endpoint=endpoint_namespace % "login",
              visible_with_auth_user=False,
              extends=menu_context)
        @template(template_page % "login",
                  endpoint_namespace=endpoint_namespace)
        @route("login/",
               methods=["GET", "POST"],
               endpoint=endpoint_namespace % "login")
        @no_login_required
        def login(self):
            """ Login page """

            self._login_enabled()
            logout_user()
            self.tmp_data = None
            self.meta_tags(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("Email or Password is empty", "error")
                    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("Email or Password is invalid", "error")
                    return redirect(url_for(login_view, next=request.form.get("next")))

            return dict(login_url_next=request.args.get("next", ""),
                        login_url_default=url_for(on_signin_view),
                        signup_enabled=self.get_config("USER_AUTH_ALLOW_SIGNUP"),
                        oauth_enabled=self.get_config("USER_AUTH_ALLOW_LOGIN"))

        @menu("Logout",
              endpoint=endpoint_namespace % "logout",
              visible_with_auth_user=True,
              order=100,
              extends=menu_context)
        @route("logout/",
               endpoint=endpoint_namespace % "logout")
        @no_login_required
        def logout(self):
            logout_user()
            return redirect(url_for(on_signout_view or login_view))

        @menu("Signup",
              endpoint=endpoint_namespace % "signup",
              visible_with_auth_user=False,
              extends=menu_context)
        @template(template_page % "signup",
                  endpoint_namespace=endpoint_namespace)
        @route("signup/",
               methods=["GET", "POST"],
               endpoint=endpoint_namespace % "signup")
        @no_login_required
        def signup(self):
            """
            For Email Signup
            :return:
            """
            self._login_enabled()
            self._signup_enabled()
            self.meta_tags(title="Signup")

            if request.method == "POST":
                # reCaptcha
                if not recaptcha.verify():
                    flash("Invalid Security code", "error")
                    return redirect(url_for(endpoint_namespace % "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 UserError("Name is required")
                    elif not utils.is_valid_email(email):
                        raise UserError("Invalid email address '%s'" % email)
                    elif not password.strip() or password.strip() != password2.strip():
                        raise UserError("Passwords don't match")
                    elif not utils.is_valid_password(password):
                        raise UserError("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 ApplicationError as ex:
                    flash(ex.message, "error")
                return redirect(url_for(endpoint_namespace % "signup",
                                        next=request.form.get("next")))

            logout_user()
            return dict(login_url_next=request.args.get("next", ""))

        @route("lost-password/",
               methods=["GET", "POST"],
               endpoint=endpoint_namespace % "lost_password")
        @template(template_page % "lost_password",
                  endpoint_namespace=endpoint_namespace)
        @no_login_required
        def lost_password(self):
            self._login_enabled()
            logout_user()

            self.meta_tags(title="Lost Password")

            if request.method == "POST":
                email = request.form.get("email")
                user = User.get_by_email(email)
                if user:
                    self._send_reset_password(user)
                    flash("A new password has been sent to '%s'" % email, "success")
                else:
                    flash("Invalid email address", "error")
                return redirect(url_for(login_view))
            else:
                return {}


        @menu("Account Settings",
              endpoint=endpoint_namespace % "account_settings",
              order=99,
              visible_with_auth_user=True,
              extends=menu_context)
        @template(template_page % "account_settings",
                  endpoint_namespace=endpoint_namespace)
        @route("account-settings",
               methods=["GET", "POST"],
               endpoint=endpoint_namespace % "account_settings")
        @fresh_login_required
        def account_settings(self):
            self.meta_tags(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("Account info updated successfully!", "success")
                    #
                    elif action == "login":
                        confirm_password = request.form.get("confirm-password").strip()
                        if current_user.password_matched(confirm_password):
                            self.change_login_handler()
                            flash("Login Info updated successfully!", "success")
                        else:
                            flash("Invalid password", "error")
                    #
                    elif action == "password":
                        confirm_password = request.form.get("confirm-password").strip()
                        if current_user.password_matched(confirm_password):
                            self.change_password_handler()
                            flash("Password updated successfully!", "success")
                        else:
                            flash("Invalid password", "error")

                    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("Profile Image updated successfully!", "success")
                    else:
                        raise UserError("Invalid action")

                except Exception as e:
                    flash(e.message, "error")

                return redirect(url_for(endpoint_namespace % "account_settings"))

            return {}

        @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=endpoint_namespace % "oauth_login")
        @template(template_page % "oauth_login",
                  endpoint_namespace=endpoint_namespace)
        @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("Account already exists with this email '%s'. "
                                        "Try to login or retrieve your password " % oauth_user.email, "error")

                            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(endpoint_namespace % "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(e.message, "error")
                                    popup_js_custom.update({
                                        "action": "redirect",
                                        "url": url_for(endpoint_namespace % "login")
                                    })
                    if user:
                        self.login_user(user)

                    return dict(popup_js=result.popup_js(custom=popup_js_custom),
                                template_=template_page % "oauth_login")
            return response

        @template(template_page % "setup_login",
                  endpoint_namespace=endpoint_namespace)
        @route("setup-login/", methods=["GET", "POST"], 
               endpoint=endpoint_namespace % "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_tags(title="Setup  Login")

            # Only user without email can set email
            if current_user.is_authenticated() and current_user.email:
                return redirect(url_for(endpoint_namespace % "account_settings"))

            if self.tmp_data:
                if request.method == "POST":
                    if not self.tmp_data["is_oauth"]:
                        return redirect(endpoint_namespace % "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 UserError("Invalid email address '%s'" % email)
                        elif User.get_by_email(email):
                            raise UserError("An account exists already with this email address '%s' " % email)
                        elif not password.strip() or password.strip() != password2.strip():
                            raise UserError("Passwords don't match")
                        elif not utils.is_valid_password(password):
                            raise UserError("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 ApplicationError as ex:
                        flash(ex.message, "error")
                        return redirect(url_for(endpoint_namespace % "login"))

                return dict(provider=self.tmp_data)

            else:
                return redirect(url_for(endpoint_namespace % "login"))

        @route("reset-password/<token>",
               methods=["GET", "POST"],
               endpoint=endpoint_namespace % "reset_password")
        @template(template_page % "reset_password",
                  endpoint_namespace=endpoint_namespace)
        @no_login_required
        def reset_password(self, token):
            self._login_enabled()
            logout_user()

            self.meta_tags(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("Password updated successfully!", "success")
                        return redirect(url_for(on_signin_view))
                    except Exception as ex:
                        flash("Error: %s" % ex.message, "error")
                        return redirect(url_for(endpoint_namespace % "reset_password",
                                                token=token))
                else:
                    return dict(token=token)
            else:
                abort(404, "Invalid token")

        @route("oauth-connect", methods=["POST"], 
               endpoint="%s:oauth_connect" % endpoint_namespace)
        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("Unable to link your account", "error")

            return redirect(url_for(endpoint_namespace % "account_settings"))

    return Auth
Ejemplo n.º 5
0
Requirements:
    config:
        APPLICATION_NAME
        NEWRELIC_LICENSE_KEY
"""

from juice 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)