package io.vertx.ext.web.handler.impl;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.http.HttpHeaders;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.ext.auth.authentication.AuthenticationProvider;
import io.vertx.ext.web.RoutingContext;
abstract class HTTPAuthorizationHandler<T extends AuthenticationProvider> extends AuthenticationHandlerImpl<T> {
enum Type {
BASIC("Basic"),
DIGEST("Digest"),
BEARER("Bearer"),
HOBA("HOBA"),
MUTUAL("Mutual"),
NEGOTIATE("Negotiate"),
OAUTH("OAuth"),
SCRAM_SHA_1("SCRAM-SHA-1"),
SCRAM_SHA_256("SCRAM-SHA-256");
private final String label;
Type(String label) {
this.label = label;
}
public boolean is(String other) {
return label.equalsIgnoreCase(other);
}
@Override
public String toString() {
return label;
}
}
protected final Type type;
HTTPAuthorizationHandler(T authProvider, Type type) {
super(authProvider);
this.type = type;
}
HTTPAuthorizationHandler(T authProvider, String realm, Type type) {
super(authProvider, realm);
this.type = type;
}
protected final void parseAuthorization(RoutingContext ctx, boolean optional, Handler<AsyncResult<String>> handler) {
final HttpServerRequest request = ctx.request();
final String authorization = request.headers().get(HttpHeaders.AUTHORIZATION);
if (authorization == null) {
if (optional) {
handler.handle(Future.succeededFuture());
} else {
handler.handle(Future.failedFuture(UNAUTHORIZED));
}
return;
}
try {
int idx = authorization.indexOf(' ');
if (idx <= 0) {
handler.handle(Future.failedFuture(BAD_REQUEST));
return;
}
if (!type.is(authorization.substring(0, idx))) {
handler.handle(Future.failedFuture(UNAUTHORIZED));
return;
}
handler.handle(Future.succeededFuture(authorization.substring(idx + 1)));
} catch (RuntimeException e) {
handler.handle(Future.failedFuture(e));
}
}
@Override
public String authenticateHeader(RoutingContext context) {
if (realm != null && realm.length() > 0) {
return type + " realm=\"" +realm + "\"";
}
return null;
}
}