Skip to content

Commit 68ee672

Browse files
committed
update to 12.0
1 parent 150c96f commit 68ee672

File tree

20 files changed

+373
-339
lines changed

20 files changed

+373
-339
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.vscode/

__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33
from . import controllers
44
from . import models
55

6-
from . import validator, jwt_http
6+
from . import validator, jwt_http, util

__manifest__.py

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
'name': "jwt_provider",
44

55
'summary': """
6-
Provide a simple rest using jwt for odoo 11""",
6+
Provide a simple rest using jwt for odoo 12""",
77

88
'description': """
99
Key features:
@@ -26,15 +26,13 @@
2626
'external_dependencies': {
2727
'python': ['jwt'],
2828
},
29-
30-
# always loaded
3129
'data': [
32-
# 'security/ir.model.access.csv',
33-
#'views/views.xml',
34-
#'views/templates.xml',
30+
'security/ir.model.access.csv',
31+
'views/user_view.xml',
32+
],
33+
'css': [
34+
'static/src/css/jwt.css',
3535
],
36-
# only loaded in demonstration mode
3736
'demo': [
38-
#'demo/demo.xml',
3937
],
4038
}

controllers/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# -*- coding: utf-8 -*-
22

3-
from . import main
3+
from . import api
4+
from . import web

controllers/api.py

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# -*- coding: utf-8 -*-
2+
import werkzeug
3+
from odoo import http
4+
from odoo.http import request, Response
5+
from odoo.addons.auth_signup.models.res_users import SignupError
6+
from odoo.exceptions import UserError
7+
8+
from ..validator import validator
9+
from ..jwt_http import jwt_http
10+
11+
import logging
12+
_logger = logging.getLogger(__name__)
13+
14+
SENSITIVE_FIELDS = ['password', 'password_crypt', 'new_password', 'create_uid', 'write_uid']
15+
16+
17+
class JwtController(http.Controller):
18+
# test route
19+
@http.route('/api/info', auth='public', csrf=False, cors='*')
20+
def index(self, **kw):
21+
return 'Hello, world'
22+
23+
@http.route('/api/login', type='http', auth='public', csrf=False, cors='*', methods=['POST'])
24+
def login(self, email, password, **kw):
25+
26+
return jwt_http.do_login(email, password)
27+
28+
@http.route('/api/me', type='http', auth='public', csrf=False, cors='*')
29+
def me(self, **kw):
30+
http_method, body, headers, token = jwt_http.parse_request()
31+
result = validator.verify_token(token)
32+
if not result['status']:
33+
return jwt_http.errcode(code=result['code'], message=result['message'])
34+
35+
return jwt_http.response(request.env.user.to_dict(True))
36+
37+
@http.route('/api/logout', type='http', auth='public', csrf=False, cors='*')
38+
def logout(self, **kw):
39+
http_method, body, headers, token = jwt_http.parse_request()
40+
result = validator.verify_token(token)
41+
if not result['status']:
42+
return jwt_http.errcode(code=result['code'], message=result['message'])
43+
44+
jwt_http.do_logout(token)
45+
return jwt_http.response()
46+
47+
@http.route('/api/register', type='http', auth='public', csrf=False, cors='*', methods=['POST'])
48+
def register(self, email=None, name=None, password=None, **kw):
49+
if not validator.is_valid_email(email):
50+
return jwt_http.errcode(code=400, message='Invalid email address')
51+
if not name:
52+
return jwt_http.errcode(code=400, message='Name cannot be empty')
53+
if not password:
54+
return jwt_http.errcode(code=400, message='Password cannot be empty')
55+
56+
# sign up
57+
try:
58+
self._signup_with_values(login=email, name=name, password=password)
59+
except AttributeError:
60+
return jwt_http.errcode(code=501, message='Signup is disabled')
61+
except (SignupError, AssertionError) as e:
62+
if request.env["res.users"].sudo().search([("login", "=", email)]):
63+
return jwt_http.errcode(code=400, message='Email address already existed')
64+
else:
65+
_logger.error("%s", e)
66+
return jwt_http.response_500()
67+
except Exception as e:
68+
_logger.error(str(e))
69+
return jwt_http.response_500()
70+
# log the user in
71+
return jwt_http.do_login(email, password)
72+
73+
def _signup_with_values(self, **values):
74+
request.env['res.users'].sudo().signup(values, None)
75+
request.env.cr.commit() # as authenticate will use its own cursor we need to commit the current transaction
76+
self.signup_email(values)
77+
78+
79+
def signup_email(self, values):
80+
user_sudo = request.env['res.users'].sudo().search([('login', '=', values.get('login'))])
81+
template = request.env.ref('auth_signup.mail_template_user_signup_account_created', raise_if_not_found=False)
82+
if user_sudo and template:
83+
template.sudo().with_context(
84+
lang=user_sudo.lang,
85+
auth_login=werkzeug.url_encode({'auth_login': user_sudo.email}),
86+
).send_mail(user_sudo.id, force_send=True)

controllers/main.py

Lines changed: 0 additions & 147 deletions
This file was deleted.

controllers/web.py

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import werkzeug
2+
import odoo
3+
import base64
4+
from odoo import http
5+
from odoo.http import request
6+
from ..jwt_http import jwt_http
7+
from ..util import util
8+
9+
import logging
10+
_logger = logging.getLogger(__name__)
11+
12+
class WebController(http.Controller):
13+
@http.route([
14+
'/web/avatar/<int:id>',
15+
'/web/avatar/<int:id>/<string:size>'
16+
], auth='public', csrf=False, cors='*')
17+
def avatar(self, id=None, size='small', **kw):
18+
# get product
19+
headers = []
20+
try:
21+
user = request.env['res.users'].sudo().browse(id)
22+
content = None
23+
mimetype = None
24+
if user:
25+
# determine field to get
26+
field_size = 'image'
27+
resize = True
28+
if size in ['medium', 'small']:
29+
field_size = '%s_%s' % (field_size, size)
30+
resize = False
31+
content = getattr(user, field_size)
32+
# the following lines purpose is to get mimetype
33+
attachment = request.env['ir.attachment'].sudo().search([
34+
('res_model', '=', 'res.partner'),
35+
('res_id', '=', user.partner_id.id),
36+
('res_field', '=', 'image'),
37+
])
38+
if attachment.exists():
39+
mimetype = attachment.mimetype
40+
if content and mimetype:
41+
# resize image_variant here
42+
if resize:
43+
if size == 'large':
44+
width, height = (500, 500)
45+
# add other size here, eg:
46+
# elif size == 'huge':
47+
# width, height = (800, 800)
48+
else:
49+
width = None
50+
height = None
51+
if width:
52+
content = odoo.tools.image_resize_image(base64_source=content, size=(width or None, height or None), encoding='base64', avoid_if_small=True)
53+
# force mime type becuz of image resizer
54+
# mimetype = 'image/png'
55+
image_base64 = base64.b64decode(content)
56+
else:
57+
image_base64 = self.placeholder() # could return (contenttype, content) in master
58+
mimetype = 'image/gif'
59+
except Exception as ex:
60+
# just to make sure the placeholder image existed
61+
image_base64 = base64.b64decode('R0lGODlhAQABAIABAP///wAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==')
62+
mimetype = 'image/gif'
63+
_logger.error(str(ex))
64+
finally:
65+
headers.append(('Content-Length', len(image_base64)))
66+
headers.append(('Content-Type', mimetype))
67+
response = request.make_response(image_base64, headers)
68+
response.status_code = 200
69+
return response
70+
71+
def placeholder(self, image='no_image.gif'):
72+
return open(util.path('jwt_provider', 'static', 'img', image), 'rb').read()

demo/demo.xml

Lines changed: 0 additions & 30 deletions
This file was deleted.

0 commit comments

Comments
 (0)