Skip to content

Commit 64c4769

Browse files
committed
Add whitelist system
1 parent 6931cc6 commit 64c4769

File tree

18 files changed

+343
-175
lines changed

18 files changed

+343
-175
lines changed

api/lib/src/event/process/client.dart

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -140,15 +140,15 @@ Future<ServerResponse?> processClientEvent(
140140

141141
if (event == null) {
142142
if (challengeManager != null) {
143-
final challenge = challengeManager.getChallenge(channel);
143+
final challenge = challengeManager.generateNewChallenge(channel);
144144
return ServerResponse.builder(
145145
AuthenticatedRequested(
146146
challenge,
147147
isRequired: true,
148148
),
149149
channel);
150150
}
151-
userManager?.addUser(channel);
151+
await userManager?.addUser(channel);
152152
return ServerResponse.builder(buildInitialize(), channel);
153153
}
154154
if (!isValidClientEvent(event, channel, state, assetManager: assetManager)) {
@@ -299,12 +299,20 @@ Future<ServerResponse?> processClientEvent(
299299
case AuthenticateRequest():
300300
final challenge = challengeManager?.getChallenge(channel);
301301
if (challenge == null) return null;
302+
if (challengeManager == null) return null;
302303
final verified = await event.verify(challenge);
303304
if (!verified) {
305+
final newChallenge = challengeManager.generateNewChallenge(channel);
304306
return ServerResponse.builder(
305-
AuthenticatedRequested(challenge, isRequired: true), channel);
307+
AuthenticatedRequested(newChallenge, isRequired: true), channel);
308+
}
309+
final result = await userManager?.addUser(
310+
channel, generateFingerprint(event.publicKey));
311+
if (result == false) {
312+
final newChallenge = challengeManager.generateNewChallenge(channel);
313+
return ServerResponse.builder(
314+
AuthenticatedRequested(newChallenge, isRequired: true), channel);
306315
}
307-
userManager?.addUser(channel, generateFingerprint(event.publicKey));
308316
return ServerResponse.builder(buildInitialize(), channel);
309317
}
310318
}

api/lib/src/models/config.dart

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,12 @@ final class SetonixConfig with SetonixConfigMappable {
2929
final String? guestPrefix;
3030
static const String defaultGuestPrefix = 'Guest ';
3131
static const String envGuestPrefix = 'SETONIX_GUEST_PREFIX';
32-
final String? authEndpoint;
33-
static const String defaultAuthEndpoint = '';
34-
static const String envAuthEndpoint = 'SETONIX_AUTH_ENDPOINT';
32+
final bool? whitelistEnabled;
33+
static const bool defaultWhitelistEnabled = false;
34+
static const String envWhitelistEnabled = 'SETONIX_WHITELIST_ENABLED';
35+
final bool? accountRequired;
36+
static const bool defaultAccountRequired = true;
37+
static const String envAccountRequired = 'SETONIX_ACCOUNT_REQUIRED';
3538
final String? endpointSecret;
3639
static const String defaultEndpointSecret = '';
3740
static const String envEndpointSecret = 'SETONIX_ENDPOINT_SECRET';
@@ -45,7 +48,8 @@ final class SetonixConfig with SetonixConfigMappable {
4548
this.maxPlayers,
4649
this.description,
4750
this.guestPrefix,
48-
this.authEndpoint,
51+
this.whitelistEnabled,
52+
this.accountRequired,
4953
this.endpointSecret,
5054
});
5155

@@ -58,7 +62,8 @@ final class SetonixConfig with SetonixConfigMappable {
5862
maxPlayers: defaultMaxPlayers,
5963
description: defaultDescription,
6064
guestPrefix: defaultGuestPrefix,
61-
authEndpoint: defaultAuthEndpoint,
65+
whitelistEnabled: defaultWhitelistEnabled,
66+
accountRequired: defaultAccountRequired,
6267
endpointSecret: defaultEndpointSecret,
6368
);
6469

