Skip to content

Commit fbc9b8d

Browse files
committed
[ADD] fastapi_captcha_altcha_backend
1 parent c6de540 commit fbc9b8d

File tree

15 files changed

+685
-0
lines changed

15 files changed

+685
-0
lines changed
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
==============================
2+
Fastapi Captcha Altcha Backend
3+
==============================
4+
5+
..
6+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
7+
!! This file is generated by oca-gen-addon-readme !!
8+
!! changes will be overwritten. !!
9+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10+
!! source digest: sha256:e97f2c1f5989e99007440eecfb45f75fb664da90312dfd68b8a61d8a321305c1
11+
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
12+
13+
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
14+
:target: https://odoo-community.org/page/development-status
15+
:alt: Beta
16+
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
17+
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
18+
:alt: License: AGPL-3
19+
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Frest--framework-lightgray.png?logo=github
20+
:target: https://github.com/OCA/rest-framework/tree/16.0/fastapi_captcha_altcha_backend
21+
:alt: OCA/rest-framework
22+
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
23+
:target: https://translation.odoo-community.org/projects/rest-framework-16-0/rest-framework-16-0-fastapi_captcha_altcha_backend
24+
:alt: Translate me on Weblate
25+
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
26+
:target: https://runboat.odoo-community.org/builds?repo=OCA/rest-framework&target_branch=16.0
27+
:alt: Try me on Runboat
28+
29+
|badge1| |badge2| |badge3| |badge4| |badge5|
30+
31+
This module adds Altcha service as a FastApi router and add local Altcha
32+
verification as a captcha method.
33+
34+
**Table of contents**
35+
36+
.. contents::
37+
:local:
38+
39+
Usage
40+
=====
41+
42+
Add the altcha router in your FastAPI application to enable the Altcha
43+
captcha verification. Get the challenge from the /altcha/challenge
44+
endpoint. Choose the altcha_local captcha type in your FastAPI endpoint
45+
configuration.
46+
47+
Bug Tracker
48+
===========
49+
50+
Bugs are tracked on `GitHub Issues <https://github.com/OCA/rest-framework/issues>`_.
51+
In case of trouble, please check there if your issue has already been reported.
52+
If you spotted it first, help us to smash it by providing a detailed and welcomed
53+
`feedback <https://github.com/OCA/rest-framework/issues/new?body=module:%20fastapi_captcha_altcha_backend%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
54+
55+
Do not contact contributors directly about support or help with technical issues.
56+
57+
Credits
58+
=======
59+
60+
Authors
61+
-------
62+
63+
* Akretion
64+
65+
Contributors
66+
------------
67+
68+
- Florian Mounier florian.mounier@akretion.com
69+
70+
Maintainers
71+
-----------
72+
73+
This module is maintained by the OCA.
74+
75+
.. image:: https://odoo-community.org/logo.png
76+
:alt: Odoo Community Association
77+
:target: https://odoo-community.org
78+
79+
OCA, or the Odoo Community Association, is a nonprofit organization whose
80+
mission is to support the collaborative development of Odoo features and
81+
promote its widespread use.
82+
83+
.. |maintainer-paradoxxxzero| image:: https://github.com/paradoxxxzero.png?size=40px
84+
:target: https://github.com/paradoxxxzero
85+
:alt: paradoxxxzero
86+
87+
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
88+
89+
|maintainer-paradoxxxzero|
90+
91+
This module is part of the `OCA/rest-framework <https://github.com/OCA/rest-framework/tree/16.0/fastapi_captcha_altcha_backend>`_ project on GitHub.
92+
93+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from . import models
2+
from . import routers
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Copyright 2025 Akretion (http://www.akretion.com).
2+
# @author Florian Mounier <florian.mounier@akretion.com>
3+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
4+
5+
{
6+
"name": "Fastapi Captcha Altcha Backend",
7+
"version": "16.0.1.0.0",
8+
"author": "Akretion, Odoo Community Association (OCA)",
9+
"summary": "Implement Altcha server in FastAPI",
10+
"category": "Tools",
11+
"depends": ["fastapi_captcha"],
12+
"website": "https://github.com/OCA/rest-framework",
13+
"data": [],
14+
"maintainers": ["paradoxxxzero"],
15+
"demo": [],
16+
"installable": True,
17+
"license": "AGPL-3",
18+
"external_dependencies": {
19+
"python": [
20+
"altcha",
21+
]
22+
},
23+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import fastapi_endpoint
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Copyright 2025 Akretion (http://www.akretion.com).
2+
# @author Florian Mounier <florian.mounier@akretion.com>
3+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
4+
5+
from odoo import _, fields, models
6+
from odoo.exceptions import AccessError, UserError, ValidationError
7+
8+
try:
9+
import altcha
10+
from altcha import verify_solution
11+
except ImportError:
12+
altcha = None
13+
14+
15+
class FastapiEndpoint(models.Model):
16+
_inherit = "fastapi.endpoint"
17+
18+
captcha_type = fields.Selection(
19+
selection_add=[
20+
("altcha_local", "Altcha (Local)"),
21+
],
22+
)
23+
24+
def validate_captcha(self, captcha_response):
25+
"""Validate the captcha response."""
26+
super().validate_captcha(captcha_response)
27+
secret_key = self.captcha_secret_key
28+
if self.captcha_type == "altcha_local":
29+
if not altcha:
30+
raise UserError(_("Altcha library is not installed."))
31+
return self._validate_altcha_local(captcha_response, secret_key)
32+
33+
def _validate_altcha_local(self, captcha_response, secret_key):
34+
"""Validate the altcha"""
35+
36+
try:
37+
# Verify the solution
38+
verified, err = verify_solution(captcha_response, secret_key, True)
39+
if not verified:
40+
raise AccessError(
41+
_("Altcha validation failed: %(error)s") % {"error": err}
42+
)
43+
44+
return
45+
except Exception as e:
46+
raise ValidationError(
47+
_("Failed to process Altcha payload: %(error)s") % {"error": str(e)}
48+
) from e
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Florian Mounier <florian.mounier@akretion.com>
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
This module adds Altcha service as a FastApi router and add local Altcha verification as
2+
a captcha method.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Add the altcha router in your FastAPI application to enable the Altcha captcha
2+
verification. Get the challenge from the /altcha/challenge endpoint. Choose the
3+
altcha_local captcha type in your FastAPI endpoint configuration.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from .altcha import altcha_router
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
# Copyright 2025 Akretion (http://www.akretion.com).
2+
# @author Florian Mounier <florian.mounier@akretion.com>
3+
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
4+
import datetime
5+
from typing import Annotated
6+
7+
from odoo import _
8+
from odoo.exceptions import AccessDenied, ValidationError
9+
10+
from odoo.addons.fastapi.dependencies import fastapi_endpoint
11+
from odoo.addons.fastapi.models import FastapiEndpoint
12+
13+
from fastapi import APIRouter, Depends
14+
15+
try:
16+
import altcha
17+
from altcha import ChallengeOptions, create_challenge
18+
except ImportError:
19+
altcha = None
20+
21+
from ..schemas import AltchaChallenge
22+
23+
altcha_router = APIRouter(tags=["altcha"])
24+
25+
26+
@altcha_router.get("/altcha/challenge")
27+
def altcha_challenge(
28+
endpoint: Annotated[FastapiEndpoint, Depends(fastapi_endpoint)],
29+
) -> AltchaChallenge:
30+
if not altcha:
31+
raise ValidationError(_("Altcha library is not installed."))
32+
secret_key = endpoint.sudo().captcha_secret_key
33+
if not secret_key:
34+
raise ValidationError(_("Captcha secret key is not set for this endpoint."))
35+
36+
try:
37+
challenge = create_challenge(
38+
ChallengeOptions(
39+
expires=datetime.datetime.now() + datetime.timedelta(minutes=5),
40+
hmac_key=secret_key,
41+
max_number=50000,
42+
)
43+
)
44+
return AltchaChallenge.from_challenge(challenge)
45+
except Exception as e:
46+
raise AccessDenied(_("Failed to create Altcha challenge.")) from e

0 commit comments

Comments
 (0)