platform/lib/src/hooks/restrict_to_owner.dart
2017-12-22 08:34:31 -05:00

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);
}
}
};
}