keycloak-d4science-spi-parent/avatar-realm-resource/src/main/java/org/gcube/keycloak/avatar/AvatarResource.java

102 lines
3.5 KiB
Java

package org.gcube.keycloak.avatar;
import java.io.InputStream;
import java.util.Objects;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import org.jboss.resteasy.annotations.cache.NoCache;
import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.keycloak.models.KeycloakSession;
import org.keycloak.models.RealmModel;
import org.keycloak.services.managers.AppAuthManager;
import org.keycloak.services.managers.AuthenticationManager;
import org.keycloak.services.resources.RealmsResource;
public class AvatarResource extends AbstractAvatarResource {
public static final String STATE_CHECKER_ATTRIBUTE = "state_checker";
public static final String STATE_CHECKER_PARAMETER = "stateChecker";
private final AuthenticationManager.AuthResult auth;
public AvatarResource(KeycloakSession session) {
super(session);
this.auth = resolveAuthentication(session);
}
private AuthenticationManager.AuthResult resolveAuthentication(KeycloakSession keycloakSession) {
AppAuthManager appAuthManager = new AppAuthManager();
RealmModel realm = keycloakSession.getContext().getRealm();
return appAuthManager.authenticateIdentityCookie(keycloakSession, realm);
}
@Path("/admin")
public AvatarAdminResource admin() {
AvatarAdminResource service = new AvatarAdminResource(session);
ResteasyProviderFactory.getInstance().injectProperties(service);
service.init();
return service;
}
@GET
@Produces({ "image/png", "image/jpeg", "image/gif" })
public Response downloadCurrentUserAvatarImage() {
if (auth == null) {
return unauthorized();
}
return Response.ok(fetchUserImage(auth.getSession().getRealm(), auth.getUser())).build();
}
@POST
@NoCache
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadCurrentUserAvatarImage(MultipartFormDataInput input, @Context UriInfo uriInfo) {
if (auth == null) {
return unauthorized();
}
if (!isValidStateChecker(input)) {
return invalidState();
}
try {
InputStream imageInputStream = input.getFormDataPart(AVATAR_IMAGE_PARAMETER, InputStream.class, null);
saveUserImage(auth.getSession().getRealm(), auth.getUser(), imageInputStream);
if (uriInfo.getQueryParameters().containsKey("account")) {
return Response.seeOther(
RealmsResource.accountUrl(session.getContext().getUri().getBaseUriBuilder())
.build(auth.getSession().getRealm().getName())).build();
}
return Response.ok().build();
} catch (Exception ex) {
return Response.serverError().build();
}
}
private boolean isValidStateChecker(MultipartFormDataInput input) {
try {
String actualStateChecker = input.getFormDataPart(STATE_CHECKER_PARAMETER, String.class, null);
String requiredStateChecker = (String) session.getAttribute(STATE_CHECKER_ATTRIBUTE);
return Objects.equals(requiredStateChecker, actualStateChecker);
} catch (Exception ex) {
return false;
}
}
}