diff --git a/pycroft/model/alembic/versions/55e9f0d9b5f4_add_custom_non_blocking_radius_groups.py b/pycroft/model/alembic/versions/55e9f0d9b5f4_add_custom_non_blocking_radius_groups.py index 64404102b..21890bcbb 100644 --- a/pycroft/model/alembic/versions/55e9f0d9b5f4_add_custom_non_blocking_radius_groups.py +++ b/pycroft/model/alembic/versions/55e9f0d9b5f4_add_custom_non_blocking_radius_groups.py @@ -51,7 +51,7 @@ def upgrade(): op.execute( """ CREATE OR REPLACE VIEW radusergroup AS - SELECT interface.mac AS "UserName", + SELECT interface.mac::text AS "UserName", host(switch.management_ip) AS "NASIPAddress", switch_port.name AS "NASPortId", vlan.name::text || '_untagged'::text AS "GroupName", @@ -69,7 +69,7 @@ def upgrade(): JOIN current_property ON "user".id = current_property.user_id AND NOT current_property.denied WHERE current_property.property_name::text = 'network_access'::text UNION ALL - SELECT interface.mac AS "UserName", + SELECT interface.mac::text AS "UserName", host(switch.management_ip) AS "NASIPAddress", switch_port.name AS "NASPortId", radius_property.hades_group_name AS "GroupName", @@ -87,7 +87,7 @@ def upgrade(): JOIN current_property ON "user".id = current_property.user_id AND NOT current_property.denied JOIN radius_property ON radius_property.property::text = current_property.property_name::text UNION ALL - SELECT interface.mac AS "UserName", + SELECT interface.mac::text AS "UserName", host(switch.management_ip) AS "NASIPAddress", switch_port.name AS "NASPortId", 'no_network_access'::text AS "GroupName", @@ -104,7 +104,13 @@ def upgrade(): JOIN patch_port ON patch_port.room_id = room.id AND patch_port.switch_port_id IS NOT NULL JOIN switch_port ON switch_port.id = patch_port.switch_port_id JOIN switch ON switch.host_id = switch_port.switch_id - WHERE users_with_network_access.network_access IS NULL; + WHERE users_with_network_access.network_access IS NULL + UNION ALL + SELECT 'unknown'::text AS "UserName", + NULL::text AS "NASIPAddress", + NULL::character varying AS "NASPortId", + 'unknown'::text AS "GroupName", + 1 AS "Priority"; """ ) op.execute( @@ -227,7 +233,7 @@ def downgrade(): op.execute( """ CREATE OR REPLACE VIEW radusergroup AS - SELECT interface.mac AS "UserName", + SELECT interface.mac::text AS "UserName", host(switch.management_ip) AS "NASIPAddress", switch_port.name AS "NASPortId", vlan.name::text || '_untagged'::text AS "GroupName", @@ -245,7 +251,7 @@ def downgrade(): JOIN current_property ON "user".id = current_property.user_id AND NOT current_property.denied WHERE current_property.property_name::text = 'network_access'::text UNION ALL - SELECT interface.mac AS "UserName", + SELECT interface.mac::text AS "UserName", host(switch.management_ip) AS "NASIPAddress", switch_port.name AS "NASPortId", radius_property.property AS "GroupName", @@ -260,7 +266,7 @@ def downgrade(): JOIN current_property ON "user".id = current_property.user_id AND NOT current_property.denied JOIN radius_property ON radius_property.property::text = current_property.property_name::text UNION ALL - SELECT interface.mac AS "UserName", + SELECT interface.mac::text AS "UserName", host(switch.management_ip) AS "NASIPAddress", switch_port.name AS "NASPortId", 'no_network_access'::text AS "GroupName", @@ -277,7 +283,13 @@ def downgrade(): JOIN patch_port ON patch_port.room_id = room.id AND patch_port.switch_port_id IS NOT NULL JOIN switch_port ON switch_port.id = patch_port.switch_port_id JOIN switch ON switch.host_id = switch_port.switch_id - WHERE users_with_network_access.network_access IS NULL; + WHERE users_with_network_access.network_access IS NULL + UNION ALL + SELECT 'unknown'::text AS "UserName", + NULL::text AS "NASIPAddress", + NULL::character varying AS "NASPortId", + 'unknown'::text AS "GroupName", + 1 AS "Priority"; """ ) diff --git a/pycroft/model/hades.py b/pycroft/model/hades.py index 570d7fcec..af4a89020 100644 --- a/pycroft/model/hades.py +++ b/pycroft/model/hades.py @@ -6,6 +6,7 @@ literal, Column, String, + Text, func, union_all, Table, @@ -16,6 +17,7 @@ Boolean, select, case, + cast, ) from sqlalchemy.orm import Query, aliased, configure_mappers @@ -69,15 +71,18 @@ # Priority 20: valid case (interface's mac w/ vlan at correct ports) # @ /_[un]tagged (Prio 20) # Parsing continues because of Fall-Through:=Yes - Query([ - Interface.mac.label('UserName'), - # `host()` does not print the `/32` like `text` would - func.host(Switch.management_ip).label('NASIPAddress'), - SwitchPort.name.label('NASPortId'), - # TODO: add `_tagged` instead if interface needs that - (VLAN.name + '_untagged').label('GroupName'), - literal(20).label('Priority'), - ]).select_from(User) + Query( + [ + func.text(Interface.mac).label("UserName"), + # `host()` does not print the `/32` like `text` would + func.host(Switch.management_ip).label("NASIPAddress"), + SwitchPort.name.label("NASPortId"), + # TODO: add `_tagged` instead if interface needs that + (VLAN.name + "_untagged").label("GroupName"), + literal(20).label("Priority"), + ] + ) + .select_from(User) .join(Host) .join(Interface) .join(Host.room) @@ -97,7 +102,7 @@ # Also, priority 10: some other custom radius group # @ / (Prio -10) select( - Interface.mac.label("UserName"), + func.text(Interface.mac).label("UserName"), func.host(Switch.management_ip).label("NASIPAddress"), SwitchPort.name.label("NASPortId"), radius_property.c.hades_group_name.label("GroupName"), @@ -118,13 +123,16 @@ radius_property, radius_property.c.property == CurrentProperty.property_name ), # Priority 0: No blocking reason exists → generic error group `no_network_access` - Query([ - Interface.mac.label('UserName'), - func.host(Switch.management_ip).label('NASIPAddress'), - SwitchPort.name.label('NASPortId'), - literal('no_network_access').label('GroupName'), - literal(0).label('Priority'), - ]).select_from(User) + Query( + [ + func.text(Interface.mac).label("UserName"), + func.host(Switch.management_ip).label("NASIPAddress"), + SwitchPort.name.label("NASPortId"), + literal("no_network_access").label("GroupName"), + literal(0).label("Priority"), + ] + ) + .select_from(User) .outerjoin(network_access_subq, User.id == network_access_subq.c.user_id) .filter(network_access_subq.c.network_access.is_(None)) .join(User.hosts) @@ -134,6 +142,13 @@ .join(SwitchPort) .join(Switch) .statement, + select( + cast(literal("unknown"), Text).label("UserName"), + cast(literal(None), Text).label("NASIPAddress"), + cast(literal(None), String).label("NASPortId"), + cast(literal("unknown"), Text).label("GroupName"), + literal(1).label("Priority"), + ), ), ) hades_view_ddl.add_view(radius_property, radusergroup)