mirror of
https://github.com/Mercantec-GHC/h4-projekt-gruppe-0-sm.git
synced 2025-04-27 16:24:07 +02:00
cookies as persistent storage
This commit is contained in:
parent
fd288dafee
commit
f36505a38e
@ -1,12 +1,40 @@
|
|||||||
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:mobile/models/user.dart';
|
import 'package:mobile/models/user.dart';
|
||||||
import 'package:mobile/results.dart';
|
import 'package:mobile/results.dart';
|
||||||
import 'package:mobile/server/server.dart';
|
import 'package:mobile/server/server.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
|
||||||
|
class CookieController {
|
||||||
|
CookieController();
|
||||||
|
|
||||||
|
static Future<File> get _cacheFile async {
|
||||||
|
final directory = await getApplicationCacheDirectory();
|
||||||
|
return File("${directory.path}/cookies.txt").create();
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> clear() async {
|
||||||
|
(await _cacheFile).writeAsString("", mode: FileMode.write);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> save(String token) async {
|
||||||
|
(await _cacheFile).writeAsString(token, mode: FileMode.write);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<Result<String, Null>> load() async {
|
||||||
|
final token = await (await _cacheFile).readAsString();
|
||||||
|
if (token.isEmpty) {
|
||||||
|
return const Err(null);
|
||||||
|
}
|
||||||
|
return Ok(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class SessionController {
|
class SessionController {
|
||||||
final Server server;
|
final Server server;
|
||||||
|
final CookieController cookieController = CookieController();
|
||||||
|
|
||||||
String? _sessionToken;
|
|
||||||
User? _sessionUser;
|
User? _sessionUser;
|
||||||
|
|
||||||
final List<_ChangeListener> _sessionChangeListeners = [];
|
final List<_ChangeListener> _sessionChangeListeners = [];
|
||||||
@ -18,7 +46,7 @@ class SessionController {
|
|||||||
final loginResult = await server.login(email, password);
|
final loginResult = await server.login(email, password);
|
||||||
switch (loginResult) {
|
switch (loginResult) {
|
||||||
case Ok<String, String>(value: final sessionToken):
|
case Ok<String, String>(value: final sessionToken):
|
||||||
_sessionToken = sessionToken;
|
await cookieController.save(sessionToken);
|
||||||
notifySessionChangeListeners();
|
notifySessionChangeListeners();
|
||||||
return const Ok(null);
|
return const Ok(null);
|
||||||
case Err<String, String>(value: final message):
|
case Err<String, String>(value: final message):
|
||||||
@ -27,8 +55,13 @@ class SessionController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Result<Null, Null>> loadCachedUser() async {
|
Future<Result<Null, Null>> loadCachedUser() async {
|
||||||
// TODO: retrieve session from cache, if exists
|
switch (await cookieController.load()) {
|
||||||
return _loadCurrentUser();
|
case Ok<String, Null>():
|
||||||
|
return _loadCurrentUser();
|
||||||
|
case Err<String, Null>():
|
||||||
|
notifyUserChangeListeners();
|
||||||
|
return const Err(null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<Result<Null, Null>> loadUpdatedUser() async {
|
Future<Result<Null, Null>> loadUpdatedUser() async {
|
||||||
@ -49,13 +82,16 @@ class SessionController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<Null> logout() async {
|
Future<Null> logout() async {
|
||||||
final sessionToken = _sessionToken;
|
switch (await cookieController.load()) {
|
||||||
if (sessionToken == null) {
|
case Ok<String, Null>(value: final sessionToken):
|
||||||
return;
|
await server.logout(sessionToken);
|
||||||
|
await cookieController.clear();
|
||||||
|
_sessionUser = null;
|
||||||
|
notifySessionChangeListeners();
|
||||||
|
case Err<String, Null>():
|
||||||
|
notifySessionChangeListeners();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
await server.logout(sessionToken);
|
|
||||||
_sessionToken = null;
|
|
||||||
notifySessionChangeListeners();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
User get user {
|
User get user {
|
||||||
@ -86,21 +122,22 @@ class SessionController {
|
|||||||
Future<Result<T, String>> requestWithSession<T>(
|
Future<Result<T, String>> requestWithSession<T>(
|
||||||
Future<Result<T, String>> Function(Server server, String sessionToken)
|
Future<Result<T, String>> Function(Server server, String sessionToken)
|
||||||
func) async {
|
func) async {
|
||||||
final sessionToken = _sessionToken;
|
switch (await cookieController.load()) {
|
||||||
if (sessionToken == null) {
|
case Err<String, Null>():
|
||||||
return const Err("unathorized");
|
|
||||||
}
|
|
||||||
final result = await func(server, sessionToken);
|
|
||||||
if (result case Err<T, String>(value: final message)) {
|
|
||||||
if (message == "unauthorized") {
|
|
||||||
_sessionToken = null;
|
|
||||||
_sessionUser = null;
|
|
||||||
notifySessionChangeListeners();
|
|
||||||
notifyUserChangeListeners();
|
|
||||||
return const Err("unathorized");
|
return const Err("unathorized");
|
||||||
}
|
case Ok<String, Null>(value: final sessionToken):
|
||||||
|
final result = await func(server, sessionToken);
|
||||||
|
if (result case Err<T, String>(value: final message)) {
|
||||||
|
if (message == "unauthorized") {
|
||||||
|
cookieController.clear();
|
||||||
|
_sessionUser = null;
|
||||||
|
notifySessionChangeListeners();
|
||||||
|
notifyUserChangeListeners();
|
||||||
|
return const Err("unathorized");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void notifySessionChangeListeners() {
|
void notifySessionChangeListeners() {
|
||||||
|
@ -18,6 +18,7 @@ import 'package:provider/provider.dart';
|
|||||||
import 'package:mobile/controllers/routing.dart';
|
import 'package:mobile/controllers/routing.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
final server = BackendServer();
|
final server = BackendServer();
|
||||||
final usersController = UsersController(server: server);
|
final usersController = UsersController(server: server);
|
||||||
final sessionController = SessionController(server: server);
|
final sessionController = SessionController(server: server);
|
||||||
@ -47,6 +48,7 @@ class MyApp extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MultiProvider(
|
return MultiProvider(
|
||||||
providers: [
|
providers: [
|
||||||
|
Provider(create: (_) => CookieController()),
|
||||||
ChangeNotifierProvider(
|
ChangeNotifierProvider(
|
||||||
create: (_) => SessionProvider(controller: sessionController)),
|
create: (_) => SessionProvider(controller: sessionController)),
|
||||||
ChangeNotifierProvider(
|
ChangeNotifierProvider(
|
||||||
@ -79,12 +81,12 @@ class MyApp extends StatelessWidget {
|
|||||||
useMaterial3: true,
|
useMaterial3: true,
|
||||||
),
|
),
|
||||||
home: Consumer2<SessionProvider, CurrentUserProvider>(
|
home: Consumer2<SessionProvider, CurrentUserProvider>(
|
||||||
builder: (_, provider1, provider2, ___) {
|
builder: (_, sessionProvider, currentUserProvider, ___) {
|
||||||
if (provider1.controller.hasUser) {
|
if (sessionProvider.controller.hasUser) {
|
||||||
return Dashboard();
|
return Dashboard();
|
||||||
}
|
}
|
||||||
return FutureBuilder(
|
return FutureBuilder(
|
||||||
future: provider1.controller.loadCachedUser(),
|
future: sessionProvider.controller.loadCachedUser(),
|
||||||
builder: (_, snapshot) {
|
builder: (_, snapshot) {
|
||||||
final error = snapshot.error;
|
final error = snapshot.error;
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
|
@ -102,12 +102,12 @@ class AllProductsPage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _AllProductsPageState extends State<AllProductsPage> {
|
class _AllProductsPageState extends State<AllProductsPage> {
|
||||||
final seawchContwowwew = TextEditingController();
|
final searchController = TextEditingController();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
final contwowwew = context.read<ProductController>();
|
final controller = context.read<ProductController>();
|
||||||
seawchContwowwew.text = contwowwew.query;
|
searchController.text = controller.query;
|
||||||
super.initState();
|
super.initState();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -128,7 +128,7 @@ class _AllProductsPageState extends State<AllProductsPage> {
|
|||||||
onChanged: (query) {
|
onChanged: (query) {
|
||||||
productRepo.searchProducts(query);
|
productRepo.searchProducts(query);
|
||||||
},
|
},
|
||||||
controller: seawchContwowwew,
|
controller: searchController,
|
||||||
decoration: const InputDecoration(
|
decoration: const InputDecoration(
|
||||||
label: Text("Search"),
|
label: Text("Search"),
|
||||||
contentPadding: EdgeInsets.only(top: 20))),
|
contentPadding: EdgeInsets.only(top: 20))),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user