Skip to content

Commit

Permalink
fix: SecuredUserController init after database reset
Browse files Browse the repository at this point in the history
  • Loading branch information
Gustl22 committed Sep 2, 2024
1 parent b2d9c3d commit 9020dfb
Show file tree
Hide file tree
Showing 7 changed files with 48 additions and 37 deletions.
8 changes: 7 additions & 1 deletion wrestling_scoreboard_client/lib/view/screens/home/home.dart
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,13 @@ class HomeState extends ConsumerState<Home> {
Padding(
padding: const EdgeInsets.symmetric(horizontal: 8),
child: SimpleDropdown<Type?>(
options: [null, ...dataTypes..remove(ParticipantState)].map((type) => MapEntry(
options: [
null,
...dataTypes
..remove(ParticipantState)
..remove(User)
..remove(SecuredUser)
].map((type) => MapEntry(
type,
Text(type != null ? localizeType(context, type) : '${localizations.optionSelect} Type'),
)),
Expand Down
2 changes: 1 addition & 1 deletion wrestling_scoreboard_common/lib/src/data/user.dart
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ class SecuredUser with _$SecuredUser implements AbstractUser {
}

@override
String get tableName => 'user';
String get tableName => 'secured_user';

@override
SecuredUser copyWithId(int? id) {
Expand Down
32 changes: 17 additions & 15 deletions wrestling_scoreboard_common/lib/src/util/data_wrapper.dart
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ String getTableNameFromType(Type t) {
const (Participation) => 'participation',
const (ParticipantState) => 'participant_state',
const (Person) => 'person',
const (SecuredUser) => 'user',
const (SecuredUser) => 'secured_user',
const (Team) => 'team',
const (TeamMatch) => 'team_match',
const (TeamMatchBout) => 'team_match_bout',
Expand All @@ -265,6 +265,7 @@ Type getTypeFromTableName(String tableName) {
'basic_auth_service' => BasicAuthService, // Only used for type decoding
'bout_config' => BoutConfig,
'club' => Club,
'competition' => Competition,
'bout' => Bout,
'bout_action' => BoutAction,
'organization' => Organization,
Expand All @@ -280,32 +281,33 @@ Type getTypeFromTableName(String tableName) {
'team' => Team,
'team_match' => TeamMatch,
'team_match_bout' => TeamMatchBout,
'user' => SecuredUser,
'competition' => Competition,
'user' => User,
'weight_class' => WeightClass,
_ => throw UnimplementedError('Type for "${tableName.toString()}" not found.'),
};
}

/// Hierarchically ordered data types.
final dataTypes = [
BoutAction,
ParticipantState,
TeamMatchBout,
Bout,
Participation,
TeamMatch,
BoutAction,
BoutConfig,
Club,
Competition,
Lineup,
LeagueTeamParticipation,
Division,
DivisionWeightClass,
League,
BoutConfig,
LeagueTeamParticipation,
Lineup,
Membership,
Organization,
ParticipantState,
Participation,
Person,
SecuredUser,
Team,
Club,
DivisionWeightClass,
Division,
TeamMatch,
TeamMatchBout,
User,
WeightClass,
Organization,
];
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:io';

import 'package:collection/collection.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:shelf/shelf.dart';
import 'package:wrestling_scoreboard_common/common.dart';
Expand Down Expand Up @@ -49,7 +50,8 @@ class DatabaseController {
Future<Response> reset(Request request, User? user) async {
try {
await _restoreDefault();
Iterable<ShelfController> entityControllers = dataTypes.map((t) => ShelfController.getControllerFromDataType(t));
Iterable<ShelfController> entityControllers =
dataTypes.map((t) => ShelfController.getControllerFromDataType(t)).nonNulls;
// Remove data
await Future.forEach(entityControllers, (e) => e.deleteMany());
// No need to restore the database semantic version for migration,
Expand Down Expand Up @@ -142,7 +144,8 @@ class DatabaseController {
final processResult = await Process.run('psql', args, environment: {'PGPASSWORD': db.dbPW});
await db.open();

Iterable<ShelfController> entityControllers = dataTypes.map((t) => ShelfController.getControllerFromDataType(t));
Iterable<ShelfController> entityControllers =
dataTypes.map((t) => ShelfController.getControllerFromDataType(t)).nonNulls;
await Future.forEach(entityControllers, (e) => e.init());

if (processResult.exitCode != 0) {
Expand Down
20 changes: 10 additions & 10 deletions wrestling_scoreboard_server/lib/controllers/entity_controller.dart
Original file line number Diff line number Diff line change
Expand Up @@ -163,16 +163,18 @@ abstract class ShelfController<T extends DataObject> extends EntityController<T>
}
}

static ShelfController getControllerFromDataType(Type t) {
static ShelfController? getControllerFromDataType(Type t) {
switch (t) {
case const (BoutConfig):
return BoutConfigController();
case const (Club):
return ClubController();
case const (Bout):
return BoutController();
case const (BoutAction):
return BoutActionController();
case const (BoutConfig):
return BoutConfigController();
case const (Club):
return ClubController();
case const (Competition):
return CompetitionController();
case const (Organization):
return OrganizationController();
case const (Division):
Expand Down Expand Up @@ -201,12 +203,10 @@ abstract class ShelfController<T extends DataObject> extends EntityController<T>
return TeamMatchController();
case const (TeamMatchBout):
return TeamMatchBoutController();
case const (Competition):
return CompetitionController();
case const (WeightClass):
return WeightClassController();
default:
throw UnimplementedError('Controller not available for type: $t');
return null;
}
}
}
Expand Down Expand Up @@ -525,7 +525,7 @@ abstract class EntityController<T extends DataObject> {
int id, {
required bool obfuscate,
}) {
return ShelfController.getControllerFromDataType(T).getSingle(id, obfuscate: obfuscate) as Future<T>;
return ShelfController.getControllerFromDataType(T)?.getSingle(id, obfuscate: obfuscate) as Future<T>;
}

static Future<List<T>> getManyFromDataType<T extends DataObject>({
Expand All @@ -534,7 +534,7 @@ abstract class EntityController<T extends DataObject> {
Map<String, dynamic>? substitutionValues,
required bool obfuscate,
}) {
return ShelfController.getControllerFromDataType(T).getMany(
return ShelfController.getControllerFromDataType(T)?.getMany(
conditions: conditions,
conjunction: conjunction,
substitutionValues: substitutionValues,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class SearchController {
final entityController = ShelfController.getControllerFromDataType(searchType);
Map<String, dynamic>? manyJson;
if (isValidLikeSearch) {
manyJson = await entityController.getManyJsonLike(raw, likeParam,
manyJson = await entityController?.getManyJsonLike(raw, likeParam,
organizationId: searchOrganizationId, obfuscate: obfuscate);
if (!searchAllTypes && useProvider && searchOrganizationId != null) {
final orgSearchRes = await OrganizationController().search(
Expand All @@ -55,7 +55,7 @@ class SearchController {
manyJson = manyToJson(orgSearchRes, searchType, CRUD.read, isRaw: false);
}
} else if (!searchAllTypes) {
manyJson = await entityController.getManyJson(
manyJson = await entityController?.getManyJson(
isRaw: raw,
conditions: searchOrganizationId != null ? ['organization_id = @org'] : null,
substitutionValues: searchOrganizationId != null ? {'org': searchOrganizationId} : null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ Future<int> handleSingle<T extends DataObject>({
if (privilege < UserPrivilege.write) {
throw Exception('Not allowed to perform update operation on ${single.tableName}/${single.id}');
}
await controller.updateSingle(single);
await controller!.updateSingle(single);
broadcast((obfuscate) async {
// Need to provide an obfuscated version of the dataObject, but can reuse the `single` object for non obfuscated broadcast, to raise performance
return jsonEncode(
Expand All @@ -317,12 +317,12 @@ Future<int> handleSingle<T extends DataObject>({
if (privilege < UserPrivilege.write) {
throw Exception('Not allowed to perform create operation on ${single.tableName}/${single.id}');
}
single = single.copyWithId(await controller.createSingle(single)) as T;
single = single.copyWithId(await controller!.createSingle(single)) as T;
} else if (operation == CRUD.delete) {
if (privilege < UserPrivilege.write) {
throw Exception('Not allowed to perform delete operation on ${single.tableName}/${single.id}');
}
await controller.deleteSingle(single.id!);
await controller!.deleteSingle(single.id!);
}
if (operation == CRUD.create || operation == CRUD.delete) {
// Update doesn't need to update filtered lists, as it should already be listened to the object itself, which gets an update event
Expand All @@ -345,7 +345,7 @@ Future<int> handleSingleRaw<T extends DataObject>({
if (privilege < UserPrivilege.write) {
throw Exception('Not allowed to perform update operation on ${getTableNameFromType(T)}/${single['id']}');
}
await controller.updateSingleRaw(single);
await controller!.updateSingleRaw(single);
broadcast((obfuscate) async {
// Need to provide an obfuscated version of the dataObject, but can reuse the `single` object for non obfuscated broadcast, to raise performance
return jsonEncode(singleToJson(
Expand All @@ -355,12 +355,12 @@ Future<int> handleSingleRaw<T extends DataObject>({
if (privilege < UserPrivilege.write) {
throw Exception('Not allowed to perform create operation on ${getTableNameFromType(T)}/${single['id']}');
}
single['id'] = await controller.createSingleRaw(single);
single['id'] = await controller!.createSingleRaw(single);
} else if (operation == CRUD.delete) {
if (privilege < UserPrivilege.write) {
throw Exception('Not allowed to perform delete operation on ${getTableNameFromType(T)}/${single['id']}');
}
await controller.deleteSingle(single['id']);
await controller!.deleteSingle(single['id']);
}
if (operation == CRUD.create || operation == CRUD.delete) {
// Update doesn't need to update filtered lists, as it should already be listened to the object itself, which gets an update event
Expand Down

0 comments on commit 9020dfb

Please sign in to comment.