diff --git a/galicea_base/README.md b/galicea_base/README.md
new file mode 100644
index 0000000..ffdcdb9
--- /dev/null
+++ b/galicea_base/README.md
@@ -0,0 +1 @@
+Base menu for Odoo Galicea Ecosystem
diff --git a/galicea_base/__init__.py b/galicea_base/__init__.py
new file mode 100644
index 0000000..633f866
--- /dev/null
+++ b/galicea_base/__init__.py
@@ -0,0 +1,2 @@
+# -*- coding: utf-8 -*-
+
diff --git a/galicea_base/__manifest__.py b/galicea_base/__manifest__.py
new file mode 100644
index 0000000..576af3e
--- /dev/null
+++ b/galicea_base/__manifest__.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+{
+ 'name': "Base menu for Odoo Galicea Ecosystem",
+
+ 'summary': """
+ Menu only
+ """,
+
+ 'author': "Jurek Wawro",
+ 'maintainer': "Galicea",
+ 'website': "http://galicea.pl",
+
+ 'category': 'Technical Settings',
+ 'version': '12.0.1.0',
+
+ 'depends': ['web',],
+
+ 'data': [
+ 'views/base_menu.xml',
+ ],
+
+ 'installable': True
+}
diff --git a/galicea_base/views/base_menu.xml b/galicea_base/views/base_menu.xml
new file mode 100644
index 0000000..02fc5b3
--- /dev/null
+++ b/galicea_base/views/base_menu.xml
@@ -0,0 +1,6 @@
+
+
=x.y.z,
>=x.y.z,
^x.z.y,
~x.y.z. Got{}""".format(cgi.escape(self.dependency['version'])) ) - parsed_installed_version = map(int, installed_version.split('.')) + parsed_installed_version = list(map(int, installed_version.split('.'))) parsed_version.extend(0 for _ in range(len(parsed_installed_version) - len(parsed_version))) parsed_installed_version.extend(0 for _ in range(len(parsed_version) - len(parsed_installed_version))) @@ -132,7 +134,7 @@ class ExternalDependencyCheck(DependencyCheck): def _installed_version(self, env, name): try: exe = which(name) - out = subprocess.check_output([exe, '--version']) + out = str(subprocess.check_output([exe, '--version'])) # Py3 str() match = re.search('[\d.]+', out) if not match: raise CheckWarning( diff --git a/galicea_environment_checkup/environment_checkup/runtime.py b/galicea_environment_checkup/environment_checkup/runtime.py index b9bc9b7..252f8cc 100644 --- a/galicea_environment_checkup/environment_checkup/runtime.py +++ b/galicea_environment_checkup/environment_checkup/runtime.py @@ -1,6 +1,6 @@ # -*- coding: utf-8 -*- -import custom, dependencies +from . import custom, dependencies def all_installed_checks(env): result = [] diff --git a/galicea_environment_checkup/static/src/js/environment_checkup.js b/galicea_environment_checkup/static/src/js/environment_checkup.js index c6fec5a..6445bd0 100644 --- a/galicea_environment_checkup/static/src/js/environment_checkup.js +++ b/galicea_environment_checkup/static/src/js/environment_checkup.js @@ -1,69 +1,79 @@ -odoo.define('galicea_environment_checkup', function(require) { - "use strict"; - - var core = require('web.core'); - var form_common = require('web.form_common'); - var Widget = require('web.Widget'); - var session = require('web.session'); - var QWeb = core.qweb; - var SystrayMenu = require('web.SystrayMenu'); - var Model = require('web.Model'); - - var Users = new Model('res.users'); - - var SystrayIcon = Widget.extend({ - tagName: 'li', - events: { - "click": "on_click", - }, - - start: function(){ - this.load(this.all_dashboards); - return this._super(); - }, - - load: function(dashboards){ - var self = this; - var loading_done = new $.Deferred(); - Users.call('has_group', ['base.group_erp_manager']).then(function(is_admin) { - if (is_admin) { - session.rpc('/galicea_environment_checkup/data', {}) - .then(function (data) { - var counts = { 'success': 0, 'warning': 0, 'fail': 0 }; - data.forEach(function (check) { ++counts[check.result]; }); - - var result; - if (counts['fail']) { - result = 'fail'; - } else if (counts['warning']) { - result = 'warning'; - } else { - result = 'success'; - } - - self.replaceElement(QWeb.render('GaliceaEnvironmentCheckupIcon', { - 'result': result, - 'count': counts['warning'] + counts['fail'] - })); - loading_done.resolve(); - }); - } else { - loading_done.resolve(); - } - }); +odoo.define('galicea_environment_checkup', function (require) { +"use strict"; + +//var SystrayMenu = require('web.SystrayMenu'); +//var Model = require('web.Model'); + +var AbstractAction = require('web.AbstractAction'); +var core = require('web.core'); +//var framework = require('web.framework'); +var session = require('web.session'); +//var Widget = require('web.Widget'); +////////////////// +var QWeb = core.qweb; +//var _t = core._t; + +/* SystrayIcon - nie działa poprawnie ??? +//https://www.odoo.com/documentation/12.0/reference/javascript_reference.html +var Model = require('web.Model'); + +var Users = new Model('res.users'); + +var SystrayIcon = Widget.extend({ + tagName: 'li', + events: { + "click": "on_click", + }, + + start: function(){ + this.load(this.all_dashboards); + return this._super(); + }, + + load: function(dashboards){ + var self = this; + var loading_done = new $.Deferred(); + Users.call('has_group', ['base.group_erp_manager']).then(function(is_admin) { + if (is_admin) { + session.rpc('/galicea_environment_checkup/data', {}) + .then(function (data) { + var counts = { 'success': 0, 'warning': 0, 'fail': 0 }; + data.forEach(function (check) { ++counts[check.result]; }); + + var result; + if (counts['fail']) { + result = 'fail'; + } else if (counts['warning']) { + result = 'warning'; + } else { + result = 'success'; + } + + self.replaceElement(QWeb.render('GaliceaEnvironmentCheckupIcon', { + 'result': result, + 'count': counts['warning'] + counts['fail'] + })); + loading_done.resolve(); + }); + } else { + loading_done.resolve(); + } + }); - return loading_done; - }, + return loading_done; + }, - on_click: function (event) { - event.preventDefault(); - this.do_action('galicea_environment_checkup.dashboard_action', {clear_breadcrumbs: true}); - }, - }); + on_click: function (event) { + event.preventDefault(); + this.do_action('galicea_environment_checkup.dashboard_action', {clear_breadcrumbs: true}); + }, +}); - SystrayMenu.Items.push(SystrayIcon); +*/ - var Dashboard = Widget.extend({ +///////////////////////////// +var Dashboard = AbstractAction.extend({ +// v.10 var Dashboard = Widget.extend({ start: function(){ return this.load(this.all_dashboards); }, @@ -73,16 +83,18 @@ odoo.define('galicea_environment_checkup', function(require) { var loading_done = new $.Deferred(); session.rpc('/galicea_environment_checkup/data', {}) .then(function (data) { - self.replaceElement(QWeb.render('GaliceaEnvironmentCheckupDashboard', {'data': data})); + self._replaceElement(QWeb.render('GaliceaEnvironmentCheckupDashboard', {'data': data})); // v.10: self.replaceElement loading_done.resolve(); }); return loading_done; }, }); - core.action_registry.add('galicea_environment_checkup.dashboard', Dashboard); - - var FormWidget = form_common.AbstractField.extend({ +//!JW - nowa propozycja: core.action_registry.add('galicea_environment_checkup.environment_checkup', Dashboard); +core.action_registry.add('galicea_environment_checkup.dashboard', Dashboard); +//////////////////// +/* v.10 +var FormWidget = form_common.AbstractField.extend({ init: function() { this._super.apply(this, arguments); this.set("value", "[]"); @@ -99,10 +111,36 @@ odoo.define('galicea_environment_checkup', function(require) { }); core.form_widget_registry.add('environment_checks', FormWidget); +*/ +var FormView = require('web.FormView'); + +var FormWidget = FormView.extend({ + + template: "environment_checks", - return { - SystrayIcon: SystrayIcon, + init: function() { + this._super.apply(this, arguments); + this.set("value", "[]"); + }, + + events: { + }, + + render_value: function() { + var data = JSON.parse(this.get('value')); + if (data.length == 0) { + this._replaceElement(''); + return; + } + this._replaceElement(QWeb.render('GaliceaEnvironmentCheckupFormWidget', {'data': data})); + } +}); + +//////////////////// +return { +//!! SystrayIcon: SystrayIcon, Dashboard: Dashboard, FormWidget: FormWidget - }; +}; + }); diff --git a/galicea_environment_checkup/static/src/js/environment_checkup10.js b/galicea_environment_checkup/static/src/js/environment_checkup10.js new file mode 100644 index 0000000..c6fec5a --- /dev/null +++ b/galicea_environment_checkup/static/src/js/environment_checkup10.js @@ -0,0 +1,108 @@ +odoo.define('galicea_environment_checkup', function(require) { + "use strict"; + + var core = require('web.core'); + var form_common = require('web.form_common'); + var Widget = require('web.Widget'); + var session = require('web.session'); + var QWeb = core.qweb; + var SystrayMenu = require('web.SystrayMenu'); + var Model = require('web.Model'); + + var Users = new Model('res.users'); + + var SystrayIcon = Widget.extend({ + tagName: 'li', + events: { + "click": "on_click", + }, + + start: function(){ + this.load(this.all_dashboards); + return this._super(); + }, + + load: function(dashboards){ + var self = this; + var loading_done = new $.Deferred(); + Users.call('has_group', ['base.group_erp_manager']).then(function(is_admin) { + if (is_admin) { + session.rpc('/galicea_environment_checkup/data', {}) + .then(function (data) { + var counts = { 'success': 0, 'warning': 0, 'fail': 0 }; + data.forEach(function (check) { ++counts[check.result]; }); + + var result; + if (counts['fail']) { + result = 'fail'; + } else if (counts['warning']) { + result = 'warning'; + } else { + result = 'success'; + } + + self.replaceElement(QWeb.render('GaliceaEnvironmentCheckupIcon', { + 'result': result, + 'count': counts['warning'] + counts['fail'] + })); + loading_done.resolve(); + }); + } else { + loading_done.resolve(); + } + }); + + return loading_done; + }, + + on_click: function (event) { + event.preventDefault(); + this.do_action('galicea_environment_checkup.dashboard_action', {clear_breadcrumbs: true}); + }, + }); + + SystrayMenu.Items.push(SystrayIcon); + + var Dashboard = Widget.extend({ + start: function(){ + return this.load(this.all_dashboards); + }, + + load: function(dashboards) { + var self = this; + var loading_done = new $.Deferred(); + session.rpc('/galicea_environment_checkup/data', {}) + .then(function (data) { + self.replaceElement(QWeb.render('GaliceaEnvironmentCheckupDashboard', {'data': data})); + loading_done.resolve(); + }); + return loading_done; + }, + }); + + core.action_registry.add('galicea_environment_checkup.dashboard', Dashboard); + + var FormWidget = form_common.AbstractField.extend({ + init: function() { + this._super.apply(this, arguments); + this.set("value", "[]"); + }, + + render_value: function() { + var data = JSON.parse(this.get('value')); + if (data.length == 0) { + this.replaceElement(''); + return; + } + this.replaceElement(QWeb.render('GaliceaEnvironmentCheckupFormWidget', {'data': data})); + }, + }); + + core.form_widget_registry.add('environment_checks', FormWidget); + + return { + SystrayIcon: SystrayIcon, + Dashboard: Dashboard, + FormWidget: FormWidget + }; +}); diff --git a/galicea_environment_checkup/static/src/xml/templates.xml b/galicea_environment_checkup/static/src/xml/templates.xml index 12fa26e..7039c07 100644 --- a/galicea_environment_checkup/static/src/xml/templates.xml +++ b/galicea_environment_checkup/static/src/xml/templates.xml @@ -27,13 +27,13 @@- + - + - + diff --git a/galicea_environment_checkup/views/views.xml b/galicea_environment_checkup/views/views.xml index 7a4071b..c3c0b32 100644 --- a/galicea_environment_checkup/views/views.xml +++ b/galicea_environment_checkup/views/views.xml @@ -5,7 +5,7 @@galicea_environment_checkup.dashboard + action="dashboard_action" parent="galicea_base.galicea_admin_menu" groups="base.group_erp_manager" />module_form.checks diff --git a/galicea_git/__manifest__.py b/galicea_git/__manifest__.py index 63f5e8d..95e98f5 100644 --- a/galicea_git/__manifest__.py +++ b/galicea_git/__manifest__.py @@ -9,9 +9,9 @@ 'website': "http://galicea.pl", 'category': 'Technical Settings', - 'version': '10.0.1.0', + 'version': '12.0.0.1', - 'depends': ['web', 'galicea_environment_checkup'], + 'depends': ['web', 'galicea_environment_checkup','galicea_base'], 'external_dependencies': { 'bin': ['git'] diff --git a/galicea_git/controllers/main.py b/galicea_git/controllers/main.py index 96abad9..52f66c9 100644 --- a/galicea_git/controllers/main.py +++ b/galicea_git/controllers/main.py @@ -65,14 +65,14 @@ class Main(http.Controller): shell=True ) stdout, stderr = git.communicate(http_input_stream(request).read()) - headers_str, body = stdout.split("\r\n\r\n", 2) + headers_str, body = stdout.split(b"\r\n\r\n", 2) http_status_code = 200 headers = [] - for header in headers_str.split("\r\n"): - name, value = header.split(': ', 2) + for header in headers_str.split(b"\r\n"): + name, value = header.split(b': ', 2) if name == 'Status': - http_code = int(value.split(' ')[0]) + http_code = int(value.split(b' ')[0]) else: headers.append((name, value)) diff --git a/galicea_git/data/config.xml b/galicea_git/data/config.xml index 1c984af..7f998dc 100644 --- a/galicea_git/data/config.xml +++ b/galicea_git/data/config.xml @@ -1,9 +1,12 @@ +- - diff --git a/galicea_git/models/repository.py b/galicea_git/models/repository.py index 7a7561f..1607502 100644 --- a/galicea_git/models/repository.py +++ b/galicea_git/models/repository.py @@ -5,6 +5,11 @@ import random import shutil import string import subprocess +try: + import git +except ImportError: + pass + from odoo import models, fields, api, http from odoo.exceptions import ValidationError @@ -56,7 +61,7 @@ class Repository(models.Model): @api.constrains('system_name') def _validate_system_name(self): - allowed_characters = string.ascii_lowercase + string.digits + '-' + allowed_characters = string.ascii_lowercase + string.digits + '-_' if not all(c in allowed_characters for c in self.system_name): raise ValidationError( 'Only lowercase, digits and hyphens (-) are allowed in directory name' diff --git a/galicea_git/views/views.org.xml b/galicea_git/views/views.org.xml new file mode 100644 index 0000000..ea11d5f --- /dev/null +++ b/galicea_git/views/views.org.xml @@ -0,0 +1,71 @@ +- + + +galicea_git.git_http_backend -/usr/lib/git-core/git-http-backend -- + +galicea_git.git_http_backend +/usr/lib/git-core/git-http-backend ++ + + diff --git a/galicea_git/views/views.xml b/galicea_git/views/views.xml index 86d808d..56f94d2 100644 --- a/galicea_git/views/views.xml +++ b/galicea_git/views/views.xml @@ -1,5 +1,8 @@ ++ + +galicea_git.repository ++ + ++ + +galicea_git.repository ++ ++ ++ + + + + + + +galicea_git.config.settings ++ + ++ + + + + + - diff --git a/galicea_openapi/__init__.py b/galicea_openapi/__init__.py new file mode 100644 index 0000000..4ca83e8 --- /dev/null +++ b/galicea_openapi/__init__.py @@ -0,0 +1,5 @@ +# -*- coding: utf-8 -*- + +#from . import models +from . import controllers + diff --git a/galicea_openapi/__manifest__.py b/galicea_openapi/__manifest__.py new file mode 100644 index 0000000..2321139 --- /dev/null +++ b/galicea_openapi/__manifest__.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +{ + 'name': "openapi", + + 'summary': """ + Odoo Opnapi + UWAGA! Obecnie dekorator apiroute ma ograniczoną funkcjonalność. + M.in. tylko jeden URL + controllers/api.py zawiera przykład wykorzystania - + pod adresem /oapi/api zwraca dokumentację w JSON + """, + + 'description': """ + + """, + + 'author': 'Jerzy Wawro', + 'maintainer': "Galicea", + 'website': "http://www.galicea.pl", + 'category': 'Tools', + 'version': '12.0.0.1', + + 'depends': [ + ], + 'external_dependencies': { + 'python': [ 'fastapi', 'pydantic', 'starlette' ] + }, + 'data': [ + ], + 'application': True, + 'installable': True, + +} diff --git a/galicea_openapi/controllers/__init__.py b/galicea_openapi/controllers/__init__.py new file mode 100644 index 0000000..f8bf31f --- /dev/null +++ b/galicea_openapi/controllers/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- + +from . import api + diff --git a/galicea_openapi/controllers/api.py b/galicea_openapi/controllers/api.py new file mode 100644 index 0000000..4871c3b --- /dev/null +++ b/galicea_openapi/controllers/api.py @@ -0,0 +1,56 @@ +# -*- coding: utf-8 -*- + +import json + +from fastapi.openapi.docs import get_swagger_ui_html + +from odoo import http, _ +from ..openapi import apiroute +from ..openapi import oapi + + + + + +class OpenApiTest(http.Controller): + + + @http.route(['/oapi/tst1',], type='http', auth="user", website=True) + def tst1(self, **kw): + return "tst1" + + @oapi.get('/oapi/tst2') + @http.route(['/oapi/tst2',], type='http', auth="user", website=True) + def tst2(self): + return 'ok test2' + + @oapi.api_route('/oapi/tst3') + @http.route(['/oapi/tst3',], type='http', auth="user", website=True) + def tst3(self, par1="abc"): + return par1 + + + @oapi.api_route('/oapi/tst4') + @http.route(['/oapi/tst4', ], type='http', auth="user", website=True) + def tst4(self,par1="444"): + return par1 + + + @apiroute('/oapi/tst5') + def tst5(self, par1="555"): + return par1 + + @http.route(['/oapi/api',], type='http', auth="user", website=True) + def api(self, **kw): + return json.dumps(oapi.openapi()) +# wynik możesz skopiować do https://editor.swagger.io/ + + @http.route(['/oapi/docs',], type='http', auth="user", website=True) + def api_UI(self, **kw): + response = get_swagger_ui_html(openapi_url = '/oapi/api', title = 'tytuł') + return response.body + + + + + diff --git a/galicea_openapi/doc/helloworld.py b/galicea_openapi/doc/helloworld.py new file mode 100644 index 0000000..4d082fb --- /dev/null +++ b/galicea_openapi/doc/helloworld.py @@ -0,0 +1,22 @@ +# pip install fastapi +# pip install email-validator +# pip install pydantic +# pip install starlette +# pip install uvicorn + +import uvicorn +from fastapi import FastAPI + +app = FastAPI() + + +@app.get("/") +def read_root(): + return {"Hello": "World"} + +def run_server(): + uvicorn.run(app) + +if __name__ == '__main__': + uvicorn.run(app, #'server:app', + host='127.0.0.1', port=8000, reload=True) \ No newline at end of file diff --git a/galicea_openapi/doc/test1.py b/galicea_openapi/doc/test1.py new file mode 100644 index 0000000..bc31151 --- /dev/null +++ b/galicea_openapi/doc/test1.py @@ -0,0 +1,41 @@ +# pip install fastapi +# pip install email-validator +# pip install pydantic +# pip install starlette +# pip install uvicorn + +import uvicorn +from fastapi import FastAPI +from fastapi.openapi.utils import get_openapi + +app = FastAPI() + + +@app.get("/items/") +async def read_items(): + return [{"name": "Foo"}] + + +def custom_openapi(): + if app.openapi_schema: + return app.openapi_schema + openapi_schema = get_openapi( + title="Custom title", + version="2.5.0", + description="This is a very custom OpenAPI schema", + routes=app.routes, + ) + openapi_schema["info"]["x-logo"] = { + "url": "https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" + } + app.openapi_schema = openapi_schema + return app.openapi_schema + + +app.openapi = custom_openapi + + +if __name__ == '__main__': + print("see http://127.0.0.1:8000/docs") + uvicorn.run(app, #'server:app', + host='127.0.0.1', port=8000, reload=True) diff --git a/galicea_openapi/models/__init__.py b/galicea_openapi/models/__init__.py new file mode 100644 index 0000000..faaaf79 --- /dev/null +++ b/galicea_openapi/models/__init__.py @@ -0,0 +1,3 @@ +# -*- coding: utf-8 -*- + + diff --git a/galicea_openapi/openapi.py b/galicea_openapi/openapi.py new file mode 100644 index 0000000..549f4aa --- /dev/null +++ b/galicea_openapi/openapi.py @@ -0,0 +1,52 @@ +# -*- coding: utf-8 -*- + + +import functools +from fastapi import FastAPI +from fastapi.openapi.utils import get_openapi + + + +def custom_openapi(): + if oapi.openapi_schema: + return oapi.openapi_schema + openapi_schema = get_openapi( + title="Custom title", + version="2.5.0", + description="This is a very custom OpenAPI schema", + routes=oapi.routes, + ) + openapi_schema["info"]["x-logo"] = { + "url": "https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" + } + oapi.openapi_schema = openapi_schema + return oapi.openapi_schema + +oapi = FastAPI() +oapi.openapi = custom_openapi + +def apiroute(route=None, **kw): + + routing = kw.copy() + def apidecorator(f): + if route: + if isinstance(route, list): + routes = route + else: + routes = [route] + routing['routes'] = routes + + @functools.wraps(f) + def response_wrap(*args, **kw): + response = f(*args, **kw) + return response + + oapi.add_api_route(routes[0], f, include_in_schema=True) + response_wrap.routing = routing + response_wrap.original_func = f + return response_wrap + + return apidecorator + + +# \ No newline at end of file diff --git a/galicea_openapi/security/ir.model.access.csv b/galicea_openapi/security/ir.model.access.csv new file mode 100644 index 0000000..de4392b --- /dev/null +++ b/galicea_openapi/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_galicea_openapi,galicea_openapi,model_galicea_openapi_openapi_script,galicea_openapi.script,1,1,1,0 diff --git a/galicea_openapi/static/description/icon.png b/galicea_openapi/static/description/icon.png new file mode 100644 index 0000000..d357260 Binary files /dev/null and b/galicea_openapi/static/description/icon.png differ diff --git a/galicea_openid_connect/__init__.py b/galicea_openid_connect/__init__.py index 26e263a..e84f253 100644 --- a/galicea_openid_connect/__init__.py +++ b/galicea_openid_connect/__init__.py @@ -3,3 +3,5 @@ from . import controllers from . import models from . import system_checks + +from . import api diff --git a/galicea_openid_connect/__manifest__.py b/galicea_openid_connect/__manifest__.py index 4a8f194..e157b73 100644 --- a/galicea_openid_connect/__manifest__.py +++ b/galicea_openid_connect/__manifest__.py @@ -9,9 +9,9 @@ 'website': "http://galicea.pl", 'category': 'Technical Settings', - 'version': '10.0.1.3', + 'version': '12.0.0.0', - 'depends': ['web', 'galicea_environment_checkup'], + 'depends': ['web', 'galicea_environment_checkup', 'galicea_base' ], 'external_dependencies': { 'python': ['jwcrypto', 'cryptography'] @@ -20,8 +20,8 @@ 'data': [ 'security/security.xml', 'security/ir.model.access.csv', - 'security/init.yml', - +# 'security/init.yml', + 'security/init.xml', 'views/views.xml', 'views/templates.xml' ], diff --git a/galicea_openid_connect/api.py b/galicea_openid_connect/api.py index a3c06ec..8b33e40 100644 --- a/galicea_openid_connect/api.py +++ b/galicea_openid_connect/api.py @@ -16,13 +16,7 @@ class ApiException(Exception): super(Exception, self).__init__(message) self.code = code if code else self.INVALID_REQUEST - def to_json(self): - return { - 'error': self.code, - 'error_message': self.message - } - -def resource(path, method, auth='user', clients=None): +def resource(path, method, auth='user'): assert auth in ['user', 'client'] def endpoint_decorator(func): @@ -33,7 +27,6 @@ def resource(path, method, auth='user', clients=None): 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Headers': 'Origin, X-Requested-With, Content-Type, Accept, X-Debug-Mode, Authorization', 'Access-Control-Max-Age': 60 * 60 * 24, - 'Access-Control-Allow-Methods': 'OPTIONS, HEAD, GET, POST, PUT, DELETE' } if req.httprequest.method == 'OPTIONS': return http.Response( @@ -75,10 +68,6 @@ def resource(path, method, auth='user', clients=None): ) req.uid = token.client_id.system_user_id.id - if clients: - if token.client_id.id not in map(lambda c: req.env.ref(c).id, clients): - raise ApiException('Access denied', 'restricted_app') - ctx = req.context.copy() ctx.update({'client_id': token.client_id.id}) req.context = ctx @@ -89,17 +78,23 @@ def resource(path, method, auth='user', clients=None): headers=cors_headers, status=200 ) - except Exception as e: - status = 400 - if not isinstance(e, ApiException): - _logger.exception('Unexpected exception while processing API request') - e = ApiException('Unexpected server error', 'server_error') - status = 500 + except ApiException as e: + error_message = "error: {0}".format(e) return werkzeug.Response( - response=json.dumps(e.to_json()), - status=status, + response=json.dumps({'error': e.code, 'error_message': error_message}), + status=400, headers=cors_headers ) + except: + _logger.exception('Unexpected exception while processing API request') + return werkzeug.Response( + response=json.dumps({ + 'error': 'server_error', + 'error_message': 'Unexpected server error', + }), + headers=cors_headers, + status=500 + ) return func_wrapper return endpoint_decorator diff --git a/galicea_openid_connect/controllers/main.py b/galicea_openid_connect/controllers/main.py index d5419a3..2fafaf2 100644 --- a/galicea_openid_connect/controllers/main.py +++ b/galicea_openid_connect/controllers/main.py @@ -47,7 +47,6 @@ class OAuthException(Exception): UNSUPPORTED_RESPONSE_TYPE = 'unsupported_response_type' INVALID_GRANT = 'invalid_grant' UNSUPPORTED_GRANT_TYPE = 'unsupported_grant_type' - RESTRICTED_APP = 'restricted_app' def __init__(self, message, type): super(Exception, self).__init__(message) @@ -104,15 +103,6 @@ class Main(http.Controller): OAuthException.INVALID_CLIENT, ) - def __validate_user(self, client, user): - if not client.user_group_id: - return - if client.user_group_id not in user.groups_id: - raise OAuthException( - 'User is not allowed to use this client', - OAuthException.RESTRICTED_APP - ) - @http.route('/.well-known/openid-configuration', auth='public', type='http') def metadata(self, req, **query): base_url = http.request.httprequest.host_url @@ -216,7 +206,6 @@ class Main(http.Controller): } return self.__redirect('/web/login', params, 'query') - self.__validate_user(client, user) response_types = response_type.split() extra_claims = { @@ -366,7 +355,7 @@ class Main(http.Controller): 'Invalid username or password', OAuthException.INVALID_REQUEST ) - self.__validate_user(client, req.env['res.users'].sudo().browse(user_id)) + scopes = query['scope'].split(' ') if query.get('scope') else [] # Retrieve/generate access token. We currently only store one per user/client token = req.env['galicea_openid_connect.access_token'].sudo().retrieve_or_create( diff --git a/galicea_openid_connect/models/__init__.py b/galicea_openid_connect/models/__init__.py index c5f0513..d6be90d 100644 --- a/galicea_openid_connect/models/__init__.py +++ b/galicea_openid_connect/models/__init__.py @@ -2,3 +2,4 @@ from . import client from . import access_token +from . import config_parameter \ No newline at end of file diff --git a/galicea_openid_connect/models/client.py b/galicea_openid_connect/models/client.py index 70f353e..0c00e20 100644 --- a/galicea_openid_connect/models/client.py +++ b/galicea_openid_connect/models/client.py @@ -34,10 +34,6 @@ class Client(models.Model): string='Allow OAuth2 password grant', default=False, ) - user_group_id = fields.Many2one( - 'res.groups', - 'Restrict the client to a group' - ) @api.model def __system_user_name(self, client_name): diff --git a/galicea_openid_connect/models/config_parameter.py b/galicea_openid_connect/models/config_parameter.py new file mode 100644 index 0000000..ffa9286 --- /dev/null +++ b/galicea_openid_connect/models/config_parameter.py @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- + +from odoo import models, fields, api +from .. import random_tokens +try: + from jwcrypto import jwk +except ImportError: + pass + +class ConfigParameter(models.Model): + _inherit = 'ir.config_parameter' + + @api.model + def openid_init_keys(self): + keys = { + 'galicea_openid_connect.authorization_code_jwk': lambda: \ + jwk.JWK.generate(kty='oct', size=256, kid=random_tokens.alpha_numeric(16), use='sig', alg='HS256').export(), + 'galicea_openid_connect.id_token_jwk': lambda: \ + jwk.JWK.generate(kty='RSA', size=2054, kid=random_tokens.alpha_numeric(16), use='sig', alg='RS256').export() + } + + for key, gen in iter(keys.items()): + if not self.search([('key', '=', key)]): + self.create({ + 'key': key, + 'value': gen(), + 'group_ids': [(4, self.env.ref('base.group_erp_manager').id)] + }) diff --git a/galicea_openid_connect/random_tokens.py b/galicea_openid_connect/random_tokens.py index d448b42..1eee816 100644 --- a/galicea_openid_connect/random_tokens.py +++ b/galicea_openid_connect/random_tokens.py @@ -3,7 +3,7 @@ from random import SystemRandom def random_token(length, byte_filter): - allowed_bytes = ''.join(c for c in map(chr, range(256)) if byte_filter(c)) + allowed_bytes = ''.join(c for c in map(chr, range(128)) if byte_filter(c)) random = SystemRandom() return ''.join([random.choice(allowed_bytes) for _ in range(length)]) diff --git a/galicea_openid_connect/security/init.xml b/galicea_openid_connect/security/init.xml new file mode 100644 index 0000000..6a8285d --- /dev/null +++ b/galicea_openid_connect/security/init.xml @@ -0,0 +1,8 @@ + ++ + + galicea_git.repository + + diff --git a/galicea_openid_connect/views/views.xml b/galicea_openid_connect/views/views.xml index facd3e1..5fd28fc 100644 --- a/galicea_openid_connect/views/views.xml +++ b/galicea_openid_connect/views/views.xml @@ -28,7 +28,6 @@+ + - @@ -61,7 +60,7 @@ name="OpenID Clients" res_model="galicea_openid_connect.client" /> - - + diff --git a/galicea_toolset/README.md b/galicea_toolset/README.md new file mode 100644 index 0000000..0317287 --- /dev/null +++ b/galicea_toolset/README.md @@ -0,0 +1,30 @@ +Widgets +======= + + + +Creates an iframe with ``url_field`` value as a source. + + + +Allows changing the target for the item click action. + +Functions +========= + odoo.addons.galicea_toolset.utils.get_base_url(env) + +Client actions +============== + @api.multi + + def button_action(self): + + return { + + 'type': 'ir.actions.client', + + 'tag': 'galicea_toolset.open_edit_dialog', + + 'params': { 'res_id': , 'res_model': , 'title': } + + }; diff --git a/galicea_toolset/__init__.py b/galicea_toolset/__init__.py new file mode 100644 index 0000000..40a96af --- /dev/null +++ b/galicea_toolset/__init__.py @@ -0,0 +1 @@ +# -*- coding: utf-8 -*- diff --git a/galicea_toolset/__manifest__.py b/galicea_toolset/__manifest__.py new file mode 100644 index 0000000..89b713f --- /dev/null +++ b/galicea_toolset/__manifest__.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +{ + 'name': "galicea toolset", + + 'summary': """ + A couple of small convenience widgets and functions""", + + 'author': "Maciej Wawro", + 'maintainer': "Galicea", + 'website': "http://www.galicea.pl", + + 'category': 'Technical Settings', + 'version': '12.0.0.1', + + 'depends': ['base'], + + 'data': [ + 'views/data.xml' + ], +} diff --git a/galicea_toolset/static/src/js/.#one2many_flexible_widget.js b/galicea_toolset/static/src/js/.#one2many_flexible_widget.js new file mode 120000 index 0000000..c86faaa --- /dev/null +++ b/galicea_toolset/static/src/js/.#one2many_flexible_widget.js @@ -0,0 +1 @@ +jurek@jurek.15022 \ No newline at end of file diff --git a/galicea_toolset/static/src/js/client_actions.js b/galicea_toolset/static/src/js/client_actions.js new file mode 100644 index 0000000..1011aaf --- /dev/null +++ b/galicea_toolset/static/src/js/client_actions.js @@ -0,0 +1,38 @@ +odoo.define('galicea_toolset.client_actions', function(require) { + var Widget = require('web.Widget'); + var core = require('web.core'); + var common = require('web.form_common'); + var ActionManager = require('web.ActionManager'); + + var OpenEditDialogAction = Widget.extend({ + init: function(parent, context) { + this._super.apply(this, arguments); + this.context = context; + if (parent instanceof ActionManager) { + this.am = parent; + } + }, + + start: function () { + var params = this.context.params; + + var popup = new common.FormViewDialog(self, { + title: params.title, + res_model: params.res_model, + res_id: params.res_id, + }).open(); + popup.on('closed', this, function() { + this.am && this.am.history_back(); + }); + }, + }); + + core.action_registry.add( + 'galicea_toolset.open_edit_dialog', + OpenEditDialogAction + ); + + return { + open_edit_dialog_action: OpenEditDialogAction, + }; +}); diff --git a/galicea_toolset/static/src/js/iframe_widget.js b/galicea_toolset/static/src/js/iframe_widget.js new file mode 100644 index 0000000..3266bc9 --- /dev/null +++ b/galicea_toolset/static/src/js/iframe_widget.js @@ -0,0 +1,49 @@ +odoo.define('pwste_epub.iframe_widget', function(require) { + + var AbstractField = require('web.AbstractField'); + var fieldRegistry = require('web.field_registry'); + + + + var core = require('web.core'); + var Widget= require('web.Widget'); + var widgetRegistry = require('web.widget_registry'); + var FieldManagerMixin = require('web.FieldManagerMixin'); + + var IFrameWidget = AbstractField.extend({ + + init: function () { + this._super.apply(this, arguments); +// this.set("value", ""); + }, + + _renderReadonly: function() { + window.widget=this; + this.$el.html( + $('