package org.fenixedu.bennu.core.api; import java.io.IOException; import java.io.InputStream; import java.util.IllformedLocaleException; import java.util.Locale; import java.util.Locale.Builder; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.ws.rs.DefaultValue; import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.HeaderParam; import javax.ws.rs.POST; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.EntityTag; import javax.ws.rs.core.HttpHeaders; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import org.fenixedu.bennu.core.api.json.AuthenticatedUserViewer; import org.fenixedu.bennu.core.domain.Avatar; import org.fenixedu.bennu.core.domain.User; import org.fenixedu.bennu.core.domain.exceptions.AuthorizationException; import org.fenixedu.bennu.core.domain.exceptions.BennuCoreDomainException; import org.fenixedu.bennu.core.groups.Group; import org.fenixedu.bennu.core.i18n.I18NFilter; import org.fenixedu.bennu.core.rest.BennuRestResource; import org.fenixedu.bennu.core.security.Authenticate; import org.fenixedu.bennu.core.util.CoreConfiguration; import pt.ist.fenixframework.Atomic; import pt.ist.fenixframework.Atomic.TxMode; import com.google.gson.JsonElement; @Path("/bennu-core/profile") public class ProfileResource extends BennuRestResource { @GET @Produces(MediaType.APPLICATION_JSON) public JsonElement getProfile() { return view(null, Void.class, AuthenticatedUserViewer.class); } @POST @Path("login") @Produces(MediaType.APPLICATION_JSON) public JsonElement login(@Context HttpServletRequest request, @Context HttpServletResponse response, @FormParam("username") String username, @FormParam("password") String password) { if (CoreConfiguration.getConfiguration().localLoginEnabled()) { User user = User.findByUsername(username); if (user != null && (CoreConfiguration.getConfiguration().developmentMode() || user.matchesPassword(password))) { Authenticate.login(request, response, user); } else { throw AuthorizationException.authenticationFailed(); } return view(null, Void.class, AuthenticatedUserViewer.class); } throw AuthorizationException.authenticationFailed(); } @GET @Path("logout") @Produces(MediaType.APPLICATION_JSON) public JsonElement logout(@Context HttpServletRequest request, @Context HttpServletResponse response) { accessControl(Group.logged()); Authenticate.logout(request, response); return view(null, Void.class, AuthenticatedUserViewer.class); } @POST @Path("locale/{tag}") @Produces(MediaType.APPLICATION_JSON) public JsonElement changeLocale(@Context HttpServletRequest request, @Context HttpServletResponse response, @PathParam("tag") String localeTag) { try { Locale locale = new Builder().setLanguageTag(localeTag).build(); if (CoreConfiguration.supportedLocales().contains(locale)) { I18NFilter.updateLocale(locale, request, response); if (Authenticate.isLogged()) { setPreferredLocale(locale); } return view(null, Void.class, AuthenticatedUserViewer.class); } } catch (IllformedLocaleException e) { } throw BennuCoreDomainException.resourceNotFound(localeTag); } @Atomic(mode = TxMode.WRITE) private void setPreferredLocale(Locale locale) { Authenticate.getUser().getProfile().setPreferredLocale(locale); } @GET @Path("localavatar/{username}") public Response localAvatar(@PathParam("username") String username, @QueryParam("s") @DefaultValue("100") Integer size, @HeaderParam("If-None-Match") String ifNoneMatch) { User user = User.findByUsername(username); if (user != null) { Avatar avatar = Avatar.getForUser(user); EntityTag etag = getEtag(avatar, size); if (etag.toString().equals(ifNoneMatch)) { return Response.notModified(etag).build(); } if (avatar != null) { return Response.ok(avatar.getData(size), avatar.getMimeType()) .header(HttpHeaders.CACHE_CONTROL, CoreConfiguration.getConfiguration().staticCacheControl()).tag(etag) .build(); } else { try (InputStream mm = ProfileResource.class.getClassLoader().getResourceAsStream("META-INF/resources/img/mysteryman.png")) { return Response.ok(Avatar.process(mm, "image/png", size), "image/png") .header(HttpHeaders.CACHE_CONTROL, CoreConfiguration.getConfiguration().staticCacheControl()) .tag(etag).build(); } catch (IOException e) { throw BennuCoreDomainException.resourceNotFound(username); } } } throw BennuCoreDomainException.resourceNotFound(username); } private EntityTag getEtag(Avatar avatar, int size) { return EntityTag.valueOf("W/\"" + (avatar == null ? "mm-av" : avatar.getExternalId()) + "-" + size + "\""); } }