Files
encoach_be_odoo19/encoach_api/controllers/registration.py
Talal Sharabi f5b627256f EnCoach Odoo 19 custom modules
Full backend implementation with custom Odoo modules:
- encoach_api: Core API, user management, JWT auth
- encoach_exam: Exam generation (reading, writing, listening, speaking)
- encoach_evaluate: AI-powered evaluation (writing, speaking)
- encoach_training: Training tips and walkthrough
- encoach_storage: File storage management
- encoach_payment: Stripe, PayPal, Paymob integration
- encoach_mail: Email notifications

Made-with: Cursor
2026-03-14 16:46:46 +04:00

150 lines
5.9 KiB
Python

import logging
from datetime import datetime, timedelta
import jwt as pyjwt
from odoo import http
from odoo.http import request
from .base import EncoachMixin
_logger = logging.getLogger(__name__)
class RegistrationController(EncoachMixin, http.Controller):
@http.route('/api/register', type='http', auth='public', methods=['POST', 'OPTIONS'], csrf=False, cors='*')
def register(self, **kwargs):
try:
body = self._get_json_body()
email = body.get('email', '').strip()
password = body.get('password', '')
name = body.get('name', '').strip()
user_type = body.get('type', 'student')
if not email or not password or not name:
return self._error_response('name, email, and password are required', 400)
Users = request.env['res.users'].sudo()
existing = Users.search([('login', '=', email)], limit=1)
if existing:
return self._error_response('A user with this email already exists', 409)
main_company = request.env['res.company'].sudo().search([], limit=1, order='id')
vals = {
'name': name,
'login': email,
'password': password,
'encoach_type': user_type,
'is_verified': False,
'company_id': main_company.id,
'company_ids': [(6, 0, [main_company.id])],
}
code_str = body.get('code')
if code_str:
result = request.env['encoach.code'].sudo().validate_code(code_str)
if result.get('valid'):
code_rec = request.env['encoach.code'].sudo().search([('code', '=', code_str)], limit=1)
if code_rec and code_rec.user_type:
vals['encoach_type'] = code_rec.user_type
user = Users.create(vals)
if code_str:
code_rec = request.env['encoach.code'].sudo().search([('code', '=', code_str)], limit=1)
if code_rec:
if code_rec.entity_id:
request.env['encoach.user.entity.rel'].sudo().create({
'user_id': user.id,
'entity_id': code_rec.entity_id.id,
})
code_rec.sudo().write({'uses': code_rec.uses + 1})
secret = request.env['ir.config_parameter'].sudo().get_param('encoach.jwt_secret')
token = pyjwt.encode({
'user_id': user.id,
'email': user.login,
'iat': datetime.utcnow(),
'exp': datetime.utcnow() + timedelta(hours=72),
}, secret, algorithm='HS256')
return self._json_response({
'user': self._serialize(user),
'token': token,
}, status=201)
except Exception:
_logger.exception("Registration error")
return self._error_response('Internal server error', 500)
@http.route(
'/api/code/<string:code>', type='http', auth='public',
methods=['GET', 'OPTIONS'], csrf=False, cors='*',
)
def validate_code(self, code, **kwargs):
try:
result = request.env['encoach.code'].sudo().validate_code(code)
if not result.get('valid'):
return self._error_response(result.get('error', 'Invalid code'), 404)
return self._json_response(result['code'])
except Exception:
_logger.exception("Validate code error")
return self._error_response('Internal server error', 500)
@http.route('/api/batch_users', type='http', auth='public', methods=['POST', 'OPTIONS'], csrf=False, cors='*')
def batch_users(self, **kwargs):
try:
user = self._authenticate()
if not user:
return self._error_response('Unauthorized', 401)
body = self._get_json_body()
users_data = body.get('users', [])
if not users_data:
return self._error_response('users array is required', 400)
mixin = request.env['encoach.registration.mixin'].sudo()
result = mixin.batch_import(users_data, user.id)
return self._json_response(result)
except Exception:
_logger.exception("Batch users error")
return self._error_response('Internal server error', 500)
@http.route('/api/make_user', type='http', auth='public', methods=['POST', 'OPTIONS'], csrf=False, cors='*')
def make_user(self, **kwargs):
try:
user = self._authenticate()
if not user:
return self._error_response('Unauthorized', 401)
body = self._get_json_body()
email = body.get('email', '').strip()
name = body.get('name', '').strip()
password = body.get('password', '')
if not email or not name:
return self._error_response('name and email are required', 400)
Users = request.env['res.users'].sudo()
existing = Users.search([('login', '=', email)], limit=1)
if existing:
return self._error_response('A user with this email already exists', 409)
import secrets
if not password:
password = secrets.token_urlsafe(12)
new_user = Users.create({
'name': name,
'login': email,
'password': password,
'encoach_type': body.get('type', 'student'),
'is_verified': body.get('isVerified', True),
})
result = self._serialize(new_user)
result['tempPassword'] = password
return self._json_response(result, status=201)
except Exception:
_logger.exception("Make user error")
return self._error_response('Internal server error', 500)