platform/lib/strategies/local.dart

92 lines
3 KiB
Dart
Raw Normal View History

2016-05-03 04:13:19 +00:00
part of angel_auth;
/// Determines the validity of an incoming username and password.
typedef Future LocalAuthVerifier(String username, String password);
class LocalAuthStrategy extends AuthStrategy {
RegExp _rgxBasic = new RegExp(r'^Basic (.+)$', caseSensitive: false);
RegExp _rgxUsrPass = new RegExp(r'^([^:]+):(.+)$');
@override
String name = 'local';
LocalAuthVerifier verifier;
String usernameField;
String passwordField;
String invalidMessage;
bool allowBasic;
bool forceBasic;
2016-05-09 20:47:28 +00:00
String realm;
2016-05-03 04:13:19 +00:00
LocalAuthStrategy(LocalAuthVerifier this.verifier,
{String this.usernameField: 'username',
String this.passwordField: 'password',
String this.invalidMessage:
'Please provide a valid username and password.',
bool this.allowBasic: true,
bool this.forceBasic: false,
2016-05-09 20:47:28 +00:00
String this.realm: 'Authentication is required.'}) {}
2016-05-03 04:13:19 +00:00
@override
Future<bool> canLogout(RequestContext req, ResponseContext res) async {
return true;
}
@override
Future<bool> authenticate(RequestContext req, ResponseContext res,
2016-05-09 20:47:28 +00:00
[AngelAuthOptions options_]) async {
AngelAuthOptions options = options_ ?? new AngelAuthOptions();
2016-05-03 04:13:19 +00:00
var verificationResult;
if (allowBasic) {
String authHeader = req.headers.value(HttpHeaders.AUTHORIZATION) ?? "";
if (_rgxBasic.hasMatch(authHeader)) {
String base64AuthString = _rgxBasic.firstMatch(authHeader).group(1);
String authString = new String.fromCharCodes(
BASE64.decode(base64AuthString));
if (_rgxUsrPass.hasMatch(authString)) {
Match usrPassMatch = _rgxUsrPass.firstMatch(authString);
verificationResult =
await verifier(usrPassMatch.group(1), usrPassMatch.group(2));
} else throw new AngelHttpException.BadRequest(
errors: [invalidMessage]);
}
}
if (verificationResult == null) {
if (_validateString(req.body[usernameField]) &&
_validateString(req.body[passwordField])) {
verificationResult =
await verifier(req.body[usernameField], req.body[passwordField]);
}
}
if (verificationResult == false || verificationResult == null) {
2016-05-09 20:47:28 +00:00
if (options.failureRedirect != null &&
options.failureRedirect.isNotEmpty) {
2016-05-03 04:13:19 +00:00
return res.redirect(
2016-05-09 20:47:28 +00:00
options.failureRedirect, code: HttpStatus.UNAUTHORIZED);
2016-05-03 04:13:19 +00:00
}
if (forceBasic) {
res
..status(401)
2016-05-09 20:47:28 +00:00
..header(HttpHeaders.WWW_AUTHENTICATE, 'Basic realm="$realm"')
2016-05-03 04:13:19 +00:00
..end();
return false;
2016-07-03 23:36:41 +00:00
} else return false;
2016-05-03 04:13:19 +00:00
}
2016-07-03 23:36:41 +00:00
else if (verificationResult != null && verificationResult != false) {
req.session['userId'] = await Auth.serializer(verificationResult);
if (options.successRedirect != null &&
options.successRedirect.isNotEmpty) {
return res.redirect(options.successRedirect, code: HttpStatus.OK);
}
2016-05-03 04:13:19 +00:00
2016-07-03 23:36:41 +00:00
return true;
} else {
throw new AngelHttpException.NotAuthenticated();
}
2016-05-03 04:13:19 +00:00
}
}