-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'MPSK_devices' into develop
- Loading branch information
Showing
22 changed files
with
999 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
# Copyright (c) 2024. The Pycroft Authors. See the AUTHORS file. | ||
# This file is part of the Pycroft project and licensed under the terms of | ||
# the Apache License, Version 2.0. See the LICENSE file for details | ||
from sqlalchemy.orm import Session | ||
|
||
from pycroft.model.mpsk_client import MPSKClient | ||
from pycroft.model.user import User | ||
from pycroft.lib.logging import log_user_event | ||
from pycroft.helpers.i18n import deferred_gettext | ||
|
||
|
||
def mpsk_delete(session: Session, *, mpsk_client: MPSKClient, processor: User) -> None: | ||
message = deferred_gettext("Deleted mpsk client '{}'.").format(mpsk_client.name) | ||
log_user_event(author=processor, user=mpsk_client.owner, message=message.to_json()) | ||
|
||
session.delete(mpsk_client) | ||
|
||
|
||
def change_mac(session: Session, *, client: MPSKClient, mac: str, processor: User) -> MPSKClient: | ||
""" | ||
This method will change the mac address of the given mpsks client to the new | ||
mac address. | ||
:param session: session to use with the database. | ||
:param client: the mpsks which should become a new mac address. | ||
:param mac: the new mac address. | ||
:param processor: the user who initiated the mac address change. | ||
:return: the changed interface with the new mac address. | ||
""" | ||
old_mac = client.mac | ||
client.mac = mac | ||
message = deferred_gettext("Changed MAC address from {} to {}.").format(old_mac, mac) | ||
if client.owner: | ||
log_user_event(message.to_json(), processor, client.owner) | ||
session.add(client) | ||
return client | ||
|
||
|
||
def mpsk_client_create( | ||
session: Session, *, owner: User, name: str, mac: str, processor: User | ||
) -> MPSKClient: | ||
""" | ||
creates a mpsks client for a given user with a mac address. | ||
:param session: session to use with the database. | ||
:param owner: the user who initiated the mac address change. | ||
:param name: the name of the mpsks client. | ||
:param mac: the new mac address. | ||
:param processor: the user who initiated the mac address change. | ||
""" | ||
client = MPSKClient(name=name, owner_id=owner.id, mac=mac) | ||
|
||
session.add(client) | ||
|
||
message = deferred_gettext("Created MPSK Client '{name}' with MAC: {mac}.").format( | ||
name=client.name, | ||
mac=client.mac, | ||
) | ||
|
||
log_user_event(author=processor, user=owner, message=message.to_json()) | ||
|
||
return client | ||
|
||
|
||
def mpsk_edit( | ||
session: Session, *, client: MPSKClient, owner: User, name: str, mac: str, processor: User | ||
) -> None: | ||
if client.name != name: | ||
message = deferred_gettext("Changed name of client '{}' to '{}'.").format(client.name, name) | ||
client.name = name | ||
|
||
log_user_event(author=processor, user=owner, message=message.to_json()) | ||
|
||
if client.owner_id != owner.id: | ||
message = deferred_gettext("Transferred Host '{}' to {}.").format(client.name, owner.id) | ||
log_user_event(author=processor, user=client.owner, message=message.to_json()) | ||
|
||
message = deferred_gettext("Transferred Host '{}' from {}.").format( | ||
client.name, client.owner.id | ||
) | ||
log_user_event(author=processor, user=owner, message=message.to_json()) | ||
|
||
client.owner = owner | ||
|
||
if client.mac != mac: | ||
message = deferred_gettext("Changed MAC address of client '{}' to '{}'.").format( | ||
client.name, mac | ||
) | ||
log_user_event(author=processor, user=owner, message=message.to_json()) | ||
client.mac = mac | ||
session.add(client) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
pycroft/model/alembic/versions/dda39ad43536_add_mpskclient.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
"""Add MPSKClient | ||
Revision ID: dda39ad43536 | ||
Revises: 5234d7ac2b4a | ||
Create Date: 2024-09-28 10:01:39.952235 | ||
""" | ||
|
||
from alembic import op | ||
import sqlalchemy as sa | ||
from sqlalchemy.dialects import postgresql | ||
|
||
# revision identifiers, used by Alembic. | ||
revision = "dda39ad43536" | ||
down_revision = "5234d7ac2b4a" | ||
branch_labels = None | ||
depends_on = None | ||
|
||
|
||
def upgrade(): | ||
op.create_table( | ||
"mpsk_client", | ||
sa.Column("name", sa.String(), nullable=False), | ||
sa.Column("owner_id", sa.Integer(), nullable=False), | ||
sa.Column("mac", postgresql.types.MACADDR, nullable=False), | ||
sa.Column("id", sa.Integer(), nullable=False), | ||
sa.ForeignKeyConstraint(["owner_id"], ["user.id"], ondelete="CASCADE"), | ||
sa.PrimaryKeyConstraint("id"), | ||
sa.UniqueConstraint("mac"), | ||
) | ||
op.create_index(op.f("ix_mpsk_client_owner_id"), "mpsk_client", ["owner_id"], unique=False) | ||
|
||
|
||
def downgrade(): | ||
op.drop_index(op.f("ix_mpsk_client_owner_id"), table_name="mpsk_client") | ||
op.drop_table("mpsk_client") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
# Copyright (c) 2024. The Pycroft Authors. See the AUTHORS file. | ||
# This file is part of the Pycroft project and licensed under the terms of | ||
# the Apache License, Version 2.0. See the LICENSE file for details | ||
|
||
from __future__ import annotations | ||
|
||
from packaging.utils import InvalidName | ||
from sqlalchemy import ForeignKey | ||
from sqlalchemy.orm import relationship, validates, Mapped, mapped_column | ||
from sqlalchemy.types import String | ||
|
||
from pycroft.helpers.net import mac_regex | ||
from pycroft.model.base import IntegerIdModel | ||
from pycroft.model.host import MulticastFlagException | ||
from pycroft.model.type_aliases import mac_address | ||
from pycroft.model.types import InvalidMACAddressException | ||
from pycroft.model.user import User | ||
|
||
|
||
class MPSKClient(IntegerIdModel): | ||
|
||
name: Mapped[str] = mapped_column(String, nullable=False) | ||
|
||
owner_id: Mapped[int | None] = mapped_column( | ||
ForeignKey(User.id, ondelete="CASCADE"), index=True, nullable=False | ||
) | ||
owner: Mapped[User] = relationship(User, back_populates="mpsk_clients") | ||
mac: Mapped[mac_address] = mapped_column(unique=True) | ||
|
||
@validates("mac") | ||
def validate_mac(self, _, mac_address): | ||
match = mac_regex.match(mac_address) | ||
if not match: | ||
raise InvalidMACAddressException(f"MAC address {mac_address!r} is not valid") | ||
if int(mac_address[0:2], base=16) & 1: | ||
raise MulticastFlagException("Multicast bit set in MAC address") | ||
return mac_address | ||
|
||
@validates("name") | ||
def validate_name(self, _, name): | ||
if name.strip() == "": | ||
raise InvalidName("Name cannot be empty") | ||
|
||
return name |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Copyright (c) 2024. The Pycroft Authors. See the AUTHORS file. | ||
# This file is part of the Pycroft project and licensed under the terms of | ||
# the Apache License, Version 2.0. See the LICENSE file for details | ||
import factory | ||
from tests.factories.base import BaseFactory | ||
from pycroft.model.mpsk_client import MPSKClient | ||
|
||
from tests.factories.user import UserFactory | ||
from tests.factories.host import UnicastMacProvider | ||
|
||
factory.Faker.add_provider(UnicastMacProvider) | ||
|
||
|
||
class BareMPSKFactory(BaseFactory): | ||
"""A host without owner or interface.""" | ||
|
||
class Meta: | ||
model = MPSKClient | ||
|
||
mac = factory.Faker("unicast_mac_address") | ||
name = factory.Faker("name") | ||
|
||
|
||
class MPSKFactory(BareMPSKFactory): | ||
|
||
owner = factory.SubFactory(UserFactory) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import pytest | ||
|
||
from tests.frontend.assertions import TestClient | ||
|
||
|
||
@pytest.fixture(scope="module", autouse=True) | ||
def client(module_test_client: TestClient) -> TestClient: | ||
return module_test_client | ||
|
||
|
||
@pytest.fixture(scope="module", autouse=True) | ||
def api_key(app) -> str: | ||
api_key = "secrettestapikey" | ||
app.config["PYCROFT_API_KEY"] = api_key | ||
return api_key | ||
|
||
|
||
@pytest.fixture(scope="module", autouse=True) | ||
def max_clients(app) -> int: | ||
max_clients = 5 | ||
app.config["MAX_MPSKS"] = max_clients | ||
return max_clients | ||
|
||
|
||
# TODO put this into the client | ||
@pytest.fixture(scope="module") | ||
def auth_header(api_key) -> dict[str, str]: | ||
# see `api.v0.parse_authorization_header` | ||
return {"AUTHORIZATION": f"apikey {api_key}"} |
Oops, something went wrong.