Skip to content

Commit

Permalink
feat: Addition of automatic FirestoreRule generation.
Browse files Browse the repository at this point in the history
  • Loading branch information
mathrunet committed Jan 24, 2024
1 parent 06a48c0 commit 3fb4c2c
Show file tree
Hide file tree
Showing 36 changed files with 3,015 additions and 180 deletions.
10 changes: 8 additions & 2 deletions packages/katana_model/lib/src/database_validator.dart
Expand Up @@ -108,6 +108,7 @@ class DatabaseValidator {
for (final validationQuery in validationQueries) {
if (!validationQuery._checkPermissionWithValue(
query: query.query,
docId: query.query.path.last(),
userId: userId,
value: value,
)) {
Expand Down Expand Up @@ -202,11 +203,13 @@ class DatabaseValidator {
}
final userId = await onRetrieveUserId();
for (final validationQuery in validationQueries) {
for (final document in (value?.values ?? <DynamicMap>[])) {
for (final document
in (value?.entries ?? <MapEntry<String, DynamicMap>>[])) {
if (!validationQuery._checkPermissionWithValue(
query: query.query,
docId: document.key,
userId: userId,
value: document,
value: document.value,
)) {
throw DatabaseValidationExcepction(
"Not permitted: OnLoadedCollection at ${query.query.path} $validationQueries $value",
Expand Down Expand Up @@ -276,6 +279,7 @@ class DatabaseValidator {
) ||
!validationQuery._checkPermissionWithValue(
query: query.query,
docId: query.query.path.last(),
userId: userId,
value: newValue,
)) {
Expand Down Expand Up @@ -316,6 +320,7 @@ class DatabaseValidator {
) ||
!validationQuery._checkPermissionWithValue(
query: query.query,
docId: query.query.path.last(),
userId: userId,
value: newValue,
)) {
Expand Down Expand Up @@ -368,6 +373,7 @@ class DatabaseValidator {
) ||
!validationQuery._checkPermissionWithValue(
query: query.query,
docId: query.query.path.last(),
userId: userId,
value: oldValue,
)) {
Expand Down
37 changes: 25 additions & 12 deletions packages/katana_model/lib/src/model_validation_query.dart
Expand Up @@ -107,12 +107,16 @@ enum ModelValidationQueryUserType {
/// {@template model_validation_query_user_type_user_from_path_index}
/// An authenticated user whose user ID matches the dynamic value specified by the index number in the document or collection path and the user ID authenticated on the app.
///
/// You can specify odd numbers such as `1` or `3` even if you specify a collection since it will always be compared to a document.
///
/// If [allUsers] or [authUsers] is specified, it takes precedence.
///
/// [userFromData] can be specified at the same time.
///
/// 認証済みユーザーのうち、ドキュメントやコレクションのパス中のインデックス番号で指定する動的な値とアプリ上で認証しているユーザーIDが一致するユーザー。
///
/// 必ずドキュメントとの比較になるのでコレクションを指定した場合でも`1``3`などの奇数番号を指定可能です。
///
/// [allUsers][authUsers]が指定されている場合はそちらが優先されます。
///
/// [userFromData]とは同時に指定可能です。
Expand All @@ -132,12 +136,16 @@ enum ModelValidationQueryUserType {
/// {@template model_validation_query_user_type_user_from_data}
/// An authenticated user whose user ID matches the value of a field with `key` in the document to be read or written and the user ID authenticated on the app.
///
/// If `@uid` is specified, a comparison with the document ID is performed.
///
/// If [allUsers] or [authUsers] is specified, it takes precedence.
///
/// [userFromPathIndex] can be specified at the same time.
///
/// 認証済みユーザーのうち、読み込みや書き込み対象のドキュメント中に`key`を持つフィールドの値ととアプリ上で認証しているユーザーIDが一致するユーザー。
///
/// `@uid`が指定されている場合ドキュメントIDとの比較が行われます。
///
/// [allUsers][authUsers]が指定されている場合はそちらが優先されます。
///
/// [userFromPathIndex]とは同時に指定可能です。
Expand Down Expand Up @@ -208,33 +216,38 @@ abstract class ModelValidationQuery {
switch (user) {
case ModelValidationQueryUserType.allUsers:
case ModelValidationQueryUserType.userFromData:
case ModelValidationQueryUserType.userFromPathIndex:
return true;
case ModelValidationQueryUserType.authUsers:
return userId.isNotEmpty;
case ModelValidationQueryUserType.userFromPathIndex:
if (key is! int) {
return false;
}
final path = query.path.trimQuery().trimString("/").split("/");
final index = key as int;
if (path.length <= index) {
return false;
}
final pathUserId = path[index];
return pathUserId == userId;
}
}

bool _checkPermissionWithValue({
required ModelQuery query,
required String? docId,
required DynamicMap? value,
String? userId,
}) {
switch (user) {
case ModelValidationQueryUserType.allUsers:
case ModelValidationQueryUserType.authUsers:
case ModelValidationQueryUserType.userFromPathIndex:
return true;
case ModelValidationQueryUserType.userFromPathIndex:
if (key is! int || docId.isEmpty) {
return false;
}
final path = query.path.trimQuery().trimString("/").split("/");
if (path.length % 2 == 0) {
path.removeLast();
}
path.add(docId!);
final index = key as int;
if (path.length <= index) {
return false;
}
final pathUserId = path[index];
return pathUserId == userId;
case ModelValidationQueryUserType.userFromData:
if (key is! String || value == null) {
return false;
Expand Down

0 comments on commit 3fb4c2c

Please sign in to comment.