Skip to content

Commit 4fc302a

Browse files
server: add admin user pupils auth
1 parent ae20446 commit 4fc302a

8 files changed

Lines changed: 175 additions & 93 deletions

File tree

school_data_hub_client/lib/src/protocol/client.dart

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,15 @@ class EndpointAdminUser extends _i1.EndpointRef {
445445
'getUserById',
446446
{'userId': userId},
447447
);
448+
449+
/// Sets the pupilsAuth value for the authenticated user.
450+
/// [pupilIds] is a set of pupil IDs that the user is authorized to access.
451+
_i2.Future<_i11.User?> setUserPupilsAuth(Set<int> pupilIds) =>
452+
caller.callServerEndpoint<_i11.User?>(
453+
'adminUser',
454+
'setUserPupilsAuth',
455+
{'pupilIds': pupilIds},
456+
);
448457
}
449458

450459
/// {@category Endpoint}

school_data_hub_client/lib/src/protocol/protocol.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1303,6 +1303,9 @@ class Protocol extends _i1.SerializationManager {
13031303
if (t == List<String>) {
13041304
return (data as List).map((e) => deserialize<String>(e)).toList() as T;
13051305
}
1306+
if (t == Set<int>) {
1307+
return (data as List).map((e) => deserialize<int>(e)).toSet() as T;
1308+
}
13061309
if (t == List<_i91.MissedSchoolday>) {
13071310
return (data as List)
13081311
.map((e) => deserialize<_i91.MissedSchoolday>(e))
@@ -1458,9 +1461,6 @@ class Protocol extends _i1.SerializationManager {
14581461
return (data as List).map((e) => deserialize<_i89.PupilData>(e)).toList()
14591462
as T;
14601463
}
1461-
if (t == Set<int>) {
1462-
return (data as List).map((e) => deserialize<int>(e)).toSet() as T;
1463-
}
14641464
if (t == List<_i105.SupportLevelLegacyDto>) {
14651465
return (data as List)
14661466
.map((e) => deserialize<_i105.SupportLevelLegacyDto>(e))

school_data_hub_flutter/lib/features/app_entry_point/loading_page.dart

Lines changed: 85 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -32,104 +32,102 @@ class LoadingPageState extends State<LoadingPage> {
3232
// }
3333

3434
return Scaffold(
35-
body: SafeArea(
36-
child: Container(
37-
width: double.infinity,
38-
height: double.infinity,
39-
decoration: BoxDecoration(color: AppColors.backgroundColor),
40-
child: LayoutBuilder(
41-
builder: (context, constraints) {
42-
final double maxContentWidth = constraints.maxWidth >= 600
43-
? 600
44-
: constraints.maxWidth;
45-
return Center(
46-
child: SingleChildScrollView(
47-
padding: const EdgeInsets.symmetric(
48-
horizontal: 24,
49-
vertical: 32,
50-
),
51-
child: ConstrainedBox(
52-
constraints: BoxConstraints(maxWidth: maxContentWidth),
53-
child: Column(
54-
mainAxisSize: MainAxisSize.min,
55-
crossAxisAlignment: CrossAxisAlignment.center,
56-
children: [
57-
SizedBox(
58-
height: 300,
59-
width: 300,
60-
child: InkWell(
61-
onTap: () {
62-
Navigator.of(context).push(
63-
MaterialPageRoute(
64-
builder: (ctx) => const LogsPage(),
65-
),
66-
);
67-
},
68-
child: const Image(
69-
image: AssetImage('assets/foreground.png'),
70-
),
35+
body: Container(
36+
width: double.infinity,
37+
height: double.infinity,
38+
decoration: BoxDecoration(color: AppColors.backgroundColor),
39+
child: LayoutBuilder(
40+
builder: (context, constraints) {
41+
final double maxContentWidth = constraints.maxWidth >= 600
42+
? 600
43+
: constraints.maxWidth;
44+
return Center(
45+
child: SingleChildScrollView(
46+
padding: const EdgeInsets.symmetric(
47+
horizontal: 24,
48+
vertical: 32,
49+
),
50+
child: ConstrainedBox(
51+
constraints: BoxConstraints(maxWidth: maxContentWidth),
52+
child: Column(
53+
mainAxisSize: MainAxisSize.min,
54+
crossAxisAlignment: CrossAxisAlignment.center,
55+
children: [
56+
SizedBox(
57+
height: 300,
58+
width: 300,
59+
child: InkWell(
60+
onTap: () {
61+
Navigator.of(context).push(
62+
MaterialPageRoute(
63+
builder: (ctx) => const LogsPage(),
64+
),
65+
);
66+
},
67+
child: const Image(
68+
image: AssetImage('assets/foreground.png'),
7169
),
7270
),
71+
),
72+
Text(
73+
locale.schoolDataHub,
74+
textAlign: TextAlign.center,
75+
style: const TextStyle(
76+
color: Colors.white,
77+
fontWeight: FontWeight.bold,
78+
fontSize: 30,
79+
),
80+
),
81+
const Gap(15),
82+
if (_envManager.activeEnv != null)
7383
Text(
74-
locale.schoolDataHub,
84+
_envManager.activeEnv!.serverName,
7585
textAlign: TextAlign.center,
7686
style: const TextStyle(
7787
color: Colors.white,
7888
fontWeight: FontWeight.bold,
79-
fontSize: 30,
89+
fontSize: 18,
8090
),
8191
),
82-
const Gap(15),
83-
if (_envManager.activeEnv != null)
84-
Text(
85-
_envManager.activeEnv!.serverName,
86-
textAlign: TextAlign.center,
87-
style: const TextStyle(
88-
color: Colors.white,
89-
fontWeight: FontWeight.bold,
90-
fontSize: 18,
91-
),
92-
),
93-
const Gap(40),
94-
const Text(
95-
'Lade Daten...',
96-
textAlign: TextAlign.center,
97-
style: TextStyle(color: Colors.white, fontSize: 18),
98-
),
99-
// Padding(
100-
// padding: const EdgeInsets.symmetric(horizontal: 8.0),
101-
// child: Text(
102-
// lastNotificationMessage,
103-
// textAlign: TextAlign.center,
104-
// style: const TextStyle(
105-
// color: Colors.white,
106-
// fontSize: 18,
107-
// fontWeight: FontWeight.bold,
108-
// ),
109-
// ),
110-
// ),
111-
// const Gap(5),
112-
// Padding(
113-
// padding: const EdgeInsets.symmetric(horizontal: 8.0),
114-
// child: Text(
115-
// actualNotificationMessage,
116-
// textAlign: TextAlign.center,
117-
// style: const TextStyle(
118-
// color: Colors.white,
119-
// fontSize: 18,
120-
// fontWeight: FontWeight.bold,
121-
// ),
122-
// ),
123-
// ),
124-
const Gap(30),
125-
const CircularProgressIndicator(color: Colors.white),
126-
],
127-
),
92+
const Gap(40),
93+
const Text(
94+
'Lade Daten...',
95+
textAlign: TextAlign.center,
96+
style: TextStyle(color: Colors.white, fontSize: 18),
97+
),
98+
// Padding(
99+
// padding: const EdgeInsets.symmetric(horizontal: 8.0),
100+
// child: Text(
101+
// lastNotificationMessage,
102+
// textAlign: TextAlign.center,
103+
// style: const TextStyle(
104+
// color: Colors.white,
105+
// fontSize: 18,
106+
// fontWeight: FontWeight.bold,
107+
// ),
108+
// ),
109+
// ),
110+
// const Gap(5),
111+
// Padding(
112+
// padding: const EdgeInsets.symmetric(horizontal: 8.0),
113+
// child: Text(
114+
// actualNotificationMessage,
115+
// textAlign: TextAlign.center,
116+
// style: const TextStyle(
117+
// color: Colors.white,
118+
// fontSize: 18,
119+
// fontWeight: FontWeight.bold,
120+
// ),
121+
// ),
122+
// ),
123+
const Gap(30),
124+
const CircularProgressIndicator(color: Colors.white),
125+
],
128126
),
129127
),
130-
);
131-
},
132-
),
128+
),
129+
);
130+
},
133131
),
134132
),
135133
);

school_data_hub_server/lib/src/_features/admin/endpoints/admin_user_endpoint.dart

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,4 +276,30 @@ class AdminUserEndpoint extends Endpoint {
276276
);
277277
return user;
278278
}
279+
280+
/// Sets the pupilsAuth value for the authenticated user.
281+
/// [pupilIds] is a set of pupil IDs that the user is authorized to access.
282+
Future<User?> setUserPupilsAuth(Session session, Set<int> pupilIds) async {
283+
// Get the authenticated user
284+
final authenticationInfo = await session.authenticated;
285+
if (authenticationInfo == null) {
286+
return null; // User is not authenticated
287+
}
288+
289+
// Find the user
290+
var user = await User.db.findFirstRow(
291+
session,
292+
where: (t) => t.userInfoId.equals(authenticationInfo.userId),
293+
);
294+
if (user == null) {
295+
return null; // User not found
296+
}
297+
298+
// Update the pupilsAuth field
299+
user.pupilsAuth = pupilIds;
300+
301+
// Save the updated User
302+
await User.db.updateRow(session, user);
303+
return user;
304+
}
279305
}

school_data_hub_server/lib/src/generated/endpoints.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1067,6 +1067,25 @@ class Endpoints extends _i1.EndpointDispatch {
10671067
params['userId'],
10681068
),
10691069
),
1070+
'setUserPupilsAuth': _i1.MethodConnector(
1071+
name: 'setUserPupilsAuth',
1072+
params: {
1073+
'pupilIds': _i1.ParameterDescription(
1074+
name: 'pupilIds',
1075+
type: _i1.getType<Set<int>>(),
1076+
nullable: false,
1077+
)
1078+
},
1079+
call: (
1080+
_i1.Session session,
1081+
Map<String, dynamic> params,
1082+
) async =>
1083+
(endpoints['adminUser'] as _i7.AdminUserEndpoint)
1084+
.setUserPupilsAuth(
1085+
session,
1086+
params['pupilIds'],
1087+
),
1088+
),
10701089
},
10711090
);
10721091
connectors['missedSchoolday'] = _i1.EndpointConnector(

school_data_hub_server/lib/src/generated/protocol.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5993,6 +5993,9 @@ class Protocol extends _i1.SerializationManagerServer {
59935993
if (t == List<String>) {
59945994
return (data as List).map((e) => deserialize<String>(e)).toList() as T;
59955995
}
5996+
if (t == Set<int>) {
5997+
return (data as List).map((e) => deserialize<int>(e)).toSet() as T;
5998+
}
59965999
if (t == List<_i93.MissedSchoolday>) {
59976000
return (data as List)
59986001
.map((e) => deserialize<_i93.MissedSchoolday>(e))
@@ -6148,9 +6151,6 @@ class Protocol extends _i1.SerializationManagerServer {
61486151
return (data as List).map((e) => deserialize<_i91.PupilData>(e)).toList()
61496152
as T;
61506153
}
6151-
if (t == Set<int>) {
6152-
return (data as List).map((e) => deserialize<int>(e)).toSet() as T;
6153-
}
61546154
if (t == List<_i106.SupportLevelLegacyDto>) {
61556155
return (data as List)
61566156
.map((e) => deserialize<_i106.SupportLevelLegacyDto>(e))

school_data_hub_server/lib/src/generated/protocol.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ adminUser:
2727
- promoteUserScope:
2828
- demoteUserScope:
2929
- getUserById:
30+
- setUserPupilsAuth:
3031
missedSchoolday:
3132
- streamMissedSchooldays:
3233
- postMissedSchoolday:

school_data_hub_server/test/integration/test_tools/serverpod_test_tools.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1282,6 +1282,35 @@ class _AdminUserEndpoint {
12821282
}
12831283
});
12841284
}
1285+
1286+
_i3.Future<_i12.User?> setUserPupilsAuth(
1287+
_i1.TestSessionBuilder sessionBuilder,
1288+
Set<int> pupilIds,
1289+
) async {
1290+
return _i1.callAwaitableFunctionAndHandleExceptions(() async {
1291+
var _localUniqueSession =
1292+
(sessionBuilder as _i1.InternalTestSessionBuilder).internalBuild(
1293+
endpoint: 'adminUser',
1294+
method: 'setUserPupilsAuth',
1295+
);
1296+
try {
1297+
var _localCallContext = await _endpointDispatch.getMethodCallContext(
1298+
createSessionCallback: (_) => _localUniqueSession,
1299+
endpointPath: 'adminUser',
1300+
methodName: 'setUserPupilsAuth',
1301+
parameters: _i1.testObjectToJson({'pupilIds': pupilIds}),
1302+
serializationManager: _serializationManager,
1303+
);
1304+
var _localReturnValue = await (_localCallContext.method.call(
1305+
_localUniqueSession,
1306+
_localCallContext.arguments,
1307+
) as _i3.Future<_i12.User?>);
1308+
return _localReturnValue;
1309+
} finally {
1310+
await _localUniqueSession.close();
1311+
}
1312+
});
1313+
}
12851314
}
12861315

12871316
class _MissedSchooldayEndpoint {

0 commit comments

Comments
 (0)