2020-08-13 16:27:32 +02:00
|
|
|
package org.gcube.keycloak.avatar;
|
|
|
|
|
|
|
|
import java.io.InputStream;
|
|
|
|
import java.util.Objects;
|
|
|
|
|
|
|
|
import javax.ws.rs.Consumes;
|
2020-08-21 11:12:17 +02:00
|
|
|
import javax.ws.rs.ForbiddenException;
|
2020-08-13 16:27:32 +02:00
|
|
|
import javax.ws.rs.GET;
|
2020-08-21 11:12:17 +02:00
|
|
|
import javax.ws.rs.NotAuthorizedException;
|
2020-08-13 16:27:32 +02:00
|
|
|
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.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";
|
|
|
|
|
|
|
|
public AvatarResource(KeycloakSession session) {
|
|
|
|
super(session);
|
|
|
|
}
|
|
|
|
|
|
|
|
@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) {
|
2020-08-21 11:12:17 +02:00
|
|
|
logger.debug("Unhautorized call to get avatar");
|
|
|
|
throw new NotAuthorizedException("Bearer");
|
2020-08-13 16:27:32 +02:00
|
|
|
}
|
2020-08-21 11:12:17 +02:00
|
|
|
logger.debugf("Getting avatar for user %s in realm %s", auth.getUser(), auth.getSession().getRealm());
|
2020-11-16 23:32:11 +01:00
|
|
|
return fetchAndCreateResponse(auth.getSession().getRealm(), auth.getUser());
|
2020-08-13 16:27:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@POST
|
|
|
|
@NoCache
|
|
|
|
@Consumes(MediaType.MULTIPART_FORM_DATA)
|
|
|
|
public Response uploadCurrentUserAvatarImage(MultipartFormDataInput input, @Context UriInfo uriInfo) {
|
|
|
|
if (auth == null) {
|
2020-08-21 11:12:17 +02:00
|
|
|
throw new NotAuthorizedException("Bearer");
|
2020-08-13 16:27:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!isValidStateChecker(input)) {
|
2020-08-21 11:12:17 +02:00
|
|
|
throw new ForbiddenException("State");
|
2020-08-13 16:27:32 +02:00
|
|
|
}
|
|
|
|
|
2020-08-21 11:12:17 +02:00
|
|
|
logger.debugf("Uploading new avatar for user %s in realm %s", auth.getUser(), auth.getSession().getRealm());
|
2020-08-13 16:27:32 +02:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|