feat(admin): grant full admin permissions in app and security rules to nicolas@gruber.info

This commit is contained in:
2026-09-14 11:35:40 +02:00
parent e64b7a085c
commit c3513e85e5
4 changed files with 52 additions and 29 deletions
+4 -1
View File
@@ -8,7 +8,10 @@ service cloud.firestore {
}
function isAdmin() {
return request.auth != null && request.auth.token.admin == true;
return request.auth != null && (
request.auth.token.admin == true ||
request.auth.token.email == 'nicolas@gruber.info'
);
}
function isAuthorOrAdmin() {
+37 -27
View File
@@ -51,11 +51,13 @@ class InfoScreen extends StatelessWidget {
const SizedBox(height: 8),
// Bürgerforum Access & Account Card
Card(
color: auth.isRegisteredUser
? Colors.green.shade50
: auth.isCommunityUnlocked
? Colors.teal.shade50
: Colors.blue.shade50,
color: auth.isAdmin
? Colors.indigo.shade50
: auth.isRegisteredUser
? Colors.green.shade50
: auth.isCommunityUnlocked
? Colors.teal.shade50
: Colors.blue.shade50,
shape:
RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
child: Padding(
@@ -65,16 +67,20 @@ class InfoScreen extends StatelessWidget {
Row(
children: [
Icon(
auth.isRegisteredUser
? Icons.account_circle
: auth.isCommunityUnlocked
? Icons.verified_user
: Icons.lock_outline,
color: auth.isRegisteredUser
? Colors.green.shade700
: auth.isCommunityUnlocked
? Colors.teal.shade800
: Colors.blue.shade800,
auth.isAdmin
? Icons.admin_panel_settings
: auth.isRegisteredUser
? Icons.account_circle
: auth.isCommunityUnlocked
? Icons.verified_user
: Icons.lock_outline,
color: auth.isAdmin
? Colors.indigo.shade700
: auth.isRegisteredUser
? Colors.green.shade700
: auth.isCommunityUnlocked
? Colors.teal.shade800
: Colors.blue.shade800,
size: 36,
),
const SizedBox(width: 14),
@@ -83,23 +89,27 @@ class InfoScreen extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
auth.isRegisteredUser
? (auth.displayName?.isNotEmpty == true
? auth.displayName!
: 'Bürger-Konto')
: auth.isCommunityUnlocked
? 'Bürgerzugang: Aktiv (Code)'
: 'Gastmodus (Nur Lesen)',
auth.isAdmin
? 'Administrator'
: auth.isRegisteredUser
? (auth.displayName?.isNotEmpty == true
? auth.displayName!
: 'Bürger-Konto')
: auth.isCommunityUnlocked
? 'Bürgerzugang: Aktiv (Code)'
: 'Gastmodus (Nur Lesen)',
style: const TextStyle(
fontWeight: FontWeight.bold, fontSize: 15),
),
const SizedBox(height: 2),
Text(
auth.isRegisteredUser
? auth.email ?? 'Angemeldet'
: auth.isCommunityUnlocked
? 'Mängel & Ideen freigeschaltet'
: 'Anmelden oder Code eingeben zum Mitwirken.',
auth.isAdmin
? '${auth.email ?? "Angemeldet"} (Admin-Rechte aktiv)'
: auth.isRegisteredUser
? auth.email ?? 'Angemeldet'
: auth.isCommunityUnlocked
? 'Mängel & Ideen freigeschaltet'
: 'Anmelden oder Code eingeben zum Mitwirken.',
style: TextStyle(
fontSize: 12, color: Colors.grey.shade700),
),
+9
View File
@@ -47,8 +47,17 @@ 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)) {
_isAdmin = true;
return;
}
try {
final tokenResult = await user.getIdTokenResult();
_isAdmin = tokenResult.claims?['admin'] == true;
+2 -1
View File
@@ -15,7 +15,8 @@ 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.admin == true ||
request.auth.token.email == 'nicolas@gruber.info'
);
}
}