refactor(admin): remove hardcoded email and dynamically resolve admin privileges via Firestore Admins collection
Build Android APK / Build Release APKs (push) Successful in 16m46s
Build Android APK / Build Release APKs (push) Successful in 16m46s
This commit is contained in:
+8
-1
@@ -10,7 +10,8 @@ service cloud.firestore {
|
||||
function isAdmin() {
|
||||
return request.auth != null && (
|
||||
request.auth.token.admin == true ||
|
||||
request.auth.token.email == 'nicolas@gruber.info'
|
||||
exists(/databases/$(database)/documents/Admins/$(request.auth.uid)) ||
|
||||
(request.auth.token.email != null && exists(/databases/$(database)/documents/Admins/$(request.auth.token.email)))
|
||||
);
|
||||
}
|
||||
|
||||
@@ -22,6 +23,12 @@ service cloud.firestore {
|
||||
);
|
||||
}
|
||||
|
||||
// Admins-Sammlung: Angemeldete Nutzer können prüfen, nur Admins schreiben
|
||||
match /Admins/{adminDoc} {
|
||||
allow read: if isAuthenticated();
|
||||
allow write: if isAdmin();
|
||||
}
|
||||
|
||||
// Öffentliche Sammlungen: News, Mängel (Issues) & Ideen (CitizensForum)
|
||||
match /{collection}/{document=**} {
|
||||
// Jeder darf News, Mängel & Ideen öffentlich lesen
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:firebase_auth/firebase_auth.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class AuthService extends ChangeNotifier {
|
||||
@@ -47,21 +48,64 @@ class AuthService extends ChangeNotifier {
|
||||
_initAuth();
|
||||
}
|
||||
|
||||
static const List<String> adminEmails = [
|
||||
'nicolas@gruber.info',
|
||||
];
|
||||
|
||||
Future<void> _checkAdminClaim(User? user) async {
|
||||
if (user != null && !user.isAnonymous) {
|
||||
final email = user.email?.trim().toLowerCase();
|
||||
if (email != null && adminEmails.contains(email)) {
|
||||
try {
|
||||
// 1. Custom claims check (token.admin == true)
|
||||
final tokenResult = await user.getIdTokenResult();
|
||||
if (tokenResult.claims?['admin'] == true) {
|
||||
_isAdmin = true;
|
||||
return;
|
||||
}
|
||||
try {
|
||||
final tokenResult = await user.getIdTokenResult();
|
||||
_isAdmin = tokenResult.claims?['admin'] == true;
|
||||
} catch (_) {
|
||||
|
||||
final firestore = FirebaseFirestore.instance;
|
||||
|
||||
// 2. Check Firestore 'Admins' collection by user UID (doc id)
|
||||
final docByUid =
|
||||
await firestore.collection('Admins').doc(user.uid).get();
|
||||
if (docByUid.exists) {
|
||||
_isAdmin = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// 3. Check Firestore 'Admins' collection by email (doc id)
|
||||
final userEmail = user.email?.trim().toLowerCase();
|
||||
if (userEmail != null && userEmail.isNotEmpty) {
|
||||
final docByEmail =
|
||||
await firestore.collection('Admins').doc(userEmail).get();
|
||||
if (docByEmail.exists) {
|
||||
_isAdmin = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Check Firestore 'Admins' collection where email field == userEmail
|
||||
final queryByEmail = await firestore
|
||||
.collection('Admins')
|
||||
.where('email', isEqualTo: userEmail)
|
||||
.limit(1)
|
||||
.get();
|
||||
if (queryByEmail.docs.isNotEmpty) {
|
||||
_isAdmin = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Check Firestore 'Admins' collection where uid field == user.uid
|
||||
final queryByUid = await firestore
|
||||
.collection('Admins')
|
||||
.where('uid', isEqualTo: user.uid)
|
||||
.limit(1)
|
||||
.get();
|
||||
if (queryByUid.docs.isNotEmpty) {
|
||||
_isAdmin = true;
|
||||
return;
|
||||
}
|
||||
|
||||
_isAdmin = false;
|
||||
} catch (e) {
|
||||
if (kDebugMode) {
|
||||
debugPrint('Error checking admin status: $e');
|
||||
}
|
||||
_isAdmin = false;
|
||||
}
|
||||
} else {
|
||||
|
||||
+1
-2
@@ -15,8 +15,7 @@ service firebase.storage {
|
||||
// Nur der Verfasser oder ein Admin darf sein Foto löschen
|
||||
allow delete: if request.auth != null && (
|
||||
request.auth.uid == userId ||
|
||||
request.auth.token.admin == true ||
|
||||
request.auth.token.email == 'nicolas@gruber.info'
|
||||
request.auth.token.admin == true
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user