コード例 #1
0
    def checkout(self):
        '''Submit of default checkout

        A GET to the method will result in passing of control to begin as
        that is basically the entry point to the checkout

        A POST to the method will result in the confirmation of the order and
        subsequent handling of data.
        '''
        cart_obj = Pool().get('nereid.cart')
        sale_obj = Pool().get('sale.sale')

        cart = cart_obj.open_cart()
        if not cart.sale:
            # This case is possible if the user changes his currency at
            # the point of checkout and the cart gets cleared.
            return redirect(url_for('nereid.cart.view_cart'))

        sale = cart.sale
        if not sale.lines:
            flash(_("Add some items to your cart before you checkout!"))
            return redirect(url_for('nereid.website.home'))
        if request.method == 'GET':
            return (self._begin_guest() if request.is_guest_user \
                else self._begin_registered())

        elif request.method == 'POST':
            form, do_process = self._submit_guest() if request.is_guest_user \
                else self._submit_registered()
            if do_process:
                # Process Shipping
                self._process_shipment(sale, form)

                # Process Payment, if the returned value from the payment
                # is a response object (isinstance) then return that instead
                # of the success page. This will allow reidrects to a third 
                # party gateway or service to collect payment.
                response = self._process_payment(sale, form)
                if isinstance(response, BaseResponse):
                    return response

                if sale.state == 'draft':
                    # Ensure that the order date is that of today
                    cart_obj.check_update_date(cart)
                    # Confirm the order
                    sale_obj.quote([sale.id])
                    sale_obj.confirm([sale.id])

                flash(_("Your order #%(sale)s has been processed", sale=sale.reference))
                if request.is_guest_user:
                    return redirect(url_for('nereid.website.home'))
                else:
                    return redirect(
                        url_for(
                            'sale.sale.render', sale=sale.id, 
                            confirmation=True
                        )
                    )

            return render_template('checkout.jinja', form=form, cart=cart)
コード例 #2
0
    def facebook_authorized_login(self):
        """Authorized handler to which facebook will redirect the user to
        after the login attempt is made.
        """
        website_obj = Pool().get('nereid.website')

        facebook = website_obj.get_facebook_oauth_client()
        if facebook is None:
            return redirect(
                request.referrer or url_for('nereid.website.login')
            )

        try:
            if 'oauth_verifier' in request.args:
                data = facebook.handle_oauth1_response()
            elif 'code' in request.args:
                data = facebook.handle_oauth2_response()
            else:
                data = facebook.handle_unknown_response()
            facebook.free_request_token()
        except Exception, exc:
            current_app.logger.error("Facebook login failed", exc)
            flash(_("We cannot talk to facebook at this time. Please try again"))
            return redirect(
                request.referrer or url_for('nereid.website.login')
            )
コード例 #3
0
ファイル: cart.py プロジェクト: rahulsukla/nereid-cart-b2c
    def add_to_cart(cls):
        """
        Adds the given item to the cart if it exists or to a new cart

        The form is expected to have the following data is post

            quantity    : decimal
            product     : integer ID
            action      : set (default), add

        Response:
            'OK' if X-HTTPRequest
            Redirect to shopping cart if normal request
        """
        form = AddtoCartForm(request.form)
        if request.method == 'POST' and form.validate():
            cart = cls.open_cart(create_order=True)
            action = request.values.get('action', 'set')
            if form.quantity.data <= 0:
                flash(
                    _('Be sensible! You can only add real quantities to cart')
                )
                return redirect(url_for('nereid.cart.view_cart'))
            cls._add_or_update(
                cart.sale.id, form.product.data, form.quantity.data, action
            )
            if action == 'add':
                flash(_('The product has been added to your cart'), 'info')
            else:
                flash(_('Your cart has been updated with the product'), 'info')
            if request.is_xhr:
                return jsonify(message='OK')

        return redirect(url_for('nereid.cart.view_cart'))
コード例 #4
0
ファイル: user.py プロジェクト: openlabs/nereid-auth-github
    def github_authorized_login(cls):
        """
        Authorized handler to which github will redirect the user to
        after the login attempt is made.
        """
        github = request.nereid_website.get_github_oauth_client()
        if github is None:
            return redirect(
                request.referrer or url_for('nereid.website.login')
            )

        try:
            # The response is an oauth2 response with code. But Github API
            # requires the
            if 'oauth_verifier' in request.args:
                data = github.handle_oauth1_response()
            elif 'code' in request.args:
                data = github.handle_oauth2_response()
            else:
                data = github.handle_unknown_response()
            github.free_request_token()
        except Exception, exc:
            current_app.logger.error("Github login failed %s" % exc)
            flash(_("We cannot talk to github at this time. Please try again"))
            return redirect(
                request.referrer or url_for('nereid.website.login')
            )
コード例 #5
0
ファイル: user.py プロジェクト: openlabs/nereid-auth-linkedin
    def linkedin_authorized_login(cls):
        """Authorized handler to which linkedin will redirect the user to
        after the login attempt is made.
        """
        Party = Pool().get('party.party')

        linkedin = request.nereid_website.get_linkedin_oauth_client()
        if linkedin is None:
            return redirect(
                request.referrer or url_for('nereid.website.login')
            )

        try:
            if 'oauth_verifier' in request.args:
                data = linkedin.handle_oauth1_response()
            elif 'code' in request.args:
                data = linkedin.handle_oauth2_response()
            else:
                data = linkedin.handle_unknown_response()
            linkedin.free_request_token()
        except Exception, exc:
            current_app.logger.error("LinkedIn login failed %s" % exc)
            flash(_(
                "We cannot talk to linkedin at this time. Please try again"
            ))
            return redirect(
                request.referrer or url_for('nereid.website.login')
            )
コード例 #6
0
ファイル: blog.py プロジェクト: openlabs/nereid-blog
    def render_comments(self):
        """
        Render comments

        GET: Return json of all the comments of this post.
        POST: Create new comment for this post.
        """
        if self.state != 'Published':
            abort(404)

        # Add re_captcha if the configuration has such an option and user
        # is guest
        if 're_captcha_public' in CONFIG.options and request.is_guest_user:
            comment_form = GuestCommentForm(
                request.form, captcha={'ip_address': request.remote_addr}
            )
        else:
            comment_form = PostCommentForm(request.form)

        if request.method == 'GET':
            if self.nereid_user == request.nereid_user:
                return jsonify(comments=[
                    comment.serialize() for comment in self.comments
                ])
            return jsonify(comments=[
                comment.serialize() for comment in self.comments
                if not comment.is_spam
            ])

        # If post does not allow guest comments,
        # then dont allow guest user to comment
        if not self.allow_guest_comments and request.is_guest_user:
            flash('Guests are not allowed to write comments')
            if request.is_xhr:
                return jsonify(
                    success=False,
                    errors=['Guests are not allowed to write comments']
                )
            return redirect(url_for(
                'blog.post.render', user_id=self.nereid_user.id, uri=self.uri
            ))

        if request.method == 'POST' and comment_form.validate():
            self.write([self], {
                'comments': [('create', [{
                    'nereid_user': current_user.id
                        if not current_user.is_anonymous() else None,
                    'name': current_user.display_name
                        if not current_user.is_anonymous()
                            else comment_form.name.data,
                    'content': comment_form.content.data,
                }])]
            })

        if request.is_xhr:
            return jsonify(success=True) if comment_form.validate() \
                else jsonify(success=False, errors=comment_form.errors)
        return redirect(url_for(
            'blog.post.render', user_id=self.nereid_user.id, uri=self.uri
        ))
コード例 #7
0
ファイル: user.py プロジェクト: 2cadz/nereid
 def verify_email(self, sign, max_age=24 * 60 * 60):
     """
     Verifies the email and redirects to home page. This is a method in
     addition to the activate method which activates the account in addition
     to verifying the email.
     """
     try:
         unsigned = self._serializer.loads(
             self._signer.unsign(sign, max_age=max_age),
             salt='verification'
         )
     except SignatureExpired:
         return self.build_response(
             'The verification link has expired',
             redirect(url_for('nereid.website.home')), 400
         )
     except BadSignature:
         return self.build_response(
             'The verification token is invalid!',
             redirect(url_for('nereid.website.home')), 400
         )
     else:
         if self.id == unsigned:
             self.email_verified = True
             self.save()
             return self.build_response(
                 'Your email has been verified!',
                 redirect(url_for('nereid.website.home')), 200
             )
         else:
             return self.build_response(
                 'The verification token is invalid!',
                 redirect(url_for('nereid.website.home')), 400
             )
コード例 #8
0
ファイル: cart.py プロジェクト: 2cadz/nereid-cart-b2c
    def add_to_cart(cls):
        """
        Adds the given item to the cart if it exists or to a new cart

        The form is expected to have the following data is post

            quantity    : decimal
            product     : integer ID
            action      : set (default), add

        Response:
            'OK' if X-HTTPRequest
            Redirect to shopping cart if normal request
        """
        Product = Pool().get('product.product')

        form = AddtoCartForm()
        if form.validate_on_submit():
            cart = cls.open_cart(create_order=True)
            action = request.values.get('action', 'set')
            if form.quantity.data <= 0:
                message = _(
                    'Be sensible! You can only add real quantities to cart')
                if request.is_xhr:
                    return jsonify(message=unicode(message)), 400
                flash(message)
                return redirect(url_for('nereid.cart.view_cart'))

            if not Product(form.product.data).template.salable:
                message = _("This product is not for sale")
                if request.is_xhr:
                    return jsonify(message=unicode(message)), 400
                flash(message)
                return redirect(request.referrer)

            sale_line = cart.sale._add_or_update(
                form.product.data, form.quantity.data, action
            )

            # Validate that product availability in inventory is not less than
            # warehouse quantity
            sale_line.validate_for_product_inventory()

            sale_line.save()

            if action == 'add':
                message = _('The product has been added to your cart')
            else:
                message = _('Your cart has been updated with the product')
            if request.is_xhr:
                return jsonify(
                    message=unicode(message),
                    line=sale_line.serialize(purpose='cart')
                ), 200
            flash(message, 'info')

        return redirect(url_for('nereid.cart.view_cart'))
コード例 #9
0
ファイル: user.py プロジェクト: param107/nereid-auth-linkedin
 def linkedin_login(cls):
     """The URL to which a new request to authenticate to linedin begins
     Usually issues a redirect.
     """
     linkedin = request.nereid_website.get_linkedin_oauth_client()
     if linkedin is None:
         return redirect(request.referrer or url_for("nereid.website.login"))
     return linkedin.authorize(
         callback=url_for(
             "nereid.user.linkedin_authorized_login",
             next=request.args.get("next") or request.referrer or None,
             _external=True,
         )
     )
コード例 #10
0
ファイル: user.py プロジェクト: openlabs/nereid-auth-facebook
 def facebook_login(cls):
     """The URL to which a new request to authenticate to facebook begins
     Usually issues a redirect.
     """
     facebook = request.nereid_website.get_facebook_oauth_client()
     if facebook is None:
         return redirect(request.referrer or url_for("nereid.website.login"))
     return facebook.authorize(
         callback=url_for(
             "nereid.user.facebook_authorized_login",
             next=request.args.get("next") or request.referrer or None,
             _external=True,
         )
     )
コード例 #11
0
 def github_login(cls):
     """The URL to which a new request to authenticate to github begins
     Usually issues a redirect.
     """
     github = request.nereid_website.get_github_oauth_client()
     if github is None:
         return redirect(
             request.referrer or url_for('nereid.website.login')
         )
     return github.authorize(
         callback = url_for('nereid.user.github_authorized_login',
             next = request.args.get('next') or request.referrer or None,
             _external = True
         )
     )
コード例 #12
0
    def new_password(self):
        """Create a new password

        .. tip::

            Unlike change password this does not demand the old password.
            And hence this method will check in the session for a parameter
            called allow_new_password which has to be True. This acts as a
            security against attempts to POST to this method and changing
            password.

            The allow_new_password flag is popped on successful saving

        This is intended to be used when a user requests for a password reset.
        """
        form = NewPasswordForm(request.form)

        if request.method == "POST" and form.validate():
            if not session.get("allow_new_password", False):
                current_app.logger.debug("New password not allowed in session")
                abort(403)

            self.write(request.nereid_user.id, {"password": form.password.data})
            session.pop("allow_new_password")
            flash(_("Your password has been successfully changed! " "Please login again"))
            session.pop("user")
            return redirect(url_for("nereid.website.login"))

        return render_template("new-password.jinja", password_form=form)
コード例 #13
0
ファイル: cart.py プロジェクト: 2cadz/nereid-cart-b2c
    def delete_from_cart(cls, line):
        """
        Delete a line from the cart. The required argument in POST is:

            line_id : ID of the line

        Response: 'OK' if X-HTTPRequest else redirect to shopping cart
        """
        SaleLine = Pool().get('sale.line')

        cart = cls.open_cart()
        if not cart.sale:
            abort(404)

        try:
            sale_line, = SaleLine.search([
                ('id', '=', line),
                ('sale', '=', cart.sale.id),
            ])
        except ValueError:
            message = 'Looks like the item is already deleted.'
        else:
            SaleLine.delete([sale_line])
            message = 'The order item has been successfully removed.'

        flash(_(message))

        if request.is_xhr:
            return jsonify(message=message)

        return redirect(url_for('nereid.cart.view_cart'))
コード例 #14
0
    def serialize(self, purpose=None):
        '''
        Serialize timesheet line and returns a dictionary.
        '''
        nereid_user_obj = Pool().get('nereid.user')

        try:
            nereid_user, = nereid_user_obj.search([
                ('employee', '=', self.employee.id)
            ], limit=1)
        except ValueError:
            nereid_user = {}
        else:
            nereid_user = nereid_user.serialize('listing')

        # Render url for timesheet line is task on which this time is marked
        return {
            'create_date': self.create_date.isoformat(),
            "url": url_for(
                'project.work.render_task', project_id=self.work.parent.id,
                task_id=self.work.id,
            ),
            "objectType": self.__name__,
            "id": self.id,
            "displayName": "%dh %dm" % (self.hours, (self.hours * 60) % 60),
            "updatedBy": nereid_user,
        }
コード例 #15
0
ファイル: blog.py プロジェクト: openlabs/nereid-blog
    def new_post(cls):
        """Create a new post
        """
        post_form = BlogPostForm(request.form)

        if request.method == 'POST' and post_form.validate():
            post, = cls.create([{
                'title': post_form.title.data,
                'uri': post_form.uri.data,
                'content': post_form.content.data,
                'nereid_user': request.nereid_user.id,
                'allow_guest_comments': post_form.allow_guest_comments.data,
            }])
            if post_form.publish.data:
                cls.publish([post])
                flash('Your post has been published.')
            else:
                flash('Your post has been saved.')

            if request.is_xhr:
                return jsonify(success=True, item=post.serialize())
            return redirect(url_for(
                'blog.post.render', user_id=post.nereid_user.id,
                uri=post.uri
            ))
        if request.is_xhr:
            return jsonify(
                success=request.method != 'POST',  # False for POST, else True
                errors=post_form.errors or None,
            )
        return render_template('blog_post_form.jinja', form=post_form)
コード例 #16
0
ファイル: blog.py プロジェクト: openlabs/nereid-blog
    def edit_post(self):
        """
            Edit an existing post
        """
        if self.nereid_user != request.nereid_user:
            abort(404)

        # Search for a post with same uri
        post_form = BlogPostForm(request.form, obj=self)

        with Transaction().set_context(blog_id=self.id):
            if request.method == 'POST' and post_form.validate():
                self.title = post_form.title.data
                self.content = post_form.content.data
                self.allow_guest_comments = post_form.allow_guest_comments.data
                self.save()
                flash('Your post has been updated.')
                if request.is_xhr:
                    return jsonify(success=True, item=self.serialize())
                return redirect(url_for(
                    'blog.post.render', user_id=self.nereid_user.id,
                    uri=self.uri
                ))
        if request.is_xhr:
            return jsonify(
                success=request.method != 'POST',  # False for POST, else True
                errors=post_form.errors or None,
            )
        return render_template(
            'blog_post_edit.jinja', form=post_form, post=self
        )
コード例 #17
0
ファイル: routing.py プロジェクト: shalabhaggarwal/nereid
    def set_language(self):
        """Sets the language in the session of the user. Also try to guess the
        currency of the user, if not use the default currency of the website

        Accepted Methods: GET, POST
        Accepts XHR: Yes

        The language has to be provided in the GET arguments of POST form. It 
        is more convenient to pass the language code than the id of the 
        language because it makes it more readable in URLs
        """
        raise DeprecationWarning("Set language is deprecated")
        lang_obj = Pool().get('ir.lang')

        language = request.values.get('language')
        exists = lang_obj.search([('code', '=', language)], limit=1)

        if exists:
            flash(_('Your language preference have been saved.'))
        else:
            flash(_('Sorry! we do not speak your language yet!'))

        # redirect to the next url if given else take to home page
        redirect_to = request.values.get('next')
        if redirect_to:
            redirect_to.replace(session['language'], language)
        return redirect(
            request.values.get('next', url_for('nereid.website.home'))
            )
コード例 #18
0
ファイル: sale.py プロジェクト: rajatguptarg/nereid-checkout
    def as_json_ld(self):
        """
        Gmail markup for order line information

        https://developers.google.com/gmail/markup/reference/order
        """
        return {
            "@type": "Offer",
            "itemOffered": {
                "@type": "Product",
                "name": self.product.name,
                "sku": self.product.code,
                "url": url_for(
                    'product.product.render',
                    uri=self.product.uri,
                    _external=True
                ) if self.product.uri else None
            },
            "price": str(self.amount),
            "priceCurrency": self.sale.currency.code,
            "eligibleQuantity": {
                "@type": "QuantitativeValue",
                "value": self.quantity,
            }
        }
コード例 #19
0
    def change_password(self):
        """
        Changes the password

        .. tip::
            On changing the password, the user is logged out and the login page
            is thrown at the user
        """
        form = ChangePasswordForm(request.form)

        if request.method == "POST" and form.validate():
            user = request.nereid_user

            # Confirm the current password
            password = form.old_password.data
            password += user.salt or ""
            if isinstance(password, unicode):
                password = password.encode("utf-8")
            password_sha = hashlib.sha1(password).hexdigest()

            if password_sha == user.password:
                self.write(request.nereid_user.id, {"password": form.password.data})
                flash(_("Your password has been successfully changed! " "Please login again"))
                session.pop("user")
                return redirect(url_for("nereid.website.login"))
            else:
                flash(_("The current password you entered is invalid"))

        return render_template("change-password.jinja", change_password_form=form)
コード例 #20
0
    def registration(self):
        """
        Invokes registration of an user
        """
        registration_form = self.get_registration_form()

        if request.method == "POST" and registration_form.validate():
            existing = self.search(
                [("email", "=", request.form["email"]), ("company", "=", request.nereid_website.company.id)]
            )
            if existing:
                flash(_("A registration already exists with this email. " "Please contact customer care"))
            else:
                user_id = self.create(
                    {
                        "name": registration_form.name.data,
                        "display_name": registration_form.name.data,
                        "email": registration_form.email.data,
                        "password": registration_form.password.data,
                        "company": request.nereid_website.company.id,
                    }
                )
                self.create_act_code(user_id)
                registration.send(user_id)
                user = self.browse(user_id)
                self.send_activation_email(user)
                flash(_("Registration Complete. Check your email for activation"))
                return redirect(request.args.get("next", url_for("nereid.website.home")))

        return render_template("registration.jinja", form=registration_form)
コード例 #21
0
ファイル: party.py プロジェクト: shalabhaggarwal/nereid
    def registration(self):
        """
        Invokes registration of an user
        """
        registration_form = self.get_registration_form()

        if request.method == 'POST' and registration_form.validate():
            existing = self.search([
                ('email', '=', request.form['email']),
                ('company', '=', request.nereid_website.company.id),
                ])
            if existing:
                flash(_('A registration already exists with this email. '
                    'Please contact customer care')
                )
            else:
                user_id = self.create({
                    'name': registration_form.name.data,
                    'display_name': registration_form.name.data,
                    'email': registration_form.email.data,
                    'password': registration_form.password.data,
                    'company': request.nereid_website.company.id,
                    })
                self.create_act_code(user_id)
                registration.send(user_id)
                user = self.browse(user_id)
                self.send_activation_email(user)
                flash(
                    _('Registration Complete. Check your email for activation')
                )
                return redirect(
                    request.args.get('next', url_for('nereid.website.home'))
                )

        return render_template('registration.jinja', form=registration_form)
コード例 #22
0
ファイル: user.py プロジェクト: sharoonthomas/nereid
    def change_password(cls):
        """
        Changes the password

        .. tip::
            On changing the password, the user is logged out and the login page
            is thrown at the user
        """
        form = ChangePasswordForm(request.form)

        if request.method == 'POST' and form.validate():
            if request.nereid_user.match_password(form.old_password.data):
                cls.write(
                    [request.nereid_user],
                    {'password': form.password.data}
                )
                flash(
                    _('Your password has been successfully changed! '
                        'Please login again')
                )
                logout_user()
                return redirect(url_for('nereid.website.login'))
            else:
                flash(_("The current password you entered is invalid"))

        return render_template(
            'change-password.jinja', change_password_form=form
        )
コード例 #23
0
    def reset_account(self):
        """
        Reset the password for the user.

        .. tip::
            This does NOT reset the password, but just creates an activation
            code and sends the link to the email of the user. If the user uses
            the link, he can change his password.
        """
        if request.method == "POST":
            user_ids = self.search(
                [("email", "=", request.form["email"]), ("company", "=", request.nereid_website.company.id)]
            )

            if not user_ids:
                flash(_("Invalid email address"))
                return render_template("reset-password.jinja")

            self.create_act_code(user_ids[0], "reset")
            user = self.browse(user_ids[0])
            self.send_reset_email(user)
            flash(_("An email has been sent to your account for resetting" " your credentials"))
            return redirect(url_for("nereid.website.login"))

        return render_template("reset-password.jinja")
コード例 #24
0
ファイル: party.py プロジェクト: shalabhaggarwal/nereid
    def edit_address(self, address=None):
        """
        Create/Edit an Address

        POST will create a new address or update and existing address depending
        on the value of address.
        GET will return a new address/existing address edit form

        :param address: ID of the address
        """
        form = AddressForm(request.form, name=request.nereid_user.name)
        countries = [
            (c.id, c.name) for c in request.nereid_website.countries
            ]
        form.country.choices = countries
        if address not in (a.id for a in request.nereid_user.party.addresses):
            address = None
        if request.method == 'POST' and form.validate():
            if address is not None:
                self.write(address, {
                    'name': form.name.data,
                    'street': form.street.data,
                    'streetbis': form.streetbis.data,
                    'zip': form.zip.data,
                    'city': form.city.data,
                    'country': form.country.data,
                    'subdivision': form.subdivision.data,
                    'email': form.email.data,
                    'phone': form.phone.data,
                    })
            else:
                self.create({
                    'name': form.name.data,
                    'street': form.street.data,
                    'streetbis': form.streetbis.data,
                    'zip': form.zip.data,
                    'city': form.city.data,
                    'country': form.country.data,
                    'subdivision': form.subdivision.data,
                    'party': request.nereid_user.party.id,
                    'email': form.email.data,
                    'phone': form.email.data,
                    })
            return redirect(url_for('party.address.view_address'))
        elif request.method == 'GET' and address:
            # Its an edit of existing address, prefill data
            record = self.browse(address)
            form = AddressForm(
                name=record.name,
                street=record.street,
                streetbis=record.streetbis,
                zip=record.zip,
                city=record.city,
                country=record.country.id,
                subdivision=record.subdivision.id,
                email=record.email,
                phone=record.phone
            )
            form.country.choices = countries
        return render_template('address-edit.jinja', form=form, address=address)
コード例 #25
0
ファイル: user.py プロジェクト: 2cadz/nereid
    def reset_account(cls):
        """
        Reset the password for the user.

        .. tip::
            This does NOT reset the password, but just creates an activation
            code and sends the link to the email of the user. If the user uses
            the link, he can change his password.
        """
        form = ResetAccountForm()
        if form.validate_on_submit():
            try:
                nereid_user, = cls.search([
                    ('email', '=', form.email.data),
                    ('company', '=', current_website.company.id),
                ])
            except ValueError:
                return cls.build_response(
                    'Invalid email address',
                    render_template('reset-password.jinja'),
                    400
                )
            nereid_user.send_reset_email()
            return cls.build_response(
                'An email has been sent to your account for resetting'
                ' your credentials',
                redirect(url_for('nereid.website.login')), 200
            )
        elif form.errors:
            if request.is_xhr or request.is_json:
                return jsonify(error=form.errors), 400
            flash(_('Invalid email address.'))

        return render_template('reset-password.jinja')
