Source code for timApp.user.personaluniquecode

from typing import Optional

import re
from dataclasses import dataclass

from timApp.timdb.sqa import db
from timApp.user.hakaorganization import HakaOrganization


[docs]class PersonalUniqueCode(db.Model): """The database model for the 'schacPersonalUniqueCode' Haka attribute.""" user_id = db.Column( db.Integer, db.ForeignKey("useraccount.id"), nullable=False, primary_key=True ) """User id.""" org_id = db.Column( db.Integer, db.ForeignKey("haka_organization.id"), nullable=False, primary_key=True, ) """Organization id.""" code = db.Column(db.Text, nullable=False, index=True) """The actual code. This could be e.g. student id or employee id.""" type = db.Column(db.Text, nullable=False, primary_key=True) """The type of the code, e.g. student or employee.""" user = db.relationship("User", back_populates="uniquecodes", lazy="joined") organization = db.relationship( "HakaOrganization", back_populates="uniquecodes", lazy="joined" ) __table_args__ = (db.UniqueConstraint("org_id", "code", "type"),) @property def user_collection_key(self): return self.org_id, self.type
[docs] @staticmethod def find_by_student_id(sid: str, org: str) -> Optional["PersonalUniqueCode"]: return PersonalUniqueCode.find_by_code(sid, org, "studentID")
[docs] @staticmethod def find_by_code( code: str, org: str, codetype: str ) -> Optional["PersonalUniqueCode"]: return ( PersonalUniqueCode.query.filter_by(code=code, type=codetype) .join(HakaOrganization) .filter_by(name=org) .first() )
[docs] @staticmethod def find_by_urn(urn: str) -> Optional["PersonalUniqueCode"]: p = SchacPersonalUniqueCode.parse(urn) if not p: return None return PersonalUniqueCode.find_by_code(p.code, p.org, p.codetype)
uc_start = "urn:schac:personalUniqueCode:int" # The mace:terena.org part is used by at least Aalto. uc_re = re.compile( rf"urn:(mace:terena\.org:)?schac:personalUniqueCode:int:(?P<type>[^:]+):(?P<org>[^:]+):(?P<code>[^:]+)" )
[docs]@dataclass class SchacPersonalUniqueCode: """Represents the 'schacPersonalUniqueCode' Haka attribute.""" code: str codetype: str org: str
[docs] @staticmethod def parse(urn: str): match = uc_re.fullmatch(urn) if not match: return None codetype = match.group("type") org_name = match.group("org") code = match.group("code") return SchacPersonalUniqueCode(code=code, codetype=codetype, org=org_name)
[docs] def to_urn(self): return f"{uc_start}:{self.codetype}:{self.org}:{self.code}"