66 lines
1.9 KiB
Dart
66 lines
1.9 KiB
Dart
import 'dart:mirrors';
|
|
import 'package:angel_framework/angel_framework.dart';
|
|
import 'errors.dart';
|
|
import 'is_server_side.dart';
|
|
|
|
/// Restricts users to accessing only their own resources.
|
|
HookedServiceEventListener restrictToOwner(
|
|
{String idField,
|
|
String ownerField,
|
|
userKey,
|
|
String errorMessage,
|
|
getId(user),
|
|
getOwner(obj)}) {
|
|
return (HookedServiceEvent e) async {
|
|
if (!isServerSide(e)) {
|
|
var user = e.request?.grab(userKey ?? 'user');
|
|
|
|
if (user == null)
|
|
throw new AngelHttpException.notAuthenticated(
|
|
message:
|
|
'The current user is missing. You must not be authenticated.');
|
|
|
|
_getId(user) {
|
|
if (getId != null)
|
|
return getId(user);
|
|
else if (user is Map)
|
|
return user[idField ?? 'id'];
|
|
else if (idField == null || idField == 'id')
|
|
return user.id;
|
|
else
|
|
return reflect(user).getField(new Symbol(idField ?? 'id')).reflectee;
|
|
}
|
|
|
|
var id = await _getId(user);
|
|
|
|
if (id == null) throw new Exception('The current user has no ID.');
|
|
|
|
var resource = await e.service.read(
|
|
e.id,
|
|
{}
|
|
..addAll(e.params ?? {})
|
|
..remove('provider'));
|
|
|
|
if (resource != null) {
|
|
_getOwner(obj) {
|
|
if (getOwner != null)
|
|
return getOwner(obj);
|
|
else if (obj is Map)
|
|
return obj[ownerField ?? 'userId'];
|
|
else if (ownerField == null || ownerField == 'userId')
|
|
return obj.userId;
|
|
else
|
|
return reflect(obj)
|
|
.getField(new Symbol(ownerField ?? 'userId'))
|
|
.reflectee;
|
|
}
|
|
|
|
var ownerId = await _getOwner(resource);
|
|
|
|
if ((ownerId is Iterable && !ownerId.contains(id)) || ownerId != id)
|
|
throw new AngelHttpException.forbidden(
|
|
message: errorMessage ?? Errors.INSUFFICIENT_PERMISSIONS);
|
|
}
|
|
}
|
|
};
|
|
}
|