コード例 #26
0
ファイル: party.py プロジェクト: baijum/nereid
    def new_password(cls):
        """Create a new password

        .. tip::

            Unlike change password this does not demand the old password.
            And hence this method will check in the session for a parameter
            called allow_new_password which has to be True. This acts as a
            security against attempts to POST to this method and changing
            password.

            The allow_new_password flag is popped on successful saving

        This is intended to be used when a user requests for a password reset.
        """
        form = NewPasswordForm(request.form)

        if request.method == 'POST' and form.validate():
            if not session.get('allow_new_password', False):
                current_app.logger.debug('New password not allowed in session')
                abort(403)

            cls.write(
                [request.nereid_user],
                {'password': form.password.data}
            )
            session.pop('allow_new_password')
            flash(_(
                'Your password has been successfully changed! '
                'Please login again'))
            session.pop('user')
            return redirect(url_for('nereid.website.login'))

        return render_template('new-password.jinja', password_form=form)
コード例 #27
0
ファイル: user.py プロジェクト: sharoonthomas/nereid
    def activate(self, sign, max_age=24 * 60 * 60):
        """A web request handler for activation of the user account. This
        method verifies the email and if it succeeds, activates the account.

        If your workflow requires a manual approval of every account, override
        this to not activate an account, or make a no op out of this method.

        If all what you require is verification of email, `verify_email` method
        could be used.
        """
        try:
            unsigned = self._serializer.loads(
                self._signer.unsign(sign, max_age=max_age),
                salt='activation'
            )
        except SignatureExpired:
            flash(_("The activation link has expired"))
        except BadSignature:
            flash(_("The activation token is invalid!"))
        else:
            if self.id == unsigned:
                self.active = True
                self.email_verified = True
                self.save()
                flash(_('Your account has been activated. Please login now.'))
            else:
                flash(_('Invalid Activation Code'))

        return redirect(url_for('nereid.website.login'))
コード例 #28
0
ファイル: user.py プロジェクト: sharoonthomas/nereid
    def new_password(self, sign, max_age=24 * 60 * 60):
        """Create a new password

        This is intended to be used when a user requests for a password reset.
        The link sent out to reset the password will be a timestamped sign
        which is validated for max_age before allowing the user to set the
        new password.
        """
        form = NewPasswordForm(request.form)

        if request.method == 'POST' and form.validate():
            try:
                unsigned = self._serializer.loads(
                    self._signer.unsign(sign, max_age=max_age),
                    salt='reset-password'
                )
            except SignatureExpired:
                flash(_("The password reset link has expired"))
            except BadSignature:
                flash(_('Invalid reset password code'))
            else:
                if not self.id == unsigned:
                    current_app.logger.debug('Invalid reset password code')
                    abort(403)

                self.write([self], {'password': form.password.data})
                flash(_(
                    'Your password has been successfully changed! '
                    'Please login again'))
            return redirect(url_for('nereid.website.login'))

        return render_template(
            'new-password.jinja', password_form=form, sign=sign, user=self
        )
コード例 #29
0
ファイル: task.py プロジェクト: GauravButola/nereid-project
    def delete_task(cls, task_id):
        """
        Delete the task from project

        Tasks can be deleted only if
            1. The user is project admin
            2. The user is an admin member in the project

        :param task_id: Id of the task to be deleted
        """
        task = cls.get_task(task_id)

        # Check if user is among the project admins
        if not request.nereid_user.is_admin_of_project(task.parent):
            flash(
                "Sorry! You are not allowed to delete tasks. \
                Contact your project admin for the same."
            )
            return redirect(request.referrer)

        cls.write([task], {"active": False})

        if request.is_xhr:
            return jsonify({"success": True})

        flash("The task has been deleted")
        return redirect(url_for("project.work.render_project", project_id=task.parent.id))
コード例 #30
0
ファイル: user.py プロジェクト: sharoonthomas/nereid
    def reset_account(cls):
        """
        Reset the password for the user.

        .. tip::
            This does NOT reset the password, but just creates an activation
            code and sends the link to the email of the user. If the user uses
            the link, he can change his password.
        """
        if request.method == 'POST':
            user_ids = cls.search(
                [
                    ('email', '=', request.form['email']),
                    ('company', '=', request.nereid_website.company.id),
                ]
            )

            if not user_ids or not request.form['email']:
                flash(_('Invalid email address'))
                return render_template('reset-password.jinja')

            nereid_user, = user_ids
            nereid_user.send_reset_email()
            flash(_('An email has been sent to your account for resetting'
                    ' your credentials'))
            return redirect(url_for('nereid.website.login'))

        return render_template('reset-password.jinja')
コード例 #31
0
    def edit_address(cls, address=None):
        """
        Edit an Address

        POST will update an existing address.
        GET will return a existing address edit form.

        .. version_changed:: 3.0.3.0

            For creating new address use the create_address handled instead of
            this one. The functionality would be deprecated in 3.2.X

        :param address: ID of the address
        """
        if address is None:
            warnings.warn(
                "Address creation will be deprecated from edit_address handler."
                " Use party.address.create_address instead",
                DeprecationWarning
            )
            return cls.create_address()

        address = cls(address)
        if address.party != current_user.party:
            # Check if the address belong to party
            abort(403)

        form = cls.get_address_form(address)

        if request.method == 'POST' and form.validate_on_submit():
            cls.write([address], {
                'name': form.name.data,
                'street': form.street.data,
                'streetbis': form.streetbis.data,
                'zip': form.zip.data,
                'city': form.city.data,
                'country': form.country.data,
                'subdivision': form.subdivision.data,
            })
            if form.phone.data:
                cls.write([address], {
                    'phone': form.phone.data
                })
            return redirect(url_for('party.address.view_address'))

        return render_template('address-edit.jinja', form=form, address=address)
コード例 #32
0
    def as_json_ld(self):
        """
        Gmail markup for order information

        https://developers.google.com/gmail/markup/reference/order
        """
        data = {
            "@context": "http://schema.org",
            "@type": "Order",
            "customer": {
                "@type": "Person",
                "name": self.party.name,
            },
            "merchant": {
                "@type": "Organization",
                "name": self.company.rec_name
            },
            "orderNumber": self.reference,
            "orderDate": str(
                datetime.combine(self.sale_date, datetime.min.time())
            ),
            "orderStatus": "http://schema.org/OrderStatus/OrderProcessing",
            "priceCurrency": self.currency.code,
            "price": str(self.total_amount),
            "acceptedOffer": [],
            "url": url_for(
                'sale.sale.render', active_id=self.id,
                access_code=self.guest_access_code, _external=True
            )
        }

        for line in self.lines:
            if not line.type == 'line' and not line.product:
                continue
            data["acceptedOffer"].append(line.as_json_ld())

        if self.invoice_address:
            data["billingAddress"] = {
                "@type": "PostalAddress",
                "name": self.invoice_address.name or self.party.name,
                "streetAddress": self.invoice_address.street,
                "addressLocality": self.invoice_address.city,
                "addressRegion": self.invoice_address.subdivision and self.invoice_address.subdivision.rec_name,  # noqa
                "addressCountry": self.invoice_address.country and self.invoice_address.country.rec_name  # noqa
            }
        return data
コード例 #33
0
    def render_wishlist(self):
        """
        Render specific wishlist of current user.
        rename wishlist on post  and delete on delete request
        """
        Wishlist = Pool().get('wishlist.wishlist')

        if self.nereid_user != current_user and \
                (request.method != "GET" or not self.is_public):

            abort(404)

        if request.method == "POST" and request.form.get('name'):

            name = request.form.get('name')
            wishlist = Wishlist.search([
                ('nereid_user', '=', current_user.id),
                ('id', '!=', self.id),
                ('name', '=', name),
            ],
                                       limit=1)
            if wishlist:
                flash(
                    _('Wishlist with name: %(name)s already exists.',
                      name=name))
                return redirect(request.referrer)
            else:
                self.name = name
                self.is_public = True if request.form.get('is_public') \
                    else False
                self.save()
                flash(_('Wishlist Updated'))
            if request.is_xhr:
                return 'success', 200

            return redirect(request.referrer)

        elif request.method == "DELETE":
            Wishlist.delete([self])
            if request.is_xhr:
                # TODO: send serialized data of current wishlist
                return 'success', 200

            return url_for('wishlist.wishlist.render_wishlists')

        return render_template('wishlist.jinja', wishlist=self)
コード例 #34
0
 def profile(cls):
     """
     User profile
     """
     user_form = ProfileForm(request.form, obj=request.nereid_user)
     if request.method == 'POST' and user_form.validate():
         cls.write(
             [request.nereid_user], {
                 'display_name': user_form.display_name.data,
                 'timezone': user_form.timezone.data,
             })
         flash('Your profile has been updated.')
         return redirect(
             request.args.get('next', url_for('nereid.user.profile')))
     return render_template('profile.jinja',
                            user_form=user_form,
                            active_type_name="general")
コード例 #35
0
    def create_address(cls):
        """
        Create an address for the current nereid_user

        GET
        ~~~

        Return an address creation form

        POST
        ~~~~

        Creates an address and redirects to the address view. If a next_url
        is provided, redirects there.

        .. version_added: 3.0.3.0
        """
        form = cls.get_address_form()

        if request.method == 'POST' and form.validate_on_submit():
            party = current_user.party
            address, = cls.create([{
                'name': form.name.data,
                'street': form.street.data,
                'streetbis': form.streetbis.data,
                'zip': form.zip.data,
                'city': form.city.data,
                'country': form.country.data,
                'subdivision': form.subdivision.data,
                'party': party.id,
            }])
            if form.phone.data:
                cls.write([address], {'phone': form.phone.data})
            return redirect(url_for('party.address.view_address'))

        try:
            return render_template('address-add.jinja', form=form)
        except TemplateNotFound:
            # The address-add template was introduced in 3.0.3.0
            # so just raise a deprecation warning till 3.2.X and then
            # expect the use of address-add template
            warnings.warn(
                "address-add.jinja template not found. "
                "Will be required in future versions", DeprecationWarning)
            return render_template('address-edit.jinja', form=form)
コード例 #36
0
    def manage_spam(self):
        "Mark the comment as spam"
        if not self.post.nereid_user == request.nereid_user:
            abort(403)

        self.is_spam = request.form.get('spam', False, type=bool)
        self.save()

        if request.is_xhr:
            return jsonify({
                'success': True,
            })
        else:
            flash('The comment has been updated')
            return redirect(
                url_for('blog.post.render',
                        user_id=self.post.nereid_user.id,
                        uri=self.post.uri))
コード例 #37
0
    def change_guest_permission(self):
        "Change guest permission of the post"
        if self.nereid_user != request.nereid_user:
            abort(404)

        allow_guest_comment = request.form.get('allow_guest_comments')
        self.allow_guest_comments = True if allow_guest_comment == 'true' \
            else False
        self.save()

        if request.is_xhr:
            return jsonify({
                'success': True,
            })
        return redirect(
            url_for('blog.post.render',
                    user_id=self.nereid_user.id,
                    uri=self.uri))
コード例 #38
0
    def change_state(self):
        "Change the state of the post"
        if self.nereid_user != request.nereid_user:
            abort(404)

        state = request.form.get('state')
        assert (state in ('publish', 'archive', 'draft'))
        getattr(self, str(state))([self])

        if request.is_xhr:
            return jsonify({
                'success': True,
                'new_state': self.state,
            })
        flash('Your post is now %s' % self.state)
        return redirect(
            url_for('blog.post.render',
                    user_id=self.nereid_user.id,
                    uri=self.uri))
コード例 #39
0
    def wishlist_product(cls):
        """
        Add/Remove product in wishlist.
        If wishlist_id is passed then search for wishlist and add/remove
        product else create a default wishlist and add product.

        :params
            wishlist: Get the id of wishlist
            product: Get product id
            action: add or remove, add will add product to wishlist.
                remove will unlink product from wishlist
        """
        Product = Pool().get('product.product')

        wishlist_id = request.form.get("wishlist", type=int)
        if wishlist_id:
            try:
                wishlist, = cls.search([
                    ('id', '=', wishlist_id),
                    ('nereid_user', '=', current_user.id),
                ])
            except ValueError:
                raise ValidationError("Wishlist not valid!")
        else:
            wishlist = cls._search_or_create_wishlist()
        product = Product.search([
            ('id', '=', request.form.get("product", type=int)),
            ('displayed_on_eshop', '=', True),
            ('template.active', '=', True),
        ],
                                 limit=1)
        if not product or request.form.get('action') not in ['add', 'remove']:
            abort(404)
        cls.write([wishlist], {
            'products': [(request.form.get('action'), product)],
        })
        if request.is_xhr:
            # TODO: Send serailized data of wishllist
            return 'success', 200

        return redirect(
            url_for('wishlist.wishlist.render_wishlist',
                    active_id=wishlist.id))
コード例 #40
0
    def delete_from_cart(cls, line):
        """
        Delete a line from the cart. The required argument in POST is:

            line_id : ID of the line

        Response: 'OK' if X-HTTPRequest else redirect to shopping cart
        """
        SaleLine = Pool().get('sale.line')

        sale_line = SaleLine(line)
        assert sale_line.sale.id == cls.open_cart().sale.id
        SaleLine.delete([sale_line])
        flash(_('The order item has been successfully removed'))

        if request.is_xhr:
            return jsonify(message='OK')

        return redirect(url_for('nereid.cart.view_cart'))
コード例 #41
0
ファイル: tag.py プロジェクト: vishu1993/nereid-project
 def serialize(self, purpose=None):
     '''
     Serialize the tag and returns a dictionary.
     '''
     return {
         'create_date':
         self.create_date.isoformat(),
         "url":
         url_for('project.work.render_task_list',
                 project_id=self.project.id,
                 state="opened",
                 tag=self.id),
         "objectType":
         self.__name__,
         "id":
         self.id,
         "displayName":
         self.name,
     }
コード例 #42
0
    def change_party(cls, party_id):
        """
        Updates the current party of the nereid_user to the new party_id if
        it is one of the parties in the list of parties of the user

        :param party_id: ID of the party
        """
        for party in current_user.parties:
            if party.id == party_id:
                cls.write([current_user], {'party': party.id})
                break
        else:
            if request.is_xhr:
                return jsonify(error='The party is not valid'), 400
            flash("The party is not valid")
        if request.is_xhr:
            return jsonify(success='Party has been changed successfully')
        return redirect(
            request.args.get('next', url_for('nereid.website.home')))
コード例 #43
0
ファイル: routing.py プロジェクト: vishu1993/trytond-nereid
    def login(cls):
        """
        Simple login based on the email and password

        Required post data see :class:LoginForm
        """
        login_form = LoginForm(request.form)

        if not request.is_guest_user and request.args.get('next'):
            return redirect(request.args['next'])

        if request.method == 'POST' and login_form.validate():
            NereidUser = Pool().get('nereid.user')
            result = NereidUser.authenticate(login_form.email.data,
                                             login_form.password.data)
            # Result can be the following:
            # 1 - Browse record of User (successful login)
            # 2 - None - Login failure without message
            # 3 - Any other false value (no message is shown. useful if you
            #       want to handle the message shown to user)
            if result:
                # NOTE: Translators leave %s as such
                flash(
                    _("You are now logged in. Welcome %(name)s",
                      name=result.name))
                session['user'] = result.id
                login.send()
                if request.is_xhr:
                    return 'OK'
                else:
                    return redirect(
                        request.values.get('next',
                                           url_for('nereid.website.home')))
            elif result is None:
                flash(_("Invalid login credentials"))

            failed_login.send(form=login_form)

            if request.is_xhr:
                return 'NOK'

        return render_template('login.jinja', login_form=login_form)
コード例 #44
0
    def _get_email_template_context(self):
        """
        Update context
        """
        context = super(Sale, self)._get_email_template_context()

        if has_request_context() and not current_user.is_anonymous():
            customer_name = current_user.display_name
        else:
            customer_name = self.party.name

        context.update({
            'url_for': lambda *args, **kargs: url_for(*args, **kargs),
            'has_request_context': lambda *args, **kargs: has_request_context(
                *args, **kargs),
            'current_user': current_user,
            'customer_name': customer_name,
            'to_json': lambda *args, **kargs: json.dumps(*args, **kargs),
        })
        return context
コード例 #45
0
    def make_pkpass(self):
        """
        Builds a pass by calling the origin model for it and then adds a serial
        number and signs it and builds the pkpass file.
        """
        passfile = self.origin.get_passfile()

        # Add information to be provided by this API
        passfile.serialNumber = str(self.id)
        passfile.webServiceURL = url_for('nereid.passbook.pass.webservice_url',
                                         _external=True,
                                         _secure=True)
        passfile.authenticationToken = self.authentication_token

        # TODO: What to do if barcode is not there ?

        return passfile.create(
            config.get('nereid_passbook', 'certificate'),
            config.get('nereid_passbook', 'key'),
            file_open('nereid_passbook/wwdr.pem').name,
            '',  # Password for pem file ?
        )
コード例 #46
0
    def move_task_to_project(self, project_id):
        """
        Move task from one project to another.
        """
        ProjectWork = Pool().get('project.work')

        assert self.type == 'task'

        try:
            target_project, = ProjectWork.search([('id', '=', project_id),
                                                  ('type', '=', 'project')],
                                                 limit=1)
        except ValueError:
            flash("No project found with given details")
            return redirect(request.referrer)

        if not (current_user.is_admin_of_project(self.parent)
                and current_user.is_admin_of_project(target_project)):
            abort(403)

        if self.parent.id == target_project.id:
            flash("Task already in this project")
            return redirect(request.referrer)

        if self.assigned_to not in [
                member.user for member in target_project.members
        ]:
            self.assigned_to = None

        # Move task to target project
        self.parent = target_project.id
        self.save()

        flash("Task #%d successfully moved to project %s" %
              (self.id, target_project.work.name))
        return redirect(
            url_for('project.work.render_task',
                    project_id=target_project.id,
                    task_id=self.id))
コード例 #47
0
    def registration(cls):
        """
        Invokes registration of an user
        """
        registration_form = cls.get_registration_form()

        if request.method == 'POST' and registration_form.validate():
            existing = cls.search([
                ('email', '=', request.form['email']),
                ('company', '=', request.nereid_website.company.id),
            ])
            if existing:
                flash(
                    _('A registration already exists with this email. '
                      'Please contact customer care'))
            else:
                nereid_user = cls.create({
                    'name':
                    registration_form.name.data,
                    'display_name':
                    registration_form.name.data,
                    'email':
                    registration_form.email.data,
                    'password':
                    registration_form.password.data,
                    'company':
                    request.nereid_website.company.id,
                })
                nereid_user.create_act_code()
                registration.send(nereid_user)
                nereid_user.send_activation_email()
                flash(
                    _('Registration Complete. Check your email for activation')
                )
                return redirect(
                    request.args.get('next', url_for('nereid.website.home')))

        return render_template('registration.jinja', form=registration_form)
コード例 #48
0
ファイル: sale.py プロジェクト: trytonus/nereid-cart-b2c
 def serialize(self, purpose=None):
     """
     Serialize SaleLine data
     """
     res = {}
     if purpose == 'cart':
         currency_format = partial(numbers.format_currency,
                                   currency=self.sale.currency.code,
                                   locale=current_locale.language.code)
         number_format = partial(numbers.format_number,
                                 locale=current_locale.language.code)
         res.update({
             'id':
             self.id,
             'display_name': (self.product and self.product.name
                              or self.description),
             'url':
             self.product.get_absolute_url(_external=True),
             'image':
             (self.product.default_image.transform_command().thumbnail(
                 150, 150, 'a').url()
              if self.product.default_image else None),
             'product':
             self.product.serialize(purpose),
             'quantity':
             number_format(self.quantity),
             'unit':
             self.unit.symbol,
             'unit_price':
             currency_format(self.unit_price),
             'amount':
             currency_format(self.amount),
             'remove_url':
             url_for('nereid.cart.delete_from_cart', line=self.id),
         })
     elif hasattr(super(SaleLine, self), 'serialize'):
         return super(SaleLine, self).serialize(purpose)  # pragma: no cover
     return res
コード例 #49
0
    def confirm_cart(cls, cart):
        '''
        Confirm the sale, clear the sale from the cart
        '''
        Sale = Pool().get('sale.sale')

        sale = cart.sale
        Sale.quote([cart.sale])
        Sale.confirm([cart.sale])

        cart.sale = None
        cart.save()

        # Redirect to the order confirmation page
        flash(_(
            "Your order #%(sale)s has been processed",
            sale=sale.reference
        ))

        return redirect(url_for(
            'sale.sale.render', active_id=sale.id, confirmation=True,
            access_code=sale.guest_access_code,
        ))
コード例 #50
0
ファイル: user.py プロジェクト: uzayr/nereid
    def change_password(cls):
        """
        Changes the password

        .. tip::
            On changing the password, the user is logged out and the login page
            is thrown at the user
        """
        form = ChangePasswordForm()

        if request.method == 'POST' and form.validate():
            if current_user.match_password(form.old_password.data):
                cls.write(
                    [current_user],
                    {'password': form.password.data}
                )
                logout_user()
                return cls.build_response(
                    'Your password has been successfully changed! '
                        'Please login again',
                    redirect(url_for('nereid.website.login')), 200
                )
            else:
                return cls.build_response(
                    'The current password you entered is invalid',
                    render_template(
                        'change-password.jinja', change_password_form=form
                    ), 400
                )

        if form.errors and (request.is_xhr or request.is_json):
            return jsonify(errors=form.errors), 400

        return render_template(
            'change-password.jinja', change_password_form=form
        )
コード例 #51
0
    def change_password(cls):
        """
        Changes the password

        .. tip::
            On changing the password, the user is logged out and the login page
            is thrown at the user
        """
        form = ChangePasswordForm(request.form)

        if request.method == 'POST' and form.validate():
            if request.nereid_user.match_password(form.old_password.data):
                cls.write([request.nereid_user],
                          {'password': form.password.data})
                flash(
                    _('Your password has been successfully changed! '
                      'Please login again'))
                session.pop('user')
                return redirect(url_for('nereid.website.login'))
            else:
                flash(_("The current password you entered is invalid"))

        return render_template('change-password.jinja',
                               change_password_form=form)
コード例 #52
0
    def serialize(self, purpose=None):
        """
        Return serializable dictionary suitable for use with variant
        selection.
        """
        if purpose != 'variant_selection':
            return super(Product, self).serialize(purpose)

        currency_format = partial(
            numbers.format_currency,
            currency=request.nereid_website.company.currency.code,
            locale=request.nereid_website.default_locale.language.code
        )

        return {
            'id': self.id,
            'rec_name': self.rec_name,
            'name': self.name,
            'code': self.code,
            'price': currency_format(self.sale_price(1)),
            'url': url_for('product.product.render', uri=self.uri),
            'image_urls': [
                {
                    'large': (
                        image.transform_command().thumbnail(500, 500, 'a')
                        .url()
                    ),
                    'thumbnail': (
                        image.transform_command().thumbnail(120, 120, 'a')
                        .url()
                    ),
                    'regular': image.url,
                }
                for image in self.get_images()
            ],
        }
コード例 #53
0
    def new_post(cls):
        """Create a new post
        """
        post_form = BlogPostForm(request.form)

        if request.method == 'POST' and post_form.validate():
            post, = cls.create([{
                'title':
                post_form.title.data,
                'uri':
                post_form.uri.data,
                'content':
                post_form.content.data,
                'nereid_user':
                request.nereid_user.id,
                'allow_guest_comments':
                post_form.allow_guest_comments.data,
            }])
            if post_form.publish.data:
                cls.publish([post])
                flash('Your post has been published.')
            else:
                flash('Your post has been saved.')

            if request.is_xhr:
                return jsonify(success=True, item=post.serialize())
            return redirect(
                url_for('blog.post.render',
                        user_id=post.nereid_user.id,
                        uri=post.uri))
        if request.is_xhr:
            return jsonify(
                success=request.method != 'POST',  # False for POST, else True
                errors=post_form.errors or None,
            )
        return render_template('blog_post_form.jinja', form=post_form)
コード例 #54
0
    def render_gift_card(cls, uri):
        """
        Add gift card as a new line in cart
        Request:
            'GET': Renders gift card page
            'POST': Buy Gift Card
        Response:
            'OK' if X-HTTPRequest
            Redirect to shopping cart if normal request
        """
        SaleLine = Pool().get('sale.line')
        Cart = Pool().get('nereid.cart')

        try:
            product, = cls.search([('displayed_on_eshop', '=', True),
                                   ('uri', '=', uri),
                                   ('template.active', '=', True),
                                   ('is_gift_card', '=', True)],
                                  limit=1)
        except ValueError:
            abort(404)

        form = GiftCardForm(product)

        if form.validate_on_submit():
            cart = Cart.open_cart(create_order=True)

            # Code to add gift card as a line to cart
            values = {
                'product': product.id,
                'sale': cart.sale.id,
                'type': 'line',
                'sequence': 10,
                'quantity': 1,
                'unit': None,
                'description': None,
                'recipient_email': form.recipient_email.data,
                'recipient_name': form.recipient_name.data,
                'message': form.message.data,
            }
            order_line = SaleLine(**values)
            order_line.on_change_product()

            # Here 0 means the default option to enter open amount is
            # selected
            if form.selected_amount.data != 0:
                order_line.gc_price = form.selected_amount.data
                order_line.on_change_gc_price()
            else:
                order_line.unit_price = Decimal(form.open_amount.data)

            order_line.save()

            message = 'Gift Card has been added to your cart'
            if request.is_xhr:  # pragma: no cover
                return jsonify(message=message)

            flash(_(message), 'info')
            return redirect(url_for('nereid.cart.view_cart'))

        return render_template('catalog/gift-card.html',
                               product=product,
                               form=form)
コード例 #55
0
class NereidUser:
    "******"
    __name__ = "nereid.user"

    github_id = fields.Integer('Github ID')
    github_url = fields.Char('Github URL')

    @classmethod
    @route("/auth/github", methods=["GET"])
    def github_login(cls):
        """
        The URL to which a new request to authenticate to github begins
        Usually issues a redirect.
        """
        github = request.nereid_website.get_github_oauth_client()
        if github is None:
            return redirect(request.referrer
                            or url_for('nereid.website.login'))
        return github.authorize(callback=url_for(
            'nereid.user.github_authorized_login',
            next=request.args.get('next') or request.referrer or None,
            _external=True))

    @classmethod
    @route("/auth/github-authorized-login", methods=["GET"])
    def github_authorized_login(cls):
        """
        Authorized handler to which github will redirect the user to
        after the login attempt is made.
        """
        github = request.nereid_website.get_github_oauth_client()
        if github is None:
            return redirect(request.referrer
                            or url_for('nereid.website.login'))

        try:
            # The response is an oauth2 response with code. But Github API
            # requires the
            if 'oauth_verifier' in request.args:
                data = github.handle_oauth1_response()
            elif 'code' in request.args:
                data = github.handle_oauth2_response()
            else:
                data = github.handle_unknown_response()
            github.free_request_token()
        except Exception, exc:
            current_app.logger.error("Github login failed %s" % exc)
            flash(_("We cannot talk to github at this time. Please try again"))
            return redirect(request.referrer
                            or url_for('nereid.website.login'))

        if data is None:
            flash(
                _("Access was denied to github: %(reason)s",
                  reason=request.args['error_reason']))
            failed_login.send(form=data)
            return redirect(url_for('nereid.website.login'))

        # Write the oauth token to the session
        session['github_oauth_token'] = data['access_token']

        # Find the information from facebook
        me = requests.get('https://api.github.com/user',
                          params={
                              'access_token': session['github_oauth_token']
                          }).json

        # Find the user
        users = cls.search([
            ('email', '=', me['email']),
            ('company', '=', request.nereid_website.company.id),
        ])
        if not users:
            current_app.logger.debug("No Github user with email %s" %
                                     me['email'])
            current_app.logger.debug("Registering new user %s" % me['name'])
            user, = cls.create([{
                'name': me['name'],
                'display_name': me['name'],
                'email': me['email'],
                'github_id': me['id'],
                'addresses': False,
                'github_url': me['html_url'],
            }])
            flash(_('Thanks for registering with us using github'))
        else:
            user, = users

        # Add the user to session and trigger signals
        session['user'] = user.id
        if not user.github_id:
            cls.write([user], {
                'github_id': me['id'],
                'github_url': me['html_url']
            })
        flash(_("You are now logged in. Welcome %(name)s", name=user.name))
        login.send()
        if request.is_xhr:
            return 'OK'
        return redirect(
            request.values.get('next', url_for('nereid.website.home')))
コード例 #56
0
    def billing_address(cls):
        '''
        Choose or Create a billing address
        '''
        NereidCart = Pool().get('nereid.cart')
        Address = Pool().get('party.address')
        PaymentProfile = Pool().get('party.payment_profile')

        cart = NereidCart.open_cart()

        address = None
        if current_user.is_anonymous and cart.sale.invoice_address:
            address = cart.sale.invoice_address

        address_form = cls.get_new_address_form(address)

        if request.method == 'POST':
            if request.form.get('use_shipment_address'):
                if not cart.sale.shipment_address:
                    # Without defining shipment address, the user is
                    # trying to set invoice_address as shipment_address
                    return redirect(
                        url_for('nereid.checkout.shipping_address'))
                cart.sale.invoice_address = cart.sale.shipment_address
                cart.sale.save()
                return redirect(url_for('nereid.checkout.payment_method'))
            if request.form.get('payment_profile'):
                payment_profile = PaymentProfile(
                    request.form.get('payment_profile', type=int))
                if payment_profile and \
                        cart.sale.invoice_address != payment_profile.address:
                    cart.sale.invoice_address = payment_profile.address
                    cart.sale.save()
                    return redirect(url_for('nereid.checkout.payment_method'))

            if not current_user.is_anonymous and request.form.get('address'):
                # Registered user has chosen an existing address
                address = Address(request.form.get('address', type=int))

                if address.party != cart.sale.party:
                    flash(_('The address chosen is not valid'))
                    return redirect(url_for('nereid.checkout.billing_address'))

            else:
                # Guest user or registered user creating an address. Only
                # difference is that the party of address depends on guest or
                # not
                if not address_form.validate():
                    address = None
                else:
                    if (current_user.is_anonymous and cart.sale.invoice_address
                            and cart.sale.invoice_address !=
                            cart.sale.shipment_address):
                        # Save to the same address if the guest user
                        # is just trying to update the address
                        address = cart.sale.invoice_address
                    else:
                        address = Address()

                    address.party = cart.sale.party
                    address.name = address_form.name.data
                    address.street = address_form.street.data
                    address.streetbis = address_form.streetbis.data
                    address.zip = address_form.zip.data
                    address.city = address_form.city.data
                    address.country = address_form.country.data
                    address.subdivision = address_form.subdivision.data

                    if address_form.phone.data:
                        # create contact mechanism
                        phone = \
                            cart.sale.party.add_contact_mechanism_if_not_exists(
                                'phone', address_form.phone.data
                            )
                        address.phone_number = phone.id

                    address.save()

            if address is not None:
                # Finally save the address to the shipment
                cart.sale.invoice_address = address
                cart.sale.save()

                return redirect(url_for('nereid.checkout.payment_method'))

        addresses = []
        if not current_user.is_anonymous:
            addresses.extend(current_user.party.addresses)

        return render_template(
            'checkout/billing_address.jinja',
            addresses=addresses,
            address_form=address_form,
        )
コード例 #57
0
    def shipping_address(cls):
        '''
        Choose or Create a shipping address

        Guest users are only allowed to create a new address while registered
        users are allowed to either choose an address or create a new one.

        GET
        ~~~

        Renders the shipping_address selection/creation page.

        The template context would have an addresses variable which carries a
        list of addresses in the case of registered users. For guest users the
        variable would be empty.

        POST
        ~~~~

        **Registered User**: If `address` (the id of the chosen address) is in
        the POST values, then the address is validated and stored as the
        `shipment_address` in the sale. If not, the new address form is
        validated to see if a new address has to be created for the party.

        **Guest User**: New address data has to be provided and validated to
        create the new address.

        Once the address is set succesfully, the delivery_options page is shown
        '''
        NereidCart = Pool().get('nereid.cart')
        Address = Pool().get('party.address')

        cart = NereidCart.open_cart()

        address = None
        if current_user.is_anonymous and cart.sale.shipment_address:
            address = cart.sale.shipment_address

        address_form = cls.get_new_address_form(address)

        if request.method == 'POST':
            if not current_user.is_anonymous and request.form.get('address'):
                # Registered user has chosen an existing address
                address = Address(request.form.get('address', type=int))

                if address.party != cart.sale.party:
                    flash(_('The address chosen is not valid'))
                    return redirect(
                        url_for('nereid.checkout.shipping_address'))

            else:
                # Guest user or registered user creating an address. Only
                # difference is that the party of address depends on guest or
                # not
                if not address_form.validate():
                    address = None
                else:
                    if current_user.is_anonymous and \
                            cart.sale.shipment_address:
                        # Save to the same address if the guest user
                        # is just trying to update the address
                        address = cart.sale.shipment_address
                    else:
                        address = Address()

                    address.party = cart.sale.party
                    address.name = address_form.name.data
                    address.street = address_form.street.data
                    address.streetbis = address_form.streetbis.data
                    address.zip = address_form.zip.data
                    address.city = address_form.city.data
                    address.country = address_form.country.data
                    address.subdivision = address_form.subdivision.data

                    if address_form.phone.data:
                        # create contact mechanism
                        phone = \
                            cart.sale.party.add_contact_mechanism_if_not_exists(
                                'phone', address_form.phone.data
                            )
                        address.phone_number = phone.id
                    address.save()

            if address is not None:
                # Finally save the address to the shipment
                cart.sale.shipment_address = address
                cart.sale.save()

                return redirect(url_for('nereid.checkout.validate_address'))

        addresses = []
        if not current_user.is_anonymous:
            addresses.extend(current_user.party.addresses)

        return render_template(
            'checkout/shipping_address.jinja',
            addresses=addresses,
            address_form=address_form,
        )
コード例 #58
0
    def sign_in(cls):
        '''
        Step 1: Sign In or Register

        GET
        ~~~

        Renders a sign-in or register page. If guest checkout is enabled, then
        an option to continue as guest is also permitted, in which case the
        email is a required field.

        POST
        ~~~~

        For guest checkout, this sign in would create a new party with the name
        as the current session_id and move the shopping cart's sale to the
        new user's ownership

        Designer notes: The registration or login must contact the
        corresponding handlers. Login and Registraion handlers are designed to
        handle a `next` parameter where the user would be redirected to if the
        operation was successful. The next url is provided in the context

        OTOH, if the user desires to checkout as guest, the user is required to
        fill in the email and submit the form, which posts the email to this
        handler.
        '''
        NereidCart = Pool().get('nereid.cart')
        NereidUser = Pool().get('nereid.user')
        Party = Pool().get('party.party')

        if not current_user.is_anonymous:
            form = cls.sign_in_form(
                email=current_user.email,
                checkout_mode='account',
            )
        else:
            # Guest user
            form = cls.sign_in_form(
                email=session.get('email'),
                checkout_mode='guest',
            )

        if form.validate_on_submit():
            if form.checkout_mode.data == 'guest':

                if not cls.allowed_as_guest(form.email.data):
                    return render_template(
                        'checkout/signin-email-in-use.jinja',
                        email=form.email.data)

                cart = NereidCart.open_cart()
                party_name = unicode(
                    _('Guest with email: %(email)s', email=form.email.data))
                if cart.sale.party == current_website.guest_user.party:
                    # Create a party with the email as email, and session as
                    # name, but attach the session to it.
                    party, = Party.create([{
                        'name':
                        party_name,
                        'nereid_session':
                        session.sid,
                        'addresses': [],
                        'contact_mechanisms': [('create', [{
                            'type':
                            'email',
                            'value':
                            form.email.data,
                        }])]
                    }])

                    cart.sale.party = party
                    # TODO: Avoid this if the user comes to sign-in twice.
                    cart.sale.shipment_address = None
                    cart.sale.invoice_address = None
                    cart.sale.save()
                else:
                    # Perhaps the email changed ?
                    party = cart.sale.party
                    party.name = party_name

                    # contact_mechanism of email type will always be there for
                    # Guest user
                    contact_mechanism = filter(lambda c: c.type == 'email',
                                               party.contact_mechanisms)[0]
                    contact_mechanism.value = form.email.data
                    contact_mechanism.save()
                    party.email = form.email.data
                    party.save()

                return redirect(url_for('nereid.checkout.shipping_address'))
            else:
                # The user wants to use existing email to login
                user = NereidUser.authenticate(form.email.data,
                                               form.password.data)
                if user:
                    # FIXME: Remove remember_me
                    login_user(user, remember=form.remember.data)
                    return redirect(
                        url_for('nereid.checkout.shipping_address'))
                else:
                    failed_login.send()

        if not current_user.is_anonymous:
            # Registered user with a fresh login can directly proceed to
            # step 2, which is filling the shipping address
            #
            # if this is a recent sign-in by a registred user
            # automatically proceed to the shipping_address step
            return redirect(url_for('nereid.checkout.shipping_address'))

        return render_template(
            'checkout/signin.jinja',
            form=form,
            next=url_for('nereid.checkout.shipping_address'))
コード例 #59
0
    def new_opportunity(cls):
        """
        Web handler to create a new sale opportunity
        """
        if 're_captcha_public' in CONFIG.options:
            contact_form = ContactUsForm(
                request.form, captcha={'ip_address': request.remote_addr})
        else:
            contact_form = ContactUsForm(request.form)

        if request.method == 'POST':
            if not contact_form.validate():
                return jsonify({
                    "success": False,
                    "message": "Field validation error",
                    "errors": contact_form.errors,
                })
            ContactMech = Pool().get('party.contact_mechanism')
            Party = Pool().get('party.party')
            Config = Pool().get('sale.configuration')
            config = Config(1)
            contact_data = contact_form.data
            # Create Party
            company = request.nereid_website.company.id

            if request.remote_addr and geoip:
                detected_country = geoip.country_name_by_addr(
                    request.remote_addr)
            else:
                detected_country = None

            party, = Party.create([{
                'name':
                contact_data.get('company') or contact_data['name'],
                'addresses': [('create', [{
                    'name': contact_data['name'],
                }])],
            }])

            if contact_data.get('website'):
                # Create website as contact mech
                ContactMech.create([{
                    'type': 'website',
                    'party': party.id,
                    'website': contact_data['website'],
                }])

            if contact_data.get('phone'):
                # Create phone as contact mech and assign as phone
                ContactMech.create([{
                    'type': 'phone',
                    'party': party.id,
                    'other_value': contact_data['phone'],
                }])

            # Create email as contact mech and assign as email
            ContactMech.create([{
                'type': 'email',
                'party': party.id,
                'email': contact_data['email'],
            }])

            # Create sale opportunity
            if not current_user.is_anonymous() and current_user.employee:
                employee = current_user.employee.id
                description = 'Created by %s' % \
                    current_user.display_name
            else:
                employee = config.website_employee.id
                description = 'Created from website'
            lead, = cls.create([{
                'party': party.id,
                'company': company,
                'employee': employee,
                'address': party.addresses[0].id,
                'description': description,
                'comment': contact_data['comment'],
                'ip_address': request.remote_addr,
                'detected_country': detected_country,
            }])
            lead.send_notification_mail()
            if request.is_xhr or request.is_json:
                return jsonify({
                    "success": True,
                    "message": "Contact saved",
                    "lead_id": lead.id,
                })

            return redirect(
                request.args.get(
                    'next',
                    url_for('sale.opportunity.admin_lead', active_id=lead.id)))
        return render_template('crm/sale_form.jinja', form=contact_form)
コード例 #60
0
ファイル: user.py プロジェクト: shaambhavipathak/nereid
    def registration(cls):
        """
        Invokes registration of an user
        """
        Party = Pool().get('party.party')
        ContactMechanism = Pool().get('party.contact_mechanism')

        registration_form = cls.get_registration_form()

        if registration_form.validate_on_submit():
            with Transaction().set_context(active_test=False):
                existing = cls.search([
                    ('email', '=', registration_form.email.data),
                    ('company', '=', request.nereid_website.company.id),
                ])
            if existing:
                message = _(
                    'A registration already exists with this email. '
                    'Please contact customer care'
                )
                if request.is_xhr or request.is_json:
                    return jsonify(message=unicode(message)), 400
                else:
                    flash(message)
            else:
                party = Party(name=registration_form.name.data)
                party.addresses = []
                party.contact_mechanisms = [
                    ContactMechanism(
                        type="email",
                        value=registration_form.email.data
                    )
                ]
                party.save()
                nereid_user = cls(**{
                    'party': party.id,
                    'display_name': registration_form.name.data,
                    'email': registration_form.email.data,
                    'password': registration_form.password.data,
                    'company': request.nereid_website.company.id,
                }
                )
                nereid_user.save()
                registration.send(nereid_user)
                nereid_user.send_activation_email()
                message = _(
                    'Registration Complete. Check your email for activation'
                )
                if request.is_xhr or request.is_json:
                    return jsonify(message=unicode(message)), 201
                else:
                    flash(message)
                return redirect(
                    request.args.get('next', url_for('nereid.website.home'))
                )

        if registration_form.errors and (request.is_xhr or request.is_json):
            return jsonify({
                'message': unicode(_('Form has errors')),
                'errors': registration_form.errors,
            }), 400

        return render_template('registration.jinja', form=registration_form)