feat(auth): connect Flutter login to MSAL
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import "package:flutter/material.dart";
|
||||
import "package:google_fonts/google_fonts.dart";
|
||||
import "../demo_identity.dart";
|
||||
import "../services/api_client.dart";
|
||||
import "../services/auth_service.dart";
|
||||
import "../theme/ensup_colors.dart";
|
||||
import "../widgets/ensup_top_bar.dart";
|
||||
@@ -10,11 +11,17 @@ import "home_screen.dart";
|
||||
import "responsable_screen.dart";
|
||||
|
||||
/// Écran de démarrage : identification de l'étudiant (RG01/RG02).
|
||||
class LoginScreen extends StatelessWidget {
|
||||
class LoginScreen extends StatefulWidget {
|
||||
const LoginScreen({super.key});
|
||||
|
||||
void _identifier(BuildContext context) {
|
||||
AuthService.selectDemoStudent();
|
||||
@override
|
||||
State<LoginScreen> createState() => _LoginScreenState();
|
||||
}
|
||||
|
||||
class _LoginScreenState extends State<LoginScreen> {
|
||||
bool _connexionEnCours = false;
|
||||
|
||||
void _ouvrirEtudiant() {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (_) => const HomeScreen(),
|
||||
@@ -23,8 +30,7 @@ class LoginScreen extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
void _identifierResponsable(BuildContext context) {
|
||||
AuthService.selectDemoResponsable();
|
||||
void _ouvrirResponsable() {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (_) => const ResponsableScreen(),
|
||||
@@ -33,6 +39,83 @@ class LoginScreen extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
void _identifierParQr() {
|
||||
if (_connexionEnCours) return;
|
||||
if (AuthService.mode == AuthenticationMode.azure) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
const SnackBar(
|
||||
content: Text(
|
||||
"L'identification QR securisee n'est pas encore configuree.",
|
||||
),
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
AuthService.selectDemoStudent();
|
||||
_ouvrirEtudiant();
|
||||
}
|
||||
|
||||
Future<void> _connecterMicrosoft({required bool responsableDemo}) async {
|
||||
if (_connexionEnCours) return;
|
||||
|
||||
setState(() => _connexionEnCours = true);
|
||||
try {
|
||||
if (AuthService.mode == AuthenticationMode.demo) {
|
||||
if (responsableDemo) {
|
||||
AuthService.selectDemoResponsable();
|
||||
_ouvrirResponsable();
|
||||
} else {
|
||||
AuthService.selectDemoStudent();
|
||||
_ouvrirEtudiant();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
await AuthService.signInWithMicrosoft();
|
||||
final reponse = await ApiClient.get("/auth/me");
|
||||
final roleCode = _roleCode(reponse);
|
||||
if (!mounted) return;
|
||||
|
||||
switch (roleCode) {
|
||||
case "ETUDIANT":
|
||||
_ouvrirEtudiant();
|
||||
case "RESPONSABLE":
|
||||
_ouvrirResponsable();
|
||||
default:
|
||||
throw StateError("Role utilisateur non autorise.");
|
||||
}
|
||||
} catch (error) {
|
||||
if (!mounted) return;
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text(error.toString())));
|
||||
} finally {
|
||||
if (mounted) {
|
||||
setState(() => _connexionEnCours = false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String _roleCode(dynamic reponse) {
|
||||
if (reponse is! Map || reponse["data"] is! Map) {
|
||||
throw StateError("Profil utilisateur invalide.");
|
||||
}
|
||||
|
||||
final data = reponse["data"] as Map;
|
||||
if (data["role"] is! Map) {
|
||||
throw StateError("Role utilisateur absent.");
|
||||
}
|
||||
|
||||
final role = data["role"] as Map;
|
||||
final code = role["code"];
|
||||
if (code is! String) {
|
||||
throw StateError("Role utilisateur invalide.");
|
||||
}
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@@ -134,7 +217,9 @@ class LoginScreen extends StatelessWidget {
|
||||
label: "Scanner ma carte étudiante",
|
||||
description:
|
||||
"Présentez votre carte étudiante dématérialisée à la douchette ou à la tablette",
|
||||
onTap: () => _identifier(context),
|
||||
onTap: _connexionEnCours
|
||||
? null
|
||||
: _identifierParQr,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
IdentificationOption(
|
||||
@@ -144,7 +229,11 @@ class LoginScreen extends StatelessWidget {
|
||||
"Connexion compte professionnel ENSUP",
|
||||
description:
|
||||
"Utiliser mon adresse e-mail Microsoft 365",
|
||||
onTap: () => _identifier(context),
|
||||
onTap: _connexionEnCours
|
||||
? null
|
||||
: () => _connecterMicrosoft(
|
||||
responsableDemo: false,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
Row(
|
||||
@@ -173,8 +262,11 @@ class LoginScreen extends StatelessWidget {
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: OutlinedButton.icon(
|
||||
onPressed: () =>
|
||||
_identifierResponsable(context),
|
||||
onPressed: _connexionEnCours
|
||||
? null
|
||||
: () => _connecterMicrosoft(
|
||||
responsableDemo: true,
|
||||
),
|
||||
icon: const Icon(
|
||||
Icons.person_outline,
|
||||
size: 16,
|
||||
|
||||
Reference in New Issue
Block a user