commit
5ce8710bbf
|
|
@ -0,0 +1,2 @@
|
||||||
|
from . import models
|
||||||
|
from . import controllers
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
'name': 'Odex Web App API',
|
||||||
|
'version': '1.0',
|
||||||
|
'license': 'AGPL-3',
|
||||||
|
'category': 'Odex25-Mobile/Odex25-Mobile',
|
||||||
|
'author': 'Expert Co. Ltd.',
|
||||||
|
'website': 'http://exp-sa.com',
|
||||||
|
'summary': "All Mopile Web App Api and Configurations",
|
||||||
|
'depends': [
|
||||||
|
'base',
|
||||||
|
'attendances',
|
||||||
|
'employee_requests',
|
||||||
|
'website',
|
||||||
|
'mass_mailing',
|
||||||
|
'hr_holidays_public',
|
||||||
|
'exp_payroll_custom',
|
||||||
|
'hr_timesheet_sheet',
|
||||||
|
],
|
||||||
|
'external_dependencies': {
|
||||||
|
'python': ['jwt', ],
|
||||||
|
},
|
||||||
|
'data': [
|
||||||
|
'views/attendance_zone_config_view.xml',
|
||||||
|
'views/hr_employee_view.xml',
|
||||||
|
],
|
||||||
|
'installable': True,
|
||||||
|
'application': False,
|
||||||
|
}
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,3 @@
|
||||||
|
from . import authentication
|
||||||
|
from . import web
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,59 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import werkzeug
|
||||||
|
from odoo import http, tools
|
||||||
|
from odoo.http import request, Response
|
||||||
|
from odoo.addons.auth_signup.models.res_users import SignupError
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
import base64
|
||||||
|
from ..validator import validator
|
||||||
|
from ..http_helper import http_helper
|
||||||
|
import json
|
||||||
|
import logging
|
||||||
|
from odoo.tools.translate import _
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
SENSITIVE_FIELDS = ['password', 'password_crypt', 'new_password', 'create_uid', 'write_uid']
|
||||||
|
|
||||||
|
|
||||||
|
class AuthenticationController(http.Controller):
|
||||||
|
|
||||||
|
@http.route('/rest_api/login', type='http', auth='none', csrf=False, cors='*', methods=['POST'])
|
||||||
|
def login_phone(self, **kw):
|
||||||
|
login = kw.get('login')
|
||||||
|
password = kw.get('password')
|
||||||
|
if not login:
|
||||||
|
return http_helper.response(code=400, message=_('username or email is missing'), success=False)
|
||||||
|
|
||||||
|
if not password:
|
||||||
|
return http_helper.response(code=400, message=_('Password is missing'), success=False)
|
||||||
|
if not kw.get('device_id'):
|
||||||
|
return http_helper.response(code=400, message=_('Device id is missing'), success=False)
|
||||||
|
|
||||||
|
# check fcm_token
|
||||||
|
if not kw.get('fcm_token'):
|
||||||
|
return http_helper.response(code=400, message=_('FCM Token is missing'), success=False)
|
||||||
|
|
||||||
|
user = request.env['res.users'].sudo().search([('login', '=', login)], limit=1)
|
||||||
|
|
||||||
|
if not user or not user.login:
|
||||||
|
return http_helper.response(code=400, message=_('User account with login {} not found').format(login),
|
||||||
|
success=False)
|
||||||
|
|
||||||
|
uid = http_helper.is_authentic(login, password)
|
||||||
|
|
||||||
|
if not uid:
|
||||||
|
return http_helper.errcode(code=400, message=_('Unable to Sign In. invalid user password'))
|
||||||
|
token = validator.create_token(request.env.user)
|
||||||
|
dic = request.env.user.to_dict(True)
|
||||||
|
employee = http.request.env['hr.employee'].sudo().search([('user_id', '=', user.id)], limit=1)
|
||||||
|
if employee and kw.get('device_id') and not employee.device_id:
|
||||||
|
employee.sudo().write({'device_id': kw.get('device_id')})
|
||||||
|
|
||||||
|
# write fcm_token and fcm_token_web in employee
|
||||||
|
if employee and (kw.get('fcm_token') or kw.get('fcm_token_web')):
|
||||||
|
employee.sudo().write({'fcm_token': kw.get('fcm_token'), 'fcm_token_web': kw.get('fcm_token_web')})
|
||||||
|
|
||||||
|
dic['token'] = token
|
||||||
|
http_helper.cleanup();
|
||||||
|
return http_helper.response(data=dic, message=_("User log in successfully"))
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
import odoo
|
||||||
|
from odoo import http
|
||||||
|
from odoo.http import request
|
||||||
|
|
||||||
|
|
||||||
|
class WebController(http.Controller):
|
||||||
|
@http.route('/web/session/authenticate', type='json', auth="none")
|
||||||
|
def authenticate(self, login, password, base_location=None):
|
||||||
|
db = odoo.tools.config.get('db_name')
|
||||||
|
if not db:
|
||||||
|
response_data = {
|
||||||
|
"error": "Database name should be specified in Conf File",
|
||||||
|
"status": 400
|
||||||
|
}
|
||||||
|
return response_data
|
||||||
|
|
||||||
|
request.session.authenticate(db, login, password)
|
||||||
|
return request.env['ir.http'].session_info()
|
||||||
|
|
@ -0,0 +1,128 @@
|
||||||
|
from odoo import http
|
||||||
|
from odoo.http import request, Response
|
||||||
|
from .validator import validator
|
||||||
|
import simplejson as json
|
||||||
|
import logging
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
return_fields = ['id', 'login', 'name', 'company_id','state']
|
||||||
|
|
||||||
|
|
||||||
|
class HttpHelper:
|
||||||
|
|
||||||
|
def get_state(self):
|
||||||
|
return {
|
||||||
|
'd': request.session.db
|
||||||
|
}
|
||||||
|
|
||||||
|
def parse_request(self):
|
||||||
|
http_method = request.httprequest.method
|
||||||
|
try:
|
||||||
|
body = http.request.params
|
||||||
|
except Exception:
|
||||||
|
body = {}
|
||||||
|
|
||||||
|
headers = dict(list(request.httprequest.headers.items()))
|
||||||
|
if 'wsgi.input' in headers:
|
||||||
|
del headers['wsgi.input']
|
||||||
|
if 'wsgi.errors' in headers:
|
||||||
|
del headers['wsgi.errors']
|
||||||
|
if 'HTTP_AUTHORIZATION' in headers:
|
||||||
|
headers['Authorization'] = headers['HTTP_AUTHORIZATION']
|
||||||
|
|
||||||
|
# extract token
|
||||||
|
token = ''
|
||||||
|
if 'Authorization' in headers:
|
||||||
|
try:
|
||||||
|
# Bearer token_string
|
||||||
|
token = headers['Authorization'].split(' ')[1]
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return http_method, body, headers, token
|
||||||
|
|
||||||
|
def date2str(self, d, f='%Y-%m-%d %H:%M:%S'):
|
||||||
|
"""
|
||||||
|
Convert datetime to string
|
||||||
|
:param self:
|
||||||
|
:param d: datetime object
|
||||||
|
:param f='%Y-%m-%d%H:%M:%S': string format
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
s = d.strftime(f)
|
||||||
|
except:
|
||||||
|
s = None
|
||||||
|
finally:
|
||||||
|
return s
|
||||||
|
|
||||||
|
def response(self, success=True, message=None, data=None, code=200,errors=None):
|
||||||
|
"""
|
||||||
|
Create a HTTP Response for controller
|
||||||
|
:param success=True indicate this response is successful or not
|
||||||
|
:param message=None message string
|
||||||
|
:param data=None data to return
|
||||||
|
:param code=200 http status code
|
||||||
|
"""
|
||||||
|
payload = json.dumps({
|
||||||
|
'success': success,
|
||||||
|
'message': message,
|
||||||
|
'data': data,
|
||||||
|
'code':code
|
||||||
|
})
|
||||||
|
|
||||||
|
return Response(payload, status=code, headers=[
|
||||||
|
('Content-Type', 'application/json'),
|
||||||
|
])
|
||||||
|
|
||||||
|
def response_500(self, message='Internal Server Error', data=None):
|
||||||
|
return self.response(success=False, message=message, data=data, code=500)
|
||||||
|
|
||||||
|
def response_404(self, message='404 Not Found', data=None):
|
||||||
|
return self.response(success=False, message=message, data=data, code=404)
|
||||||
|
|
||||||
|
def response_403(self, message='403 Forbidden', data=None):
|
||||||
|
return self.response(success=False, message=message, data=data, code=403)
|
||||||
|
|
||||||
|
def errcode(self, code, message=None):
|
||||||
|
return self.response(success=False, code=code, message=message)
|
||||||
|
|
||||||
|
def is_authentic(self, login, password):
|
||||||
|
state = self.get_state()
|
||||||
|
name = login.strip()
|
||||||
|
pwd = password.strip()
|
||||||
|
return request.session.authenticate(state['d'], name, pwd)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def do_login(self, login, password):
|
||||||
|
# get current db
|
||||||
|
state = self.get_state()
|
||||||
|
name = login.strip()
|
||||||
|
pwd = password.strip()
|
||||||
|
|
||||||
|
uid = request.session.authenticate(state['d'], name, pwd)
|
||||||
|
if not uid:
|
||||||
|
return self.errcode(code=400, message='incorrect login')
|
||||||
|
# login success, generate token
|
||||||
|
token = validator.create_token(request.env.user)
|
||||||
|
dic = request.env.user.to_dict(True)
|
||||||
|
dic['token'] = token
|
||||||
|
|
||||||
|
return self.response(data=dic)
|
||||||
|
|
||||||
|
def do_logout(self, token):
|
||||||
|
request.session.logout()
|
||||||
|
request.env['jwt_provider.access_token'].sudo().search([
|
||||||
|
('token', '=', token)
|
||||||
|
]).unlink()
|
||||||
|
|
||||||
|
def cleanup(self):
|
||||||
|
# Clean up things after success request
|
||||||
|
# use logout here to make request as stateless as possible
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
request.session.logout()
|
||||||
|
|
||||||
|
|
||||||
|
http_helper = HttpHelper()
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
from . import hr_employee
|
||||||
|
from . import attendence_zone_config
|
||||||
|
from . import mail_thread
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -0,0 +1,17 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from odoo import models, fields, api, _
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
|
||||||
|
class ResConfigSettings(models.TransientModel):
|
||||||
|
_inherit = 'res.config.settings'
|
||||||
|
web_fcm_server_key = fields.Char(string='Server Key:', related="company_id.web_fcm_server_key", readonly=False)
|
||||||
|
web_sender_id = fields.Char(string='Sender ID:', related="company_id.web_sender_id", readonly=False)
|
||||||
|
|
||||||
|
|
||||||
|
class ResCompany(models.Model):
|
||||||
|
_inherit = 'res.company'
|
||||||
|
|
||||||
|
web_fcm_server_key = fields.Char(string='Server Key')
|
||||||
|
web_sender_id = fields.Char(string='Sender ID')
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from datetime import datetime, timedelta
|
||||||
|
from odoo import models,fields,api,_
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
import random
|
||||||
|
import json
|
||||||
|
import json, requests
|
||||||
|
|
||||||
|
|
||||||
|
class HrEmployee(models.Model):
|
||||||
|
_inherit = 'hr.employee'
|
||||||
|
fcm_token_web = fields.Char(string='FCM Web Token')
|
||||||
|
def user_push_notification(self, notification):
|
||||||
|
url = "https://fcm.googleapis.com/fcm/send"
|
||||||
|
header = {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'Authorization': 'key=%s' % (self.env.user.company_id.web_fcm_server_key)
|
||||||
|
}
|
||||||
|
body = json.dumps({
|
||||||
|
"to": self.fcm_token_web,
|
||||||
|
"direct_boot_ok": True,
|
||||||
|
"notification": notification
|
||||||
|
})
|
||||||
|
try:
|
||||||
|
respons = requests.post(url=url, data=body, headers=header)
|
||||||
|
return True
|
||||||
|
except Exception as e:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
from odoo import fields, models, api
|
||||||
|
|
||||||
|
|
||||||
|
class MailThread(models.AbstractModel):
|
||||||
|
_inherit = 'mail.thread'
|
||||||
|
|
||||||
|
@api.returns('mail.message', lambda value: value.id)
|
||||||
|
def message_post(self, **kwargs):
|
||||||
|
print(self.read(),"==")
|
||||||
|
print(self.env.user.partner_id,"=====")
|
||||||
|
print("CALLED,++++++++++++++++++++++++++++++++",kwargs)
|
||||||
|
return super(MailThread, self).message_post(**kwargs)
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def message_notify(self, *,
|
||||||
|
partner_ids=False, parent_id=False, model=False, res_id=False,
|
||||||
|
author_id=None, email_from=None, body='', subject=False, **kwargs):
|
||||||
|
new_message = super(MailThread, self).message_notify(
|
||||||
|
partner_ids=partner_ids, parent_id=parent_id, model=model, res_id=res_id,
|
||||||
|
author_id=author_id, email_from=email_from, body=body, subject=subject, **kwargs
|
||||||
|
)
|
||||||
|
print(new_message,"=============================")
|
||||||
|
|
||||||
|
if partner_ids:
|
||||||
|
partners = self.env['res.partner'].browse(partner_ids)
|
||||||
|
for partner in partners:
|
||||||
|
print(partner.read(), "===============")
|
||||||
|
print(partner.employee.send_notification(subject, body), "===============")
|
||||||
|
# partner.send_notification(subject, body)
|
||||||
|
|
||||||
|
return new_message
|
||||||
|
|
@ -0,0 +1,293 @@
|
||||||
|
import logging
|
||||||
|
import jwt
|
||||||
|
import re
|
||||||
|
import datetime
|
||||||
|
import traceback
|
||||||
|
from odoo import http, service, registry, SUPERUSER_ID,_
|
||||||
|
from odoo.http import request
|
||||||
|
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||||
|
import phonenumbers
|
||||||
|
import math
|
||||||
|
from math import ceil
|
||||||
|
from odoo.service import security
|
||||||
|
|
||||||
|
import logging
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
SECRET_KEY = "skjdfe48ueq739rihesdio*($U*WIO$u8"
|
||||||
|
|
||||||
|
regex = r"^[a-z0-9!#$%&'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$"
|
||||||
|
|
||||||
|
|
||||||
|
class Validator:
|
||||||
|
def get_page_pagination(self,page):
|
||||||
|
limit = 20
|
||||||
|
page = int(page)
|
||||||
|
page = 1 if page<1 else page
|
||||||
|
offset = (page - 1) * limit
|
||||||
|
prev = False if page -1<=0 else page -1
|
||||||
|
return page,offset,limit,prev
|
||||||
|
|
||||||
|
def get_page_pagination_next(self,page,count):
|
||||||
|
page = int(page)
|
||||||
|
page = page+1
|
||||||
|
next = math.ceil(count / 20)
|
||||||
|
if next <page:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return page
|
||||||
|
|
||||||
|
def get_attendance_check(self,employee):
|
||||||
|
last = http.request.env['attendance.attendance'].sudo().search([('employee_id', '=', employee.id), ], order='name desc',
|
||||||
|
limit=1)
|
||||||
|
if last:
|
||||||
|
return last.action
|
||||||
|
else:
|
||||||
|
return 'sign_out'
|
||||||
|
|
||||||
|
|
||||||
|
def get_state_name(self,obj,state):
|
||||||
|
state_name = dict(obj.fields_get(["state"],['selection'])['state']["selection"]).get(obj.state)
|
||||||
|
return state_name
|
||||||
|
|
||||||
|
def is_valid_name(self, name):
|
||||||
|
return len (name) > 6
|
||||||
|
|
||||||
|
def is_valid_password(self, password):
|
||||||
|
return len (password) > 5
|
||||||
|
|
||||||
|
def is_valid_location(self, location):
|
||||||
|
try:
|
||||||
|
lat , lat = [float(x) for x in location.split(',') if x.replace('.','',1).isdigit()]
|
||||||
|
if lat and lat:
|
||||||
|
return True
|
||||||
|
except :
|
||||||
|
pass
|
||||||
|
return False
|
||||||
|
|
||||||
|
def is_valid_email(self, email):
|
||||||
|
return re.search(regex, email)
|
||||||
|
|
||||||
|
def is_valid_phone(self,phone):
|
||||||
|
try:
|
||||||
|
if not phone.startswith('+'):
|
||||||
|
phone = '+'+phone
|
||||||
|
number = phonenumbers.parse(phone, None)
|
||||||
|
isvalid = phonenumbers.is_valid_number(number)
|
||||||
|
return isvalid
|
||||||
|
except :
|
||||||
|
pass
|
||||||
|
return False
|
||||||
|
|
||||||
|
def get_server_error(self,e,user):
|
||||||
|
x= False
|
||||||
|
if len(e.args) == 2:
|
||||||
|
x, y = e.args
|
||||||
|
x = re.sub('\n', '', x)
|
||||||
|
else:
|
||||||
|
x = e.args
|
||||||
|
text = ""
|
||||||
|
if user.lang == 'en_US':
|
||||||
|
text =(_("contact admin or edit it Manually"))
|
||||||
|
else:
|
||||||
|
text = "الرجاء التواصل مع مدير النظام او استخدام الموقع الالكترونى"
|
||||||
|
message = "%s, %s" % (x,text)
|
||||||
|
return message
|
||||||
|
|
||||||
|
|
||||||
|
def create_token(self, user):
|
||||||
|
try:
|
||||||
|
exp = datetime.datetime.utcnow() + datetime.timedelta(days=7)
|
||||||
|
payload = {
|
||||||
|
'exp': exp,
|
||||||
|
'iat': datetime.datetime.utcnow(),
|
||||||
|
'sub': user['id'],
|
||||||
|
'lgn': user['login'],
|
||||||
|
}
|
||||||
|
token = jwt.encode(
|
||||||
|
payload,
|
||||||
|
SECRET_KEY,
|
||||||
|
algorithm='HS256'
|
||||||
|
)
|
||||||
|
# payload = jwt.decode(token, SECRET_KEY ,algorithms='HS256')
|
||||||
|
print(token)
|
||||||
|
self.save_token(token, user['id'], exp)
|
||||||
|
|
||||||
|
return token
|
||||||
|
except Exception as ex:
|
||||||
|
_logger.error(ex)
|
||||||
|
raise
|
||||||
|
|
||||||
|
def save_token(self, token, uid, exp):
|
||||||
|
request.env['jwt_provider.access_token'].sudo().create({
|
||||||
|
'user_id': uid,
|
||||||
|
'expires': exp.strftime(DEFAULT_SERVER_DATETIME_FORMAT),
|
||||||
|
'token': token,
|
||||||
|
})
|
||||||
|
|
||||||
|
def verify(self, token):
|
||||||
|
record = request.env['jwt_provider.access_token'].sudo().search([
|
||||||
|
('token', '=', token)
|
||||||
|
])
|
||||||
|
|
||||||
|
if len(record) != 1:
|
||||||
|
_logger.info('not found %s' % token)
|
||||||
|
return False
|
||||||
|
|
||||||
|
if record.is_expired:
|
||||||
|
return False
|
||||||
|
|
||||||
|
record.set_env(request.env)
|
||||||
|
return record.user_id
|
||||||
|
|
||||||
|
def verify_token(self, token):
|
||||||
|
try:
|
||||||
|
result = {
|
||||||
|
'status': False,
|
||||||
|
'message': None,
|
||||||
|
}
|
||||||
|
|
||||||
|
record = request.env['jwt_provider.access_token'].sudo().search([
|
||||||
|
('token', '=', token)
|
||||||
|
])
|
||||||
|
|
||||||
|
if len(record) != 1:
|
||||||
|
result['message'] = 'Token not found'
|
||||||
|
result['code'] = 497
|
||||||
|
return result
|
||||||
|
|
||||||
|
if record.is_expired:
|
||||||
|
result['message'] = 'Token has expired'
|
||||||
|
result['code'] = 498
|
||||||
|
return result
|
||||||
|
|
||||||
|
payload = jwt.decode(token, SECRET_KEY ,algorithms='HS256')
|
||||||
|
|
||||||
|
uid =self.verify(token)
|
||||||
|
user = uid
|
||||||
|
request.session.uid = user.id
|
||||||
|
request.session.login = user.login
|
||||||
|
request.session.session_token = user.id and security.compute_session_token(
|
||||||
|
request.session, request.env
|
||||||
|
)
|
||||||
|
request.uid = user.id
|
||||||
|
request.disable_db = False
|
||||||
|
request.session.get_context()
|
||||||
|
|
||||||
|
# Set user's context
|
||||||
|
user_context = request.env(request.cr, request.session.uid)['res.users'].context_get().copy()
|
||||||
|
request.session.context = request.context = user_context
|
||||||
|
request.env.user = uid
|
||||||
|
# uid = request.session.authenticate(request.session.db, uid=payload['sub'], password=token)
|
||||||
|
if not uid:
|
||||||
|
result['message'] = 'Token invalid or expired'
|
||||||
|
result['code'] = 498
|
||||||
|
return result
|
||||||
|
|
||||||
|
result['status'] = True
|
||||||
|
return result
|
||||||
|
except jwt.ExpiredSignatureError as ex :
|
||||||
|
result['code'] = 498
|
||||||
|
result['message'] = 'Signature has expired'
|
||||||
|
_logger.error(traceback.format_exc())
|
||||||
|
|
||||||
|
except (jwt.InvalidTokenError, Exception) as e:
|
||||||
|
result['code'] = 497
|
||||||
|
result['message'] = 'Token invalid or expired'
|
||||||
|
_logger.error(traceback.format_exc())
|
||||||
|
return result
|
||||||
|
|
||||||
|
def refresh_token(self, token):
|
||||||
|
try:
|
||||||
|
result = {
|
||||||
|
'status': False,
|
||||||
|
'message': None,
|
||||||
|
'code':200
|
||||||
|
}
|
||||||
|
record = request.env['jwt_provider.access_token'].sudo().search([
|
||||||
|
('token', '=', token)
|
||||||
|
])
|
||||||
|
|
||||||
|
if len(record) != 1 or not record:
|
||||||
|
result['message'] = 'Token not found'
|
||||||
|
result['code'] = 497
|
||||||
|
return result
|
||||||
|
|
||||||
|
payload = jwt.decode(token, SECRET_KEY ,algorithms='HS256')
|
||||||
|
user = request.env['res.users'].sudo().search([('id', '=',payload['sub'])], limit=1)
|
||||||
|
if not user:
|
||||||
|
result['message'] = 'Token for user not found'
|
||||||
|
result['code'] = 497
|
||||||
|
return result
|
||||||
|
|
||||||
|
request.env['jwt_provider.access_token'].sudo().search([
|
||||||
|
('token', '=', token)
|
||||||
|
]).unlink()
|
||||||
|
result['status'] = True
|
||||||
|
result['code'] == 200
|
||||||
|
result['data'] = {'token':self.create_token(user)}
|
||||||
|
return result
|
||||||
|
except jwt.ExpiredSignatureError as ex :
|
||||||
|
request.env['jwt_provider.access_token'].sudo().search([
|
||||||
|
('token', '=', token)
|
||||||
|
]).unlink()
|
||||||
|
result['status'] = True
|
||||||
|
result['code'] == 200
|
||||||
|
result['data'] = {'token':self.create_token(user)}
|
||||||
|
_logger.error(traceback.format_exc())
|
||||||
|
|
||||||
|
except (jwt.InvalidTokenError, Exception) as e:
|
||||||
|
result['code'] = 497
|
||||||
|
result['message'] = 'Token invalid'
|
||||||
|
_logger.error(traceback.format_exc())
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def validate_token(self, token):
|
||||||
|
try:
|
||||||
|
result = {
|
||||||
|
'status': False,
|
||||||
|
'message': None,
|
||||||
|
'code':200
|
||||||
|
}
|
||||||
|
record = request.env['jwt_provider.access_token'].sudo().search([
|
||||||
|
('token', '=', token)
|
||||||
|
])
|
||||||
|
|
||||||
|
if len(record) != 1 or not record:
|
||||||
|
result['message'] = 'Token not found'
|
||||||
|
result['code'] = 497
|
||||||
|
return result
|
||||||
|
|
||||||
|
payload = jwt.decode(token, SECRET_KEY ,algorithms='HS256')
|
||||||
|
user = request.env['res.users'].sudo().search([('id', '=',payload['sub'])], limit=1)
|
||||||
|
if not user:
|
||||||
|
result['message'] = 'Token for user not found'
|
||||||
|
result['code'] = 497
|
||||||
|
return result
|
||||||
|
|
||||||
|
uid =self.verify(token) #request.session.finalize()
|
||||||
|
# uid = request.session.authenticate(request.session.db, uid=payload['sub'], password=token)
|
||||||
|
if not uid:
|
||||||
|
result['message'] = 'Token invalid or expired'
|
||||||
|
result['code'] = 498
|
||||||
|
return result
|
||||||
|
result['data'] = {}
|
||||||
|
return result
|
||||||
|
except jwt.ExpiredSignatureError as ex :
|
||||||
|
request.env['jwt_provider.access_token'].sudo().search([
|
||||||
|
('token', '=', token)
|
||||||
|
]).unlink()
|
||||||
|
result['message'] = 'Token invalid or expired'
|
||||||
|
result['code'] = 498
|
||||||
|
_logger.error(traceback.format_exc())
|
||||||
|
return result
|
||||||
|
|
||||||
|
except (jwt.InvalidTokenError, Exception) as e:
|
||||||
|
result['code'] = 497
|
||||||
|
result['message'] = 'Token invalid'
|
||||||
|
_logger.error(traceback.format_exc())
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
validator = Validator()
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- config-->
|
||||||
|
<record id="res_config_settings_view_form" model="ir.ui.view">
|
||||||
|
<field name="name">mobile.res.config.settings.view.form</field>
|
||||||
|
<field name="model">res.config.settings</field>
|
||||||
|
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//div[hasclass('settings')]" position="inside">
|
||||||
|
<div class="app_settings_block" data-string="Web App Configuration" string="Web App" data-key="spl">
|
||||||
|
<h2>WebMobile Configuration</h2>
|
||||||
|
<div id="web_fcm_settings">
|
||||||
|
<div class="row mt16 o_settings_container">
|
||||||
|
<div class="col-xs-12 col-md-6 o_setting_box">
|
||||||
|
<div class="o_setting_right_pane">
|
||||||
|
<label for="web_fcm_server_key"/>
|
||||||
|
<field name="web_fcm_server_key"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-12 col-md-6 o_setting_box">
|
||||||
|
<div class="o_setting_right_pane">
|
||||||
|
<label for="web_sender_id"/>
|
||||||
|
<field name="web_sender_id"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<!--hr-->
|
||||||
|
|
||||||
|
<record id="employee_web_mobile_inherited_form" model="ir.ui.view">
|
||||||
|
<field name="name">employee.web.mobile.inherited.form</field>
|
||||||
|
<field name="model">hr.employee</field>
|
||||||
|
<field name="inherit_id" ref="hr.view_employee_form"/>
|
||||||
|
<field name="priority">200</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="user_id" position="after">
|
||||||
|
<field name="fcm_token_web"/>
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
Loading…
Reference in New Issue