Skip to content

Commit 17b3016

Browse files
committed
More restructuring, make things more REST-y
1 parent d0f626d commit 17b3016

6 files changed

Lines changed: 228 additions & 145 deletions

File tree

oauth_provider/controllers/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44

55
from . import oauth_mixin
66

7-
from . import oauth_api_controller
7+
from . import rest_api_controller
88
from . import oauth_provider_controller

oauth_provider/controllers/oauth_api_controller.py

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

oauth_provider/controllers/oauth_mixin.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
from odoo import http
99
from odoo.addons.web.controllers.main import ensure_db
1010

11+
from ..exceptions import OauthInvalidTokenException, OauthScopeValidationException
12+
1113
#from ..http import _json_response
1214

1315

@@ -20,6 +22,48 @@
2022

2123
class OauthMixin(http.Controller):
2224

25+
def _validate_model(self, model_name, token=None):
26+
""" Validate the access token & return a usable model.
27+
28+
Args:
29+
model_name (str): Name of model to find.
30+
token (OauthProviderToken, optional): Will return the model in
31+
the scope of the token user, if defined.
32+
33+
Returns:
34+
IrModel: Usable model object that matched model_name.
35+
36+
Raises:
37+
OauthApiException: If the model is not found.
38+
"""
39+
ensure_db()
40+
model_obj = http.request.env['ir.model'].search([
41+
('model', '=', model_name),
42+
])
43+
if not model_obj:
44+
raise OauthApiException('Model Not Found')
45+
if token is not None:
46+
model_obj = model_obj.sudo(user=token.user_id)
47+
return model_obj
48+
49+
def _validate_token(self, access_token):
50+
""" Find the access token & return it if valid.
51+
52+
Args:
53+
access_token (str): Access token that should be validated.
54+
55+
Returns:
56+
OAuthProviderToken: Token record, if valid.
57+
58+
Raises:
59+
OauthInvalidTokenException: When the token is invalid or expired.
60+
"""
61+
ensure_db()
62+
token = self._get_access_token(access_token)
63+
if not token:
64+
raise OauthInvalidTokenException()
65+
return token
66+
2367
@classmethod
2468
def _get_access_token(cls, access_token):
2569
""" Verify access token and return record if valid.
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
# -*- coding: utf-8 -*-
2+
# Copyright 2016 SYLEAM
3+
# Copyright 2017 LasLabs Inc.
4+
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).
5+
6+
import logging
7+
8+
from odoo import http, fields
9+
from odoo.addons.web.controllers.main import ensure_db
10+
11+
from ..exceptions import OauthApiException, OauthInvalidTokenException
12+
from .oauth_mixin import OauthMixin
13+
14+
_logger = logging.getLogger(__name__)
15+
16+
17+
class RestApiController(OauthMixin):
18+
19+
API_VERSION = '1.0'
20+
21+
@http.route(
22+
'/api/rest/%s/<string:model>/search' % API_VERSION,
23+
type='json',
24+
auth='none',
25+
methods=['POST'],
26+
)
27+
def rest_search(self, access_token, model, domain=None, *a, **kw):
28+
""" Return allowed information from all records, with optional query.
29+
30+
Args:
31+
access_token (str): OAuth2 access token to utilize for the
32+
operation.
33+
model (str): Name of model to operate on.
34+
domain (list, optional): Domain to apply to the search, in the
35+
standard Odoo format. This will be appended to the scope's
36+
pre-existing filter.
37+
"""
38+
token = self._validate_token(access_token)
39+
self._validate_model(model)
40+
data = token.get_data(model, domain=domain)
41+
return data
42+
43+
@http.route(
44+
'/api/rest/%s/<string:model>/' % API_VERSION,
45+
type='json',
46+
auth='none',
47+
methods=['GET'],
48+
)
49+
def rest_list(self, access_token, model, *a, **kw):
50+
""" Return allowed information from all records.
51+
52+
Args:
53+
access_token (str): OAuth2 access token to utilize for the
54+
operation.
55+
model (str): Name of model to operate on.
56+
"""
57+
return self.rest_search(access_token, model)
58+
59+
@http.route(
60+
'/api/rest/%s/<string:model>/<int:record_id>' % API_VERSION,
61+
type='json',
62+
auth='none',
63+
methods=['GET'],
64+
)
65+
def rest_read(self, access_token, model, record_id, *a, **kw):
66+
""" Return allowed information from specific records.
67+
68+
Args:
69+
access_token (str): OAuth2 access token to utilize for the
70+
operation.
71+
model (str): Name of model to operate on.
72+
record_id (int): ID of record to get.
73+
"""
74+
token = self._validate_token(access_token)
75+
self._validate_model(model)
76+
data = token.get_data(model, record_id)
77+
return data
78+
79+
@http.route(
80+
'/api/rest/%s/<string:model>/' % API_VERSION,
81+
type='json',
82+
auth='none',
83+
methods=['POST'],
84+
)
85+
def rest_create(self, access_token, model, *args, **kwargs):
86+
""" Create and return new record. """
87+
token = self._validate_token(access_token)
88+
self._validate_model(model)
89+
record = token.create_record(model, kwargs)
90+
return record.read()
91+
92+
@http.route(
93+
'/api/rest/%s/<string:model>/<int:record_id>' % API_VERSION,
94+
type='json',
95+
auth='none',
96+
methods=['PUT'],
97+
)
98+
def rest_write(self, access_token, model, record_id=None,
99+
record_ids=None, *args, **kwargs):
100+
101+
if record_ids is None:
102+
record_ids = []
103+
if record_id is not None:
104+
record_ids.append(record_id)
105+
106+
token = self._validate_token(access_token)
107+
self._validate_model(model)
108+
record = token.write_record(model, record_ids, kwargs)
109+
110+
return record.read()
111+
112+
@http.route(
113+
'/api/rest/%s/<string:model>/' % API_VERSION,
114+
type='json',
115+
auth='none',
116+
methods=['DELETE'],
117+
)
118+
def data_delete(self, access_token, model, record_id=None,
119+
record_ids=None, *args, **kwargs):
120+
121+
if record_ids is None:
122+
record_ids = []
123+
if record_id is not None:
124+
record_ids.append(record_id)
125+
126+
token = self._validate_token(access_token)
127+
self._validate_model(model)
128+
token.delete_record(model, record_ids)
129+
130+
return True

0 commit comments

Comments
 (0)