Skip to content

Commit

Permalink
[IMP] shopinvader_api_signin_jwt: anonymous cart
Browse files Browse the repository at this point in the history
  • Loading branch information
qgroulard committed Apr 3, 2024
1 parent cff4e6a commit 68e4be1
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 10 deletions.
4 changes: 2 additions & 2 deletions shopinvader_api_signin_jwt/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Shopinvader Api Signin JWT
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:75ace7db3bf1d327ad236aa12212ec10ad5363f81a8d3fd9896afe3f4d195fc4
!! source digest: sha256:335295feb8193e9691d56e3537300ec06022d9a6abe43a72a0639e1ce6e3fc68
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
Expand All @@ -24,6 +24,7 @@ Shopinvader Api Signin JWT

This addon adds a web API to signin into the application and create a partner
if the email in the jwt payload is unknown.
If we had an anonymous partner, transfer his cart to the loggedin partner and delete it.

**Table of contents**

Expand All @@ -33,7 +34,6 @@ if the email in the jwt payload is unknown.
Known issues / Roadmap
======================

* Manage anonymous cart (see https://github.com/shopinvader/odoo-shopinvader/issues/1428)
* Use ``fastapi_auth_jwt.auth_jwt_authenticated_odoo_env`` dependency for the env (see https://github.com/OCA/rest-framework/issues/406)

Bug Tracker
Expand Down
6 changes: 5 additions & 1 deletion shopinvader_api_signin_jwt/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@
"license": "AGPL-3",
"author": "ACSONE SA/NV",
"website": "https://github.com/shopinvader/odoo-shopinvader",
"depends": ["fastapi_auth_jwt"],
"depends": [
"fastapi_auth_jwt",
"shopinvader_anonymous_partner",
"shopinvader_sale_cart",
],
"data": [
"security/res_groups.xml",
"security/acl_res_partner.xml",
Expand Down
1 change: 1 addition & 0 deletions shopinvader_api_signin_jwt/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
This addon adds a web API to signin into the application and create a partner
if the email in the jwt payload is unknown.
If we had an anonymous partner, transfer his cart to the loggedin partner and delete it.
1 change: 0 additions & 1 deletion shopinvader_api_signin_jwt/readme/ROADMAP.rst
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
* Manage anonymous cart (see https://github.com/shopinvader/odoo-shopinvader/issues/1428)
* Use ``fastapi_auth_jwt.auth_jwt_authenticated_odoo_env`` dependency for the env (see https://github.com/OCA/rest-framework/issues/406)
14 changes: 12 additions & 2 deletions shopinvader_api_signin_jwt/routers/signin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import logging
from typing import Annotated, Union

from fastapi import APIRouter, Depends, Response, status
from fastapi import APIRouter, Depends, Request, Response, status

from odoo import api, models

Expand All @@ -28,17 +28,27 @@ def signin(
partner: Annotated[Partner, Depends(auth_jwt_optionally_authenticated_partner)],
payload: Annotated[Payload, Depends(auth_jwt_authenticated_payload)],
response: Response,
request: Request,
) -> None:
"""
Authenticate the partner based on a JWT token or a session cookie.
Set the session cookie if allowed.
Return HTTP code 201 if res.partner created (case of the first signin).
Transfer anonymous cart and delete anonymous partner if any.
"""
if not partner:
env[
partner = env[
"shopinvader_api_signin_jwt.signin_router.helper"
]._create_partner_from_payload(payload)
response.status_code = status.HTTP_201_CREATED
anonymous_partner = env["res.partner"]._get_anonymous_partner__cookie(
request.cookies
)
if anonymous_partner:
anonymous_cart = env["sale.order"].sudo()._find_open_cart(anonymous_partner.id)
if anonymous_cart:
anonymous_cart._transfer_cart(partner.id)
env["res.partner"]._delete_anonymous_partner__cookie(request.cookies, response)


@signin_router.post("/signout")
Expand Down
2 changes: 1 addition & 1 deletion shopinvader_api_signin_jwt/security/acl_res_partner.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<field name="perm_read" eval="1" />
<field name="perm_write" eval="1" />
<field name="perm_create" eval="1" />
<field name="perm_unlink" eval="0" />
<field name="perm_unlink" eval="1" />
</record>

</odoo>
6 changes: 3 additions & 3 deletions shopinvader_api_signin_jwt/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -367,11 +367,12 @@ <h1 class="title">Shopinvader Api Signin JWT</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:75ace7db3bf1d327ad236aa12212ec10ad5363f81a8d3fd9896afe3f4d195fc4
!! source digest: sha256:335295feb8193e9691d56e3537300ec06022d9a6abe43a72a0639e1ce6e3fc68
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/shopinvader/odoo-shopinvader/tree/16.0/shopinvader_api_signin_jwt"><img alt="shopinvader/odoo-shopinvader" src="https://img.shields.io/badge/github-shopinvader%2Fodoo--shopinvader-lightgray.png?logo=github" /></a></p>
<p>This addon adds a web API to signin into the application and create a partner
if the email in the jwt payload is unknown.</p>
if the email in the jwt payload is unknown.
If we had an anonymous partner, transfer his cart to the loggedin partner and delete it.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
Expand All @@ -388,7 +389,6 @@ <h1 class="title">Shopinvader Api Signin JWT</h1>
<div class="section" id="known-issues-roadmap">
<h1><a class="toc-backref" href="#toc-entry-1">Known issues / Roadmap</a></h1>
<ul class="simple">
<li>Manage anonymous cart (see <a class="reference external" href="https://github.com/shopinvader/odoo-shopinvader/issues/1428">https://github.com/shopinvader/odoo-shopinvader/issues/1428</a>)</li>
<li>Use <tt class="docutils literal">fastapi_auth_jwt.auth_jwt_authenticated_odoo_env</tt> dependency for the env (see <a class="reference external" href="https://github.com/OCA/rest-framework/issues/406">https://github.com/OCA/rest-framework/issues/406</a>)</li>
</ul>
</div>
Expand Down
32 changes: 32 additions & 0 deletions shopinvader_api_signin_jwt/tests/test_signin.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

from odoo.addons.fastapi.tests.common import FastAPITransactionCase
from odoo.addons.fastapi_auth_jwt.dependencies import auth_jwt_default_validator_name
from odoo.addons.shopinvader_anonymous_partner.models.res_partner import COOKIE_NAME

from ..routers import signin_router

Expand Down Expand Up @@ -79,6 +80,37 @@ def test_signin(self):
res = client.post("/signin", headers={"Authorization": token})
self.assertEqual(res.status_code, 200)

def test_signin_anonymous_cart(self):
anonymous_partner = self.env["res.partner"].create(
{"name": "Test anonymous", "anonymous_token": "1234", "active": False}
)
product = self.env["product.product"].create(
{"name": "product", "uom_id": self.env.ref("uom.product_uom_unit").id}
)
self.env["sale.order"].create(
{
"partner_id": anonymous_partner.id,
"order_line": [
(0, 0, {"product_id": product.id, "product_uom_qty": 1}),
],
"typology": "cart",
}
)

token = self._get_token()
with self._create_test_client() as client:
res = client.post(
"/signin",
headers={"Authorization": token},
cookies={COOKIE_NAME: "1234"},
)
self.assertFalse(res.cookies.get(COOKIE_NAME))
self.assertFalse(anonymous_partner.exists())
partner = self.env["res.partner"].search([("email", "=", "[email protected]")])
cart = self.env["sale.order"].search([("partner_id", "=", partner.id)])
self.assertEqual(len(cart.order_line), 1)
self.assertEqual(cart.order_line[0].product_id, product)

def test_signout(self):
self.validator.write({"cookie_enabled": True, "cookie_name": "test_cookie"})
token = self._get_token()
Expand Down

0 comments on commit 68e4be1

Please sign in to comment.