// GCG.MeinCantor - Die Schulplattform für Cantorianer. // Copyright (C) 2021-2022 Georg-Cantor-Gymnasium Halle (Saale) // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published // by the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:meincantor/networking.dart'; import 'package:meincantor/dashboard.dart'; import 'package:url_launcher/url_launcher.dart'; import 'main.dart'; Future checkKey() async { SharedPreferences prefs = await SharedPreferences.getInstance(); String? apiKey = prefs.getString('api_key'); return apiKey != null && apiKey.isNotEmpty; } class Login extends StatelessWidget { Login({Key? key}) : super(key: key); final userController = TextEditingController(); final passwordController = TextEditingController(); final otpController = TextEditingController(); final devIdController = TextEditingController(); @override Widget build(BuildContext context) { return LayoutBuilder( builder: (context, constraints) { double widgetWidth = constraints.maxWidth; //double widgetHeight = constraints.maxHeight; int factor; if (widgetWidth <= 600) { factor = 1; } else if (widgetWidth <= 1400) { factor = 2; } else if (widgetWidth <= 2000) { factor = 3; } else { factor = 4; } return Scaffold( body: Center( child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.fromLTRB(20, 20, 20, 20), child: Container( constraints: BoxConstraints( maxWidth: MediaQuery.of(context).size.width / factor, ), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ MediaQuery.of(context).platformBrightness == Brightness.light ? Image.asset( "assets/images/meincantor-big.png", width: 256) : Image.asset( "assets/images/meincantor-big-dark.png", width: 256), const Divider(), AutofillGroup( child: Column( children: [ TextField( autofillHints: const [ AutofillHints.username ], decoration: const InputDecoration( icon: Icon(MdiIcons.identifier), border: OutlineInputBorder(), labelText: 'Benutzername', ), controller: userController, ), const Divider(), TextField( autofillHints: const [ AutofillHints.password ], decoration: const InputDecoration( icon: Icon(MdiIcons.lock), border: OutlineInputBorder(), labelText: 'Passwort', ), obscureText: true, controller: passwordController, ), ], )), const Divider(), TextField( decoration: const InputDecoration( icon: Icon(MdiIcons.twoFactorAuthentication), border: OutlineInputBorder(), labelText: '2F2-Code', ), obscureText: true, controller: otpController, ), const Divider(), OutlinedButton( onPressed: () async { SharedPreferences prefs = await SharedPreferences.getInstance(); Response loginResponse = await getToken( userController.text, passwordController.text, otpController.text, devIdController.text); if (loginResponse.statusCode == 200) { String apiKey = jsonDecode(utf8.decode( loginResponse.bodyBytes))['token']; prefs.setString('api_key', apiKey); dynamic userinfo = jsonDecode( await getUserInfo( userController.text, passwordController.text, otpController.text, devIdController.text)); prefs.setString('user', userinfo['preferred_username']); prefs.setString('user', userinfo['preferred_username']); prefs.setString('name', userinfo['name']); prefs.setString( 'email', userinfo['email']); prefs.setString( 'class_num', userinfo['groups'][0] .replaceAll("_", "/")); } else if (loginResponse.statusCode == 401) { String text = loginResponse.body; final snackBar = SnackBar( content: Text('Fehler: $text')); ScaffoldMessenger.of(context) .showSnackBar(snackBar); } if (prefs.getString('api_key') != null && prefs .getString('api_key')! .isNotEmpty) { Future.delayed(Duration.zero, () { Navigator.pushReplacement( context, MaterialPageRoute( builder: (context) => const Dashboard()), ); }); } }, child: const Text("Anmelden")), const Divider(), ListTile( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15.0)), title: const Text( "Passwort vergessen?", //style: TextStyle(color: Palette.accent) ), subtitle: const Text( "Jetzt das Passwort zurücksetzen", //style: TextStyle(color: Palette.accent) ), onTap: () => launch( "https://mein.cantorgymnasium.de/auth/realms/GCG.MeinCantor/login-actions/reset-credentials"), ) ], ), ))))); }, ); } }