from .. import controller from odoo import http from odoo.http import request from odoo.tools.config import config import random, string from difflib import SequenceMatcher class User(controller.Controller): prefix = '/api/v1/' def get_user_by_email(self, email): return request.env['res.users'].search([ ('login', '=', email), ('active', 'in', [True, False]) ]) def response_with_token(self, user): data = request.env['res.users'].sudo().api_single_response(user) data['token'] = self.create_user_token(user) return data @http.route(prefix + 'user/login', auth='public', methods=['POST'], csrf=False) @controller.Controller.must_authorized() def login(self, **kw): email = kw.get('email') password = kw.get('password') if not email or not password: return self.response(code=400, description='email and password is required') user = self.get_user_by_email(email) if user and not user.active: return self.response({ 'is_auth': False, 'reason': 'NOT_ACTIVE' }) try: uid = request.session.authenticate(config.get('db_name'), email, password) user = request.env['res.users'].browse(uid) data = { 'is_auth': True, 'user': self.response_with_token(user) } return self.response(data) except: return self.response({ 'is_auth': False, 'reason': 'NOT_FOUND' }) @http.route(prefix + 'user/register', auth='public', methods=['POST'], csrf=False) @controller.Controller.must_authorized() def register(self, **kw): name = kw.get('name') email = kw.get('email') password = kw.get('password') if not name or not email or not password: return self.response(code=400, description='email, name and password is required') user = self.get_user_by_email(email) if user: return self.response({ 'register': False, 'reason': 'EMAIL_USED' }) user_data = { 'name': name, 'login': email, 'password': password, 'active': False, 'sel_groups_1_9_10': 9 } user = request.env['res.users'].create(user_data) user.partner_id.email = email company = kw.get('company', False) if company: parameter = [ ('company_type', '=', 'company'), ('name', 'ilike', company) ] match_company = request.env['res.partner'].search(parameter, limit=1) match_ratio = 0 if match_company: match_ratio = SequenceMatcher(None, match_company.name, company).ratio() if match_ratio > 0.8: request.env['user.company.request'].create({ 'user_id': user.partner_id.id, 'user_company_id': match_company.id, 'user_input': company }) else: new_company = request.env['res.partner'].create({ 'name': company }) user.parent_id = new_company.id return self.response({'register': True}) @http.route(prefix + 'user/activation-request', auth='public', methods=['POST'], csrf=False) @controller.Controller.must_authorized() def request_activation_user(self, **kw): email = kw.get('email') user = self.get_user_by_email(email) if not user: return self.response({'activation_request': False, 'reason': 'NOT_FOUND'}) if user.active: return self.response({'activation_request': False, 'reason': 'ACTIVE'}) token_source = string.ascii_letters + string.digits user.activation_token = ''.join(random.choice(token_source) for i in range(21)) return self.response({ 'activation_request': True, 'token': user.activation_token, 'user': request.env['res.users'].api_single_response(user) }) @http.route(prefix + 'user/activation', auth='public', methods=['POST'], csrf=False) @controller.Controller.must_authorized() def activation_user(self, **kw): token = kw.get('token') if not token: return self.response(code=400, description='token is required') user = request.env['res.users'].search([('activation_token', '=', token), ('active', '=', False)], limit=1) if not user: return self.response({'activation': False, 'reason': 'INVALID_TOKEN'}) user.active = True user.activation_token = '' return self.response({ 'activation': True, 'user': self.response_with_token(user) }) @http.route(prefix + 'user/forgot-password', auth='public', methods=['POST'], csrf=False) @controller.Controller.must_authorized() def forgot_password_user(self, **kw): email = kw.get('email') user = self.get_user_by_email(email) if not user: return self.response({'success': False, 'reason': 'NOT_FOUND'}) token_source = string.ascii_letters + string.digits user.reset_password_token = ''.join(random.choice(token_source) for i in range(21)) return self.response({ 'success': True, 'token': user.reset_password_token, 'user': request.env['res.users'].api_single_response(user) }) @http.route(prefix + 'user/reset-password', auth='public', methods=['POST', 'OPTIONS'], csrf=False) @controller.Controller.must_authorized() def reset_password_user(self, **kw): token = kw.get('token') if not token: return self.response(code=400, description='token is required') user = request.env['res.users'].search([('reset_password_token', '=', token), ('active', 'in', [False, True])], limit=1) if not user: return self.response({'success': False, 'reason': 'INVALID_TOKEN'}) password = kw.get('password', '') user.password = password user.reset_password_token = '' return self.response({ 'success': True, 'user': request.env['res.users'].api_single_response(user) }) @http.route(prefix + 'user/', auth='public', methods=['PUT', 'OPTIONS'], csrf=False) @controller.Controller.must_authorized() def update_user(self, **kw): id = kw.get('id') user = request.env['res.users'].search([('id', '=', id)], limit=1) if not user: return self.response(code=404, description='User not found') allowed_field = ['name', 'phone', 'mobile', 'password'] for field in allowed_field: field_value = kw.get(field) if field_value or field_value == '': user[field] = field_value return self.response({ 'user': self.response_with_token(user) }) @http.route(prefix + 'user//address', auth='public', methods=['GET', 'OPTIONS']) @controller.Controller.must_authorized() def get_user_address_by_id(self, **kw): id = kw.get('id') user = request.env['res.users'].search([('id', '=', id)], limit=1) if not user: return self.response(code=404, description='User not found') partner_ids = [user.partner_id.id] + [x.id for x in user.child_ids] partners = request.env['res.partner'].search([('id', 'in', partner_ids)], order='write_date DESC') address = [request.env['res.users'].api_address_response(x) for x in partners] return self.response(address)