package org.fenixedu.bennu.core.api.json; import java.util.Locale; import java.util.Objects; import org.fenixedu.bennu.core.annotation.DefaultJsonAdapter; import org.fenixedu.bennu.core.domain.Avatar; import org.fenixedu.bennu.core.domain.User; import org.fenixedu.bennu.core.domain.UserProfile; import org.fenixedu.bennu.core.domain.exceptions.BennuCoreDomainException; import org.fenixedu.bennu.core.json.JsonAdapter; import org.fenixedu.bennu.core.json.JsonBuilder; import org.fenixedu.bennu.core.json.JsonUtils; import org.joda.time.format.ISODateTimeFormat; import pt.ist.fenixframework.FenixFramework; import com.google.common.base.Strings; import com.google.common.io.BaseEncoding; import com.google.gson.JsonElement; import com.google.gson.JsonObject; @DefaultJsonAdapter(User.class) public class UserJsonAdapter implements JsonAdapter<User> { @Override public JsonElement view(User user, JsonBuilder ctx) { JsonObject jsonObject = new JsonObject(); UserProfile profile = user.getProfile(); jsonObject.addProperty("id", user.getExternalId()); jsonObject.addProperty("username", user.getUsername()); jsonObject.addProperty("name", profile.getFullName()); jsonObject.addProperty("displayName", user.getDisplayName()); jsonObject.addProperty("givenNames", profile.getGivenNames()); jsonObject.addProperty("familyNames", profile.getFamilyNames()); JsonUtils.put(jsonObject, "email", user.getEmail()); jsonObject.addProperty("active", !user.isLoginExpired()); user.getExpiration().ifPresent(e -> jsonObject.addProperty("expiration", ISODateTimeFormat.date().print(e))); JsonUtils.put(jsonObject, "avatar", profile.getAvatarUrl()); if (profile.getPreferredLocale() != null) { jsonObject.add("preferredLocale", ctx.view(profile.getPreferredLocale())); } return jsonObject; } @Override public User create(JsonElement json, JsonBuilder ctx) { JsonObject object = json.getAsJsonObject(); User user = new User(parseAndUpdateOrCreateProfile(object, ctx, null)); changePassword(user, object); changeAvatar(user.getProfile(), object); changeExpiration(user, object); return user; } @Override public User update(JsonElement json, User obj, JsonBuilder ctx) { JsonObject object = json.getAsJsonObject(); User user; if (object.has("id")) { user = FenixFramework.getDomainObject(object.get("id").getAsString()); } else if (object.has("username")) { user = User.findByUsername(object.get("username").getAsString()); if (user == null) { return null; } } else { return null; } parseAndUpdateOrCreateProfile(object, ctx, user.getProfile()); changePassword(user, object); changeAvatar(user.getProfile(), object); changeExpiration(user, object); return user; } private void changeExpiration(User user, JsonObject json) { String expiration = JsonUtils.getString(json, "expiration"); if (Strings.isNullOrEmpty(expiration)) { user.openLoginPeriod(); } else { user.closeLoginPeriod(ISODateTimeFormat.date().parseLocalDate(expiration)); } } private UserProfile parseAndUpdateOrCreateProfile(JsonObject json, JsonBuilder ctx, UserProfile current) { String given = JsonUtils.getString(json, "givenNames"); String family = JsonUtils.getString(json, "familyNames"); String display = JsonUtils.getString(json, "displayName"); String email = JsonUtils.getString(json, "email"); Locale preferredLocale = JsonUtils.get(json, "preferredLocale", ctx, Locale.class); if (current != null) { current.changeName(given, family, display); current.setEmail(email); current.setPreferredLocale(preferredLocale); changeAvatar(current, json); return current; } return new UserProfile(given, family, display, email, preferredLocale); } private void changePassword(User user, JsonObject json) { String password = JsonUtils.getString(json, "password"); if (Strings.isNullOrEmpty(password)) { // Don't change the password. return; } String passwordCheck = JsonUtils.getString(json, "passwordCheck"); if (!Objects.equals(password, passwordCheck)) { throw BennuCoreDomainException.passwordCheckDoesNotMatch(); } //avoid same password if (user.matchesPassword(password)) { throw BennuCoreDomainException.passwordIsTheSame(); } user.changePassword(password); } private void changeAvatar(UserProfile profile, JsonObject json) { if (json.has("avatar")) { if (json.get("avatar").isJsonPrimitive()) { profile.setAvatarUrl(json.get("avatar").getAsString()); } else { JsonObject obj = json.get("avatar").getAsJsonObject(); byte[] img = BaseEncoding.base64().decode(JsonUtils.getString(obj, "img")); String mimeType = JsonUtils.getString(obj, "mimeType"); if (obj.has("x1")) { int x1 = JsonUtils.getInt(obj, "x1"); int y1 = JsonUtils.getInt(obj, "y1"); int x2 = JsonUtils.getInt(obj, "x2"); int y2 = JsonUtils.getInt(obj, "y2"); profile.setLocalAvatar(Avatar.crop(img, mimeType, x1, y1, x2, y2)); } else { profile.setLocalAvatar(Avatar.create(img, mimeType)); } } } else { profile.setAvatarUrl(null); } } }