@@ -90,9 +95,13 @@ final class SetonixConfig with SetonixConfigMappable {
9095
? String.fromEnvironment(envGuestPrefix,
9196
defaultValue: defaultGuestPrefix)
9297
: null,
93-
authEndpoint: bool.hasEnvironment(envAuthEndpoint)
94-
? String.fromEnvironment(envAuthEndpoint,
95-
defaultValue: defaultAuthEndpoint)
98+
whitelistEnabled: bool.hasEnvironment(envWhitelistEnabled)
99+
? bool.fromEnvironment(envWhitelistEnabled,
100+
defaultValue: defaultWhitelistEnabled)
101+
: null,
102+
accountRequired: bool.hasEnvironment(envAccountRequired)
103+
? bool.fromEnvironment(envAccountRequired,
104+
defaultValue: defaultAccountRequired)
96105
: null,
97106
endpointSecret: bool.hasEnvironment(envEndpointSecret)
98107
? String.fromEnvironment(envEndpointSecret,
@@ -110,5 +119,8 @@ final class SetonixConfig with SetonixConfigMappable {
110119
maxPlayers: other.maxPlayers ?? maxPlayers,
111120
description: other.description ?? description,
112121
guestPrefix: other.guestPrefix ?? guestPrefix,
122+
endpointSecret: other.endpointSecret ?? endpointSecret,
123+
accountRequired: other.accountRequired ?? accountRequired,
124+
whitelistEnabled: other.whitelistEnabled ?? whitelistEnabled,
113125
);
114126
}

api/lib/src/models/config.mapper.dart

Lines changed: 19 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/lib/src/services/challenge.dart

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,14 @@ import 'package:networker/networker.dart';
66
class ChallengeManager {
77
final Map<Channel, Uint8List> _challenges = {};
88

9-
Uint8List getChallenge(Channel channel) {
10-
return _challenges[channel] ??= generateChallenge();
9+
Uint8List? getChallenge(Channel channel) {
10+
return _challenges[channel];
11+
}
12+
13+
Uint8List generateNewChallenge(Channel channel) {
14+
final challenge = generateChallenge();
15+
_challenges[channel] = challenge;
16+
return challenge;
1117
}
1218

1319
void removeChallenge(Channel channel) {

api/lib/src/services/user.dart

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import 'dart:async';
2-
import 'dart:typed_data';
32

43
import 'package:dart_mappable/dart_mappable.dart';
54
import 'package:networker/networker.dart';
@@ -39,10 +38,12 @@ final class UserManager {
3938
final Map<Channel, SetonixUser> _users = {};
4039
final String guestPrefix;
4140
final UserService? service;
41+
final bool whitelistEnabled;
4242
int _nextGuestId = 1;
4343

4444
UserManager({
4545
this.service,
46+
this.whitelistEnabled = SetonixConfig.defaultWhitelistEnabled,
4647
this.guestPrefix = SetonixConfig.defaultGuestPrefix,
4748
});
4849

@@ -78,7 +79,13 @@ final class UserManager {
7879
Future<bool> addUser(Channel channel,
7980
[String? fingerprint, String? name]) async {
8081
SetonixUser? user;
81-
if (fingerprint != null) user = await service?.getUser(fingerprint);
82+
if (fingerprint != null) {
83+
user = await service?.getUser(fingerprint);
84+
if (user != null) name = user.name;
85+
if (whitelistEnabled && user?.onWhitelist != true) {
86+
return false; // User is not on the whitelist
87+
}
88+
}
8289
name ??= _generateGuestName();
8390
if (containsUserName(name)) {
8491
return false;

api/lib/src/services/user.mapper.dart

Lines changed: 47 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

api/pubspec.lock

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,10 @@ packages:
6161
dependency: transitive
6262
description:
6363
name: build
64-
sha256: "8295b0b6dfe00499b786718f2936a56b5e0d56d169c528472c8c1908f2b1e3ee"
64+
sha256: "74273591bd8b7f82eeb1f191c1b65a6576535bbfd5ca3722778b07d5702d33cc"
6565
url: "https://pub.dev"
6666
source: hosted
67-
version: "2.5.0"
67+
version: "2.5.3"
6868
build_config:
6969
dependency: transitive
7070
description:
@@ -85,26 +85,26 @@ packages:
8585
dependency: transitive
8686
description:
8787
name: build_resolvers
88-
sha256: "57fe2f9149b01d52fcd0ea7de17083739b5cf9e040dedb4e24a17c628c1e9caf"
88+
sha256: badce70566085f2e87434531c4a6bc8e833672f755fc51146d612245947e91c9
8989
url: "https://pub.dev"
9090
source: hosted
91-
version: "2.5.0"
91+
version: "2.5.3"
9292
build_runner:
9393
dependency: "direct dev"
9494
description:
9595
name: build_runner
96-
sha256: "9b196d7b629c5317dff3ec83c7e98840b773cee3b9339b646fe487048d2ebc74"
96+
sha256: b9070a4127033777c0e63195f6f117ed16a351ed676f6313b095cf4f328c0b82
9797
url: "https://pub.dev"
9898
source: hosted
99-
version: "2.5.0"
99+
version: "2.5.3"
100100
build_runner_core:
101101
dependency: transitive
102102
description:
103103
name: build_runner_core
104-
sha256: dae6a8a5cbef6866cdfa0d96df4b0d85b9086897096270a405a44d946dafffba
104+
sha256: "1cdfece3eeb3f1263f7dbf5bcc0cba697bd0c22d2c866cb4b578c954dbb09bcf"
105105
url: "https://pub.dev"
106106
source: hosted
107-
version: "9.0.0"
107+
version: "9.1.1"
108108
built_collection:
109109
dependency: transitive
110110
description:

0 commit comments

Comments
 (0)