Skip to content

Commit

Permalink
Merge branch '17.0' of https://github.com/OpenSPP/openspp-modules int…
Browse files Browse the repository at this point in the history
…o spp_attendance
  • Loading branch information
reichie020212 committed Dec 6, 2024
2 parents e837792 + ca5926e commit 5371960
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 47 deletions.
2 changes: 2 additions & 0 deletions spp_entitlement_cash/security/ir.model.access.csv
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ g2p_prog_entitle_manager_cash_item_program_validator,Program Entitlement Manager

g2p_program_create_wizard_entitlement_cash_item_admin,Create Program Wizard Entitlement Cash Items Admin Access,spp_entitlement_cash.model_g2p_program_create_wizard_entitlement_cash_item,g2p_registry_base.group_g2p_admin,1,1,1,1
g2p_program_create_wizard_entitlement_cash_item_program_manager,Create Program Wizard Program Entitlement Cash Items Manager Access,spp_entitlement_cash.model_g2p_program_create_wizard_entitlement_cash_item,g2p_programs.g2p_program_manager,1,1,1,1

g2p_ir_model_program_manager,Model Program Manager Access,base.model_ir_model,g2p_programs.g2p_program_manager,1,0,0,0
7 changes: 0 additions & 7 deletions spp_openid_vci/i18n/spp_openid_vci.pot
Original file line number Diff line number Diff line change
Expand Up @@ -144,13 +144,6 @@ msgstr ""
msgid "Registrant"
msgstr ""

#. module: spp_openid_vci
#. odoo-python
#: code:addons/spp_openid_vci/models/res_partner.py:0
#, python-format
msgid "The request to the credential issuer timed out."
msgstr ""

#. module: spp_openid_vci
#: model:ir.model.fields,field_description:spp_openid_vci.field_g2p_program_membership__vc_qr_code
#: model:ir.model.fields,field_description:spp_openid_vci.field_res_partner__vc_qr_code
Expand Down
42 changes: 7 additions & 35 deletions spp_openid_vci/models/res_partner.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import base64
import calendar
import json
import logging
from datetime import datetime
from io import BytesIO

import qrcode
import requests
from qrcode.image.pil import PilImage

from odoo import _, fields, models
from odoo.exceptions import UserError

from ..tools import create_qr_code

_logger = logging.getLogger(__name__)


class SPPRegistry(models.Model):
_inherit = "res.partner"
Expand Down Expand Up @@ -38,14 +37,7 @@ def _issue_vc(self, vci_issuer):
if not reg_id:
raise UserError(f"No Registrant found with this ID Type: {vci_issuer.auth_sub_id_type_id.name}.")

web_base_url = self.env["ir.config_parameter"].sudo().get_param("web.base.url").rstrip("/")

url = f"{web_base_url}/api/v1/vci/.well-known/openid-credential-issuer/{vci_issuer.name}"
try:
credential_issuer_response = requests.get(url, timeout=5)
except requests.exceptions.Timeout as e:
raise UserError(_("The request to the credential issuer timed out.")) from e
issuer_data = credential_issuer_response.json()
issuer_data = self.env["g2p.openid.vci.issuers"].get_issuer_metadata_by_name(issuer_name=vci_issuer.name)

credential_issuer = f"{issuer_data['credential_issuer']}/api/v1/security"
credentials_supported = issuer_data.get("credentials_supported", None)
Expand All @@ -67,26 +59,6 @@ def _issue_vc(self, vci_issuer):

return self.env["g2p.openid.vci.issuers"].issue_vc(credential_request, signed_data)

def _create_qr_code(self, data):
qr = qrcode.QRCode(
error_correction=qrcode.constants.ERROR_CORRECT_L,
image_factory=PilImage,
box_size=10,
border=4,
)

qr.add_data(data)
qr.make(fit=True)

img = qr.make_image()

temp = BytesIO()
img.save(temp, format="PNG")
qr_img = base64.b64encode(temp.getvalue())
temp.close()

return qr_img

def registry_issue_card(self):
self.ensure_one()

Expand All @@ -112,7 +84,7 @@ def _issue_vc_qr(self, vci_issuer):

result = self._issue_vc(vci_issuer)

qr_img = self._create_qr_code(json.dumps(result))
qr_img = create_qr_code(json.dumps(result))

self.vc_qr_code = qr_img

Expand Down
1 change: 1 addition & 0 deletions spp_openid_vci/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
from . import test_vci_issuer
from . import test_tools
38 changes: 38 additions & 0 deletions spp_openid_vci/tests/test_tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
from qrcode.image.pil import PilImage

from odoo.tests.common import TransactionCase

from ..tools import create_qr_code, delete_keys_except, qr_image


class VCITools(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()

def test_delete_keys_except(self):
sample_data = {
"name": "John Doe",
"age": 30,
}
delete_keys_except(sample_data, "name")

self.assertEqual(sample_data, {"name": "John Doe"})

sample_data = {
"name": "John Doe",
"age": 30,
}
delete_keys_except(sample_data, ["age"])

self.assertEqual(sample_data, {"age": 30})

def test_qr_image(self):
img = qr_image("Hello, World!")
self.assertTrue(img)
self.assertIsInstance(img, PilImage)

def test_create_qr_code(self):
img = create_qr_code("Hello, World!")
self.assertTrue(img)
self.assertIsInstance(img, bytes)
5 changes: 0 additions & 5 deletions spp_openid_vci/tests/test_vci_issuer.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,6 @@ def test_issue_vc(self, mock_get):
self.res_partner_complete._issue_vc(self.vci_issuer_complete)
issue_vc.assert_called_once()

def test_create_qr_code(self):
qr_img = self.res_partner_complete._create_qr_code("Test Data")
self.assertIsNotNone(qr_img)
self.assertIsInstance(qr_img, bytes)

def test_registry_issue_card(self):
registry_issue_card_action = self.res_partner_complete.registry_issue_card()

Expand Down
3 changes: 3 additions & 0 deletions spp_openid_vci/tools/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from .tools import delete_keys_except
from .tools import qr_image
from .tools import create_qr_code
65 changes: 65 additions & 0 deletions spp_openid_vci/tools/tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import base64
import json
import logging
from io import BytesIO

import qrcode
from qrcode.exceptions import DataOverflowError
from qrcode.image.pil import PilImage

_logger = logging.getLogger(__name__)


def delete_keys_except(d, keys_to_keep):
"""
Deletes all keys from the dictionary except for the specified keys.
Parameters:
- d: The dictionary from which keys are to be deleted.
- keys_to_keep: A key or a list of keys that should not be deleted.
Returns:
None; the operation modifies the dictionary in place.
"""
# Ensure keys_to_keep is a list
if not isinstance(keys_to_keep, list):
keys_to_keep = [keys_to_keep]

keys_to_delete = [key for key in d.keys() if key not in keys_to_keep]
for key in keys_to_delete:
del d[key]

return d


def qr_image(data):
_logger.info(f"Data: {data}")
qr = qrcode.QRCode(
error_correction=qrcode.constants.ERROR_CORRECT_L,
image_factory=PilImage,
box_size=10,
border=4,
)
qr.add_data(data)
qr.make(fit=True)

return qr.make_image()


def create_qr_code(data):
try:
img = qr_image(data)
except DataOverflowError as e:
_logger.warning(f"Data Overflow Error: {e}")
_logger.info("Deleting keys in 'proof' except jws")

data_dict = json.loads(data)
data_dict["credential"]["proof"] = delete_keys_except(data_dict["credential"]["proof"], keys_to_keep="jws")
img = qr_image(json.dumps(data_dict))

temp = BytesIO()
img.save(temp, format="PNG")
qr_img = base64.b64encode(temp.getvalue())
temp.close()

return qr_img

0 comments on commit 5371960

Please sign in to comment.