Skip to content

Commit

Permalink
feat: Add Config Option for Custom Gravatar Mirror Sources (OD-2155)
Browse files Browse the repository at this point in the history
  • Loading branch information
robinshine committed Nov 10, 2024
1 parent 9121755 commit fc570fc
Show file tree
Hide file tree
Showing 5 changed files with 79 additions and 63 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,10 @@
import javax.persistence.criteria.Root;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
import java.io.*;
import java.io.File;
import java.io.IOException;
import java.io.ObjectStreamException;
import java.io.Serializable;
import java.lang.reflect.Field;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
Expand All @@ -78,7 +81,9 @@
import java.util.stream.Collectors;

import static com.google.common.base.Throwables.getStackTraceAsString;
import static io.onedev.server.model.User.*;
import static io.onedev.server.model.User.PROP_DISABLE_WATCH_NOTIFICATIONS;
import static io.onedev.server.model.User.PROP_NOTIFY_OWN_EVENTS;
import static io.onedev.server.model.support.administration.SystemSetting.*;
import static io.onedev.server.persistence.PersistenceUtils.tableExists;
import static org.unbescape.html.HtmlEscape.escapeHtml5;

Expand Down Expand Up @@ -686,10 +691,10 @@ public void complete() {
}

if (systemSetting != null) {
Collection<String> excludedProps = Sets.newHashSet("sshRootUrl", "disableAutoUpdateCheck", "gravatarEnabled");
Collection<String> excludedProps = Sets.newHashSet(PROP_SSH_ROOT_URL, PROP_DISABLE_AUTO_UPDATE_CHECK, PROP_USE_AVATAR_SERVICE);
if (Bootstrap.isInDocker()) {
excludedProps.add(SystemSetting.PROP_GIT_LOCATION);
excludedProps.add(SystemSetting.PROP_CURL_LOCATION);
excludedProps.add(PROP_GIT_LOCATION);
excludedProps.add(PROP_CURL_LOCATION);
}
if (ingressUrl != null)
excludedProps.add("serverUrl");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7153,7 +7153,13 @@ private void migrate181(File dataDir, Stack<Integer> versions) {
VersionedXmlDoc dom = VersionedXmlDoc.fromFile(file);
for (Element element : dom.getRootElement().elements()) {
String key = element.elementTextTrim("key");
if (key.equals("SERVICE_DESK_SETTING")) {
if (key.equals("SYSTEM")) {
Element valueElement = element.element("value");
if (valueElement != null) {
valueElement.element("gravatarEnabled").setName("useAvatarService");
valueElement.addElement("avatarServiceUrl").setText("https://secure.gravatar.com/avatar/");
}
} else if (key.equals("SERVICE_DESK_SETTING")) {
Element valueElement = element.element("value");
if (valueElement != null) {
valueElement.element("senderAuthorizations").detach();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,28 @@
package io.onedev.server.model.support.administration;

import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;

import javax.annotation.Nullable;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;

import io.onedev.server.annotation.ShowCondition;
import io.onedev.server.web.util.WicketUtils;
import org.apache.commons.lang3.StringUtils;
import javax.validation.constraints.NotEmpty;

import com.google.common.base.Preconditions;

import io.onedev.server.OneDev;
import io.onedev.server.ServerConfig;
import io.onedev.server.annotation.ClassValidating;
import io.onedev.server.annotation.Editable;
import io.onedev.server.annotation.ShowCondition;
import io.onedev.server.git.location.CurlLocation;
import io.onedev.server.git.location.GitLocation;
import io.onedev.server.git.location.SystemCurl;
import io.onedev.server.git.location.SystemGit;
import io.onedev.server.util.EditContext;
import io.onedev.server.validation.Validatable;
import io.onedev.server.annotation.ClassValidating;
import io.onedev.server.annotation.Editable;
import io.onedev.server.web.util.WicketUtils;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Nullable;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.net.MalformedURLException;
import java.net.URL;

@Editable
@ClassValidating
Expand All @@ -39,6 +36,10 @@ public class SystemSetting implements Serializable, Validatable {

public static final String PROP_SSH_ROOT_URL = "sshRootUrl";

public static final String PROP_USE_AVATAR_SERVICE = "useAvatarService";

public static final String PROP_DISABLE_AUTO_UPDATE_CHECK = "disableAutoUpdateCheck";

private String serverUrl;

private String sshRootUrl;
Expand All @@ -51,7 +52,9 @@ public class SystemSetting implements Serializable, Validatable {

private boolean disableDashboard;

private boolean gravatarEnabled;
private boolean useAvatarService;

private String avatarServiceUrl = "https://secure.gravatar.com/avatar/";

@Editable(name="Server URL", order=90, description="Specify root URL to access this server")
@NotEmpty
Expand Down Expand Up @@ -150,15 +153,30 @@ private static boolean isDisableDashboardEnabled() {
return WicketUtils.isSubscriptionActive();
}

@Editable(order=500, description="Whether or not to enable user gravatar (https://gravatar.com)")
public boolean isGravatarEnabled() {
return gravatarEnabled;
@Editable(order=500, description="Whether or not to use user avatar from a public service")
public boolean isUseAvatarService() {
return useAvatarService;
}

public void setUseAvatarService(boolean useAvatarService) {
this.useAvatarService = useAvatarService;
}

public void setGravatarEnabled(boolean gravatarEnabled) {
this.gravatarEnabled = gravatarEnabled;
@Editable(order=600, description="User avatar will be requested by appending a hash to this url")
@ShowCondition("isUseAvatarServiceEnabled")
@NotEmpty
public String getAvatarServiceUrl() {
return avatarServiceUrl;
}

public void setAvatarServiceUrl(String avatarServiceUrl) {
this.avatarServiceUrl = avatarServiceUrl;
}

private static boolean isUseAvatarServiceEnabled() {
return (boolean) EditContext.get().getInputValue(PROP_USE_AVATAR_SERVICE);
}

public String getEffectiveSshRootUrl() {
if (getSshRootUrl() != null)
return getSshRootUrl();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
package io.onedev.server.web.avatar;

import io.onedev.server.OneDev;
import io.onedev.server.entitymanager.SettingManager;
import org.apache.commons.lang3.StringUtils;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URLDecoder;
Expand All @@ -12,27 +16,16 @@
*
* @author Finn Kuusisto
*/
public class Gravatar {

public static final String PRE = "https://secure.gravatar.com/avatar/";

public class AvatarService {

// default images
public static final int DFLT_DEFAULT = 2;
public static final int DFLT_FOUR_O_FOUR = 0;
public static final int DFLT_MYSTERY_MAN = 1;
public static final int DFLT_IDENTICON = 2;
public static final int DFLT_MONSTERID = 3;
public static final int DFLT_WAVATAR = 4;
public static final int DFLT_RETRO = 5;
public static final int DFLT_BLANK = 6;
private static final String[] dfltImages = { "404", "mm", "identicon",
"monsterid", "wavatar", "retro", "blank" };

// ratings
public static final int RTNG_NONE = -1;
public static final int RTNG_G = 0;
public static final int RTNG_PG = 1;
public static final int RTNG_R = 2;
public static final int RTNG_X = 3;
private static final String[] ratings = { "g", "pg", "r", "x" };

Expand All @@ -50,11 +43,11 @@ public class Gravatar {
* @param email
* the email for this Gravatar
*/
public Gravatar(String email) {
public AvatarService(String email) {
this.email = email;
byte[] buf = email.trim().toLowerCase().getBytes();
try {
this.hash = Gravatar.toHexString(MessageDigest.getInstance("MD5")
this.hash = AvatarService.toHexString(MessageDigest.getInstance("MD5")
.digest(buf));
this.hash = this.hash.toLowerCase();
} catch (NoSuchAlgorithmException e) {
Expand Down Expand Up @@ -192,13 +185,13 @@ public int getRating() {
/**
* Get the URL for this Gravatar, HTTPS if specified.
*
* @param secure
* true if HTTPS is desired
* @return URL for this Gravatar
*/
public String getURL() {
StringBuilder str = new StringBuilder();
str.append(PRE);
var str = new StringBuilder();
var url = OneDev.getInstance(SettingManager.class).getSystemSetting().getAvatarServiceUrl();
str.append(StringUtils.stripEnd(url, "/\\")).append("/");
str.append(this.hash);
str.append(this.getOptions());
return str.toString();
Expand Down Expand Up @@ -255,7 +248,7 @@ private String getOptions() {
* @return the URL of the Gravatar
*/
public static String getURL(String email) {
return Gravatar.getURL(email, 0, DFLT_DEFAULT, false, RTNG_NONE);
return AvatarService.getURL(email, 0, DFLT_DEFAULT, false, RTNG_NONE);
}

/**
Expand All @@ -268,7 +261,7 @@ public static String getURL(String email) {
* @return the URL of the Gravatar
*/
public static String getURL(String email, int size) {
return Gravatar.getURL(email, size, DFLT_DEFAULT);
return AvatarService.getURL(email, size, DFLT_DEFAULT);
}

/**
Expand All @@ -283,7 +276,7 @@ public static String getURL(String email, int size) {
* @return the URL of the Gravatar
*/
public static String getURL(String email, int size, int dflt) {
return Gravatar.getURL(email, size, dflt, RTNG_NONE);
return AvatarService.getURL(email, size, dflt, RTNG_NONE);
}

/**
Expand All @@ -301,7 +294,7 @@ public static String getURL(String email, int size, int dflt) {
* @return the URL of the Gravatar
*/
public static String getURL(String email, int size, int dflt, int rating) {
return Gravatar.getURL(email, size, dflt, false, rating);
return AvatarService.getURL(email, size, dflt, false, rating);
}

/**
Expand All @@ -312,19 +305,15 @@ public static String getURL(String email, int size, int dflt, int rating) {
* the email for this Gravatar
* @param size
* the desired size for this Gravatar [1-512]
* @param customDefault
* URL of custom default image
* @param forceDefault
* true if the default should always be returned
* @param rating
* must be one of the RTNG_XXX constants
* @param secure
* true if HTTPS desired
* @return the URL of the Gravatar
*/
public static String getURL(String email, int size, int dflt,
boolean forceDefault, int rating) {
Gravatar g = new Gravatar(email);
AvatarService g = new AvatarService(email);
g.setSize(size);
g.setDefault(dflt);
g.setForceDefault(forceDefault);
Expand All @@ -346,13 +335,11 @@ public static String getURL(String email, int size, int dflt,
* true if the default should always be returned
* @param rating
* must be one of the RTNG_XXX constants
* @param secure
* true if HTTPS desired
* @return the URL of the Gravatar
*/
public static String getURL(String email, int size, String customDefault,
boolean forceDefault, int rating) {
Gravatar g = new Gravatar(email);
AvatarService g = new AvatarService(email);
g.setSize(size);
g.setCustomDefault(customDefault);
g.setForceDefault(forceDefault);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ public String getUserAvatarUrl(Long userId) {
UserFacade user = userManager.findFacadeById(userId);
if (emailAddress == null || !emailAddress.isVerified())
return generateAvatar(user.getName(), null);
else if (settingManager.getSystemSetting().isGravatarEnabled())
return Gravatar.getURL(emailAddress.getValue(), GRAVATAR_SIZE);
else if (settingManager.getSystemSetting().isUseAvatarService())
return AvatarService.getURL(emailAddress.getValue(), GRAVATAR_SIZE);
else
return generateAvatar(user.getName(), emailAddress.getValue());
}
Expand All @@ -91,9 +91,9 @@ public String getPersonAvatarUrl(PersonIdent personIdent) {
EmailAddressFacade emailAddress = emailAddressManager.findFacadeByValue(personIdent.getEmailAddress());
if (emailAddress != null && emailAddress.isVerified()) {
return getUserAvatarUrl(emailAddress.getOwnerId());
} else if (settingManager.getSystemSetting().isGravatarEnabled()
} else if (settingManager.getSystemSetting().isUseAvatarService()
&& StringUtils.isNotBlank(personIdent.getEmailAddress())) {
return Gravatar.getURL(personIdent.getEmailAddress(), GRAVATAR_SIZE);
return AvatarService.getURL(personIdent.getEmailAddress(), GRAVATAR_SIZE);
} else {
return generateAvatar(personIdent.getName(), personIdent.getEmailAddress());
}
Expand Down

0 comments on commit fc570fc

Please sign in to comment.