package io.vertx.ext.auth.jwt.impl;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
import io.vertx.ext.auth.AbstractUser;
import io.vertx.ext.auth.AuthProvider;
import java.nio.charset.StandardCharsets;
public class JWTUser extends AbstractUser {
private static final Logger log = LoggerFactory.getLogger(JWTUser.class);
private JsonObject jwtToken;
private JsonArray permissions;
public JWTUser() {
log.info("You are probably serializing the JWT User, JWT are supposed to be used in stateless servers!");
}
public JWTUser(JsonObject jwtToken, String permissionsClaimKey) {
this.jwtToken = jwtToken;
if(permissionsClaimKey.contains("/")) {
getNestedJsonValue(jwtToken, permissionsClaimKey);
} else {
this.permissions = jwtToken.getJsonArray(permissionsClaimKey, null);
}
}
private void getNestedJsonValue(JsonObject jwtToken, String permissionsClaimKey) {
String[] keys = permissionsClaimKey.split("/");
JsonObject obj = null;
for(int i = 0; i < keys.length; i++) {
if(i == 0) {
obj = jwtToken.getJsonObject(keys[i]);
} else if (i == keys.length -1) {
if(obj != null) {
this.permissions = obj.getJsonArray(keys[i]);
}
} else {
if(obj != null) {
obj = obj.getJsonObject(keys[i]);
}
}
}
}
@Override
public JsonObject principal() {
return jwtToken;
}
@Override
public void setAuthProvider(AuthProvider authProvider) {
}
@Override
public void doIsPermitted(String permission, Handler<AsyncResult<Boolean>> handler) {
if (permissions != null) {
for (Object jwtPermission : permissions) {
if (permission.equals(jwtPermission)) {
handler.handle(Future.succeededFuture(true));
return;
}
}
}
log.debug("User has no permission [" + permission + "]");
handler.handle(Future.succeededFuture(false));
}
@Override
public void writeToBuffer(Buffer buff) {
super.writeToBuffer(buff);
byte[] bytes = jwtToken.encode().getBytes(StandardCharsets.UTF_8);
buff.appendInt(bytes.length);
buff.appendBytes(bytes);
if (permissions != null) {
bytes = permissions.encode().getBytes(StandardCharsets.UTF_8);
buff.appendInt(bytes.length);
buff.appendBytes(bytes);
} else {
buff.appendInt(0);
}
}
@Override
public int readFromBuffer(int pos, Buffer buffer) {
pos = super.readFromBuffer(pos, buffer);
int len = buffer.getInt(pos);
pos += 4;
byte[] bytes = buffer.getBytes(pos, pos + len);
jwtToken = new JsonObject(new String(bytes, StandardCharsets.UTF_8));
pos += len;
len = buffer.getInt(pos);
pos += 4;
if (len > 0) {
bytes = buffer.getBytes(pos, pos + len);
permissions = new JsonArray(new String(bytes, StandardCharsets.UTF_8));
pos += len;
}
return pos;
}
}