[ADD] pms_api_rest: module created

This commit is contained in:
miguelpadin
2021-07-26 13:07:37 +02:00
committed by Darío Lodeiros
parent 02f8f126ca
commit 75f453adec
15 changed files with 317 additions and 0 deletions

5
pms_api_rest/__init__.py Normal file
View File

@@ -0,0 +1,5 @@
from . import controllers
from . import datamodels
from . import models
from . import services

View File

@@ -0,0 +1,19 @@
{
"name": "API REST PMS",
"author": "Commit [Sun], Odoo Community Association (OCA)",
"website": "https://github.com/OCA/pms",
"category": "Generic Modules/Property Management System",
"version": "14.0.1.0.0",
"license": "AGPL-3",
"depends": [
"pms",
"base_rest",
"base_rest_datamodel",
"web",
"auth_signup",
],
"external_dependencies": {
"python": ["jwt", "simplejson", "marshmallow"],
},
"installable": True,
}

View File

@@ -0,0 +1,2 @@
from . import jwt_controller
from . import pms_rest

View File

@@ -0,0 +1,110 @@
import logging
import werkzeug
from odoo import http
from odoo.http import request
from odoo.addons.auth_signup.models.res_users import SignupError
from ..lib.jwt_http import jwt_http
from ..lib.validator import validator
_logger = logging.getLogger(__name__)
SENSITIVE_FIELDS = [
"password",
"password_crypt",
"new_password",
"create_uid",
"write_uid",
]
class JwtController(http.Controller):
# test route
@http.route("/api/info", auth="public", csrf=False, cors="*")
def index(self, **kw):
return "Hello, world"
@http.route(
"/api/login", type="http", auth="public", csrf=False, cors="*", methods=["POST"]
)
def login(self, email, password, **kw):
return jwt_http.do_login(email, password)
@http.route("/api/me", type="http", auth="public", csrf=False, cors="*")
def me(self, **kw):
http_method, body, headers, token = jwt_http.parse_request()
result = validator.verify_token(token)
if not result["status"]:
return jwt_http.errcode(code=result["code"], message=result["message"])
return jwt_http.response(request.env.user.to_dict(True))
@http.route("/api/logout", type="http", auth="public", csrf=False, cors="*")
def logout(self, **kw):
http_method, body, headers, token = jwt_http.parse_request()
result = validator.verify_token(token)
if not result["status"]:
return jwt_http.errcode(code=result["code"], message=result["message"])
jwt_http.do_logout(token)
return jwt_http.response()
@http.route(
"/api/register",
type="http",
auth="public",
csrf=False,
cors="*",
methods=["POST"],
)
def register(self, email=None, name=None, password=None, **kw):
if not validator.is_valid_email(email):
return jwt_http.errcode(code=400, message="Invalid email address")
if not name:
return jwt_http.errcode(code=400, message="Name cannot be empty")
if not password:
return jwt_http.errcode(code=400, message="Password cannot be empty")
# sign up
try:
self._signup_with_values(login=email, name=name, password=password)
except AttributeError:
return jwt_http.errcode(code=501, message="Signup is disabled")
except (SignupError, AssertionError) as e:
if request.env["res.users"].sudo().search([("login", "=", email)]):
return jwt_http.errcode(
code=400, message="Email address already exists"
)
else:
_logger.error("%s", e)
return jwt_http.response_500()
except Exception as e:
_logger.error(str(e))
return jwt_http.response_500()
# log the user in
return jwt_http.do_login(email, password)
def _signup_with_values(self, **values):
request.env["res.users"].sudo().signup(values, None)
request.env.cr.commit() # as authenticate will use its
# own cursor we need to commit the current transaction
self.signup_email(values)
def signup_email(self, values):
user_sudo = (
request.env["res.users"]
.sudo()
.search([("login", "=", values.get("login"))])
)
template = request.env.ref(
"auth_signup.mail_template_user_signup_account_created",
raise_if_not_found=False,
)
if user_sudo and template:
template.sudo().with_context(
lang=user_sudo.lang,
auth_login=werkzeug.url_encode({"auth_login": user_sudo.email}),
).send_mail(user_sudo.id, force_send=True)

View File

@@ -0,0 +1,22 @@
from odoo.addons.base_rest.controllers import main
from ..lib.jwt_http import jwt_http
from ..lib.validator import validator
class BaseRestDemoPublicApiController(main.RestController):
_root_path = "/api/"
_collection_name = "pms.reservation.service"
_default_auth = "public"
# RestController OVERRIDE method
def _process_method(self, service_name, method_name, *args, params=None):
http_method, body, headers, token = jwt_http.parse_request()
result = validator.verify_token(token)
if not result["status"]:
return jwt_http.errcode(code=result["code"], message=result["message"])
else:
return super(BaseRestDemoPublicApiController, self)._process_method(
service_name, method_name, *args, params=params
)

View File

@@ -0,0 +1,2 @@
from . import pms_reservation_short_info
from . import pms_reservation_search_param

View File

@@ -0,0 +1,10 @@
from marshmallow import fields
from odoo.addons.datamodel.core import Datamodel
class PmsReservationSearchParam(Datamodel):
_name = "pms.reservation.search.param"
id = fields.Integer(required=False, allow_none=False)
name = fields.String(required=False, allow_none=False)

View File

@@ -0,0 +1,16 @@
from marshmallow import fields
from odoo.addons.datamodel.core import Datamodel
class PmsReservationShortInfo(Datamodel):
_name = "pms.reservation.short.info"
id = fields.Integer(required=True, allow_none=False)
partner = fields.String(required=True, allow_none=False)
checkin = fields.String(required=True, allow_none=False)
checkout = fields.String(required=True, allow_none=False)
preferred_room_id = fields.String(required=True, allow_none=False)
room_type_id = fields.String(required=True, allow_none=False)
name = fields.String(required=True, allow_none=False)
partner_requests = fields.String(required=False, allow_none=True)

View File

@@ -0,0 +1,2 @@
from . import res_users
from . import jwt_access_token

View File

@@ -0,0 +1,32 @@
from datetime import datetime
from odoo import api, fields, models
class JwtAccessToken(models.Model):
_name = "jwt_provider.access_token"
_description = "Store user access token for one-time-login"
token = fields.Char(
"Access Token",
required=True
)
user_id = fields.Many2one(
comodel_name="res.users",
string="User",
required=True,
ondelete="cascade",
)
expires = fields.Datetime(
"Expires",
required=True,
)
is_expired = fields.Boolean(
compute="_compute_is_expired",
)
@api.depends("expires")
def _compute_is_expired(self):
for token in self:
token.is_expired = datetime.now() > token.expires

View File

@@ -0,0 +1,43 @@
import logging
from odoo import _, api, fields, models
from odoo.exceptions import AccessDenied, ValidationError
from ..lib.validator import validator
_logger = logging.getLogger(__name__)
class ResUsers(models.Model):
_inherit = "res.users"
access_token_ids = fields.One2many(
string="Access Tokens",
comodel_name="jwt_provider.access_token",
inverse_name="user_id",
)
@classmethod
def _login(cls, db, login, password, user_agent_env):
user_id = super(ResUsers, cls)._login(db, login, password, user_agent_env)
if user_id:
return user_id
uid = validator.verify(password)
_logger.info(uid)
return uid
@api.model
def _check_credentials(self, password, user_agent_env):
try:
super(ResUsers, self)._check_credentials(password, user_agent_env)
except AccessDenied:
if not validator.verify(password):
raise
def to_dict(self, single=False):
res = []
for u in self:
d = u.read(["email", "name", "company_id"])[0]
res.append(d)
return res[0] if single else res

View File

@@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_jwt_access_token,Read jwt access token,model_jwt_provider_access_token,,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_jwt_access_token Read jwt access token model_jwt_provider_access_token 1 0 0 0

View File

@@ -0,0 +1 @@
from . import reservation_services

View File

@@ -0,0 +1,51 @@
from odoo.addons.base_rest import restapi
from odoo.addons.base_rest_datamodel.restapi import Datamodel
from odoo.addons.component.core import Component
class PmsReservationService(Component):
_inherit = "base.rest.service"
_name = "pms.reservation.service"
_usage = "reservations"
_collection = "pms.reservation.service"
@restapi.method(
[
(
[
"/",
],
"GET"
)
],
input_param=Datamodel("pms.reservation.search.param"),
output_param=Datamodel("pms.reservation.short.info", is_list=True),
auth="public",
)
def search(self, reservation_search_param):
domain = []
if reservation_search_param.name:
domain.append(("name", "like", reservation_search_param.name))
if reservation_search_param.id:
domain.append(("id", "=", reservation_search_param.id))
res = []
PmsReservationShortInfo = self.env.datamodels["pms.reservation.short.info"]
for reservation in self.env["pms.reservation"].sudo().search(
domain,
):
res.append(
PmsReservationShortInfo(
id=reservation.id,
partner=reservation.partner_id.name,
checkin=str(reservation.checkin),
checkout=str(reservation.checkout),
preferred_room_id=reservation.preferred_room_id.name
if reservation.preferred_room_id
else "",
room_type_id=reservation.room_type_id.name
if reservation.room_type_id
else "",
name=reservation.name,
)
)
return res

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB