Merge branch 'stable-3.4'
* stable-3.4:
Add missing copyright header to SamlWebFilterIT.java
Remove httpDisplaynameHeader config option
Support display names with non-ISO-8859-1 characters
Change-Id: I80f3619e05364f9bc2eef1df2194e98596b219f3
diff --git a/BUILD b/BUILD
index 00a847d..36550aa 100644
--- a/BUILD
+++ b/BUILD
@@ -10,6 +10,7 @@
resources = glob(["src/main/resources/**"]),
deps = [
"@commons-collections//jar",
+ "@commons-lang//jar",
"@cryptacular//jar",
"@joda-time//jar",
"@opensaml-core//jar",
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl
index 59f0529..16b7dad 100644
--- a/external_plugin_deps.bzl
+++ b/external_plugin_deps.bzl
@@ -15,6 +15,12 @@
)
maven_jar(
+ name = "commons-lang",
+ artifact = "commons-lang:commons-lang:2.6",
+ sha1 = "0ce1edb914c94ebc388f086c6827e8bdeec71ac2",
+ )
+
+ maven_jar(
name = "cryptacular",
artifact = "org.cryptacular:cryptacular:1.2.1",
sha1 = "c470bac7309ac04b0b9529bd7dcb1e0b75954f11",
diff --git a/simplesamlphp/README.md b/simplesamlphp/README.md
index 44646f4..3f15824 100644
--- a/simplesamlphp/README.md
+++ b/simplesamlphp/README.md
@@ -43,7 +43,6 @@
type = HTTP
logoutUrl = http://localhost:8080/simplesaml/saml2/idp/SingleLogoutService.php?ReturnTo=http://localhost:8081
httpHeader = X-SAML-UserName
- httpDisplaynameHeader = X-SAML-DisplayName
httpEmailHeader = X-SAML-EmailHeader
httpExternalIdHeader = X-SAML-ExternalId
autoUpdateAccountActiveStatus = true
diff --git a/src/main/java/com/googlesource/gerrit/plugins/saml/SamlMembership.java b/src/main/java/com/googlesource/gerrit/plugins/saml/SamlMembership.java
index 06940dc..7b91f1e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/saml/SamlMembership.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/saml/SamlMembership.java
@@ -24,9 +24,9 @@
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.ServerInitiated;
import com.google.gerrit.server.account.*;
+import com.google.gerrit.server.group.db.GroupDelta;
import com.google.gerrit.server.group.db.GroupsUpdate;
import com.google.gerrit.server.group.db.InternalGroupCreation;
-import com.google.gerrit.server.group.db.InternalGroupUpdate;
import com.google.gerrit.server.notedb.Sequences;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -56,6 +56,7 @@
private final IdentifiedUser.GenericFactory userFactory;
private final Provider<GroupsUpdate> groupsUpdateProvider;
private final Sequences sequences;
+ private final AuthRequest.Factory authRequestFactory;
@Inject
SamlMembership(
@@ -65,7 +66,8 @@
GroupCache groupCache,
IdentifiedUser.GenericFactory userFactory,
@ServerInitiated Provider<GroupsUpdate> groupsUpdateProvider,
- Sequences sequences) {
+ Sequences sequences,
+ AuthRequest.Factory authRequestFactory) {
this.memberAttr = samlConfig.getMemberOfAttr();
this.serverIdent = serverIdent;
this.accountManager = accountManager;
@@ -73,6 +75,7 @@
this.userFactory = userFactory;
this.groupsUpdateProvider = groupsUpdateProvider;
this.sequences = sequences;
+ this.authRequestFactory = authRequestFactory;
}
/**
@@ -84,7 +87,8 @@
public void sync(AuthenticatedUser user, SAML2Profile profile) throws IOException {
Set<AccountGroup.UUID> samlMembership =
Optional.ofNullable((List<?>) profile.getAttribute(memberAttr, List.class))
- .orElse(Collections.emptyList()).stream()
+ .orElse(Collections.emptyList())
+ .stream()
.map(m -> getOrCreateGroup(m.toString()))
.filter(Optional::isPresent)
.map(Optional::get)
@@ -130,9 +134,8 @@
}
private void updateMembers(
- AccountGroup.UUID group, InternalGroupUpdate.MemberModification memberModification) {
- InternalGroupUpdate update =
- InternalGroupUpdate.builder().setMemberModification(memberModification).build();
+ AccountGroup.UUID group, GroupDelta.MemberModification memberModification) {
+ GroupDelta update = GroupDelta.builder().setMemberModification(memberModification).build();
try {
groupsUpdateProvider.get().updateGroup(group, update);
} catch (Exception e) {
@@ -156,8 +159,8 @@
.setNameKey(name)
.setId(groupId)
.build();
- InternalGroupUpdate.Builder groupUpdateBuilder =
- InternalGroupUpdate.builder()
+ GroupDelta.Builder groupUpdateBuilder =
+ GroupDelta.builder()
.setVisibleToAll(false)
.setDescription(samlGroup + " (imported by the SAML plugin)");
return groupsUpdateProvider.get().createGroup(groupCreation, groupUpdateBuilder.build());
@@ -174,7 +177,7 @@
}
private Account.Id getOrCreateAccountId(AuthenticatedUser user) throws IOException {
- AuthRequest authRequest = AuthRequest.forUser(user.getUsername());
+ AuthRequest authRequest = authRequestFactory.createForUser(user.getUsername());
authRequest.setUserName(user.getUsername());
authRequest.setEmailAddress(user.getEmail());
authRequest.setDisplayName(user.getDisplayName());
diff --git a/src/main/java/com/googlesource/gerrit/plugins/saml/SamlWebFilter.java b/src/main/java/com/googlesource/gerrit/plugins/saml/SamlWebFilter.java
index db129f9..5714315 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/saml/SamlWebFilter.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/saml/SamlWebFilter.java
@@ -14,16 +14,20 @@
package com.googlesource.gerrit.plugins.saml;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Strings;
import com.google.common.collect.Iterators;
import com.google.common.collect.Sets;
+import com.google.gerrit.common.Nullable;
import com.google.gerrit.entities.Account;
import com.google.gerrit.extensions.api.GerritApi;
import com.google.gerrit.extensions.api.accounts.Accounts;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.Url;
-import com.google.gerrit.server.config.GerritServerConfig;
+import com.google.gerrit.server.config.AuthConfig;
+import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.util.ManualRequestContext;
import com.google.gerrit.server.util.OneOffRequestContext;
@@ -49,7 +53,6 @@
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
-import org.eclipse.jgit.lib.Config;
import org.pac4j.core.context.J2EContext;
import org.pac4j.core.context.session.SessionStore;
import org.pac4j.core.exception.HttpAction;
@@ -74,12 +77,8 @@
private final SAML2Client saml2Client;
private final SamlConfig samlConfig;
- private final String httpUserNameHeader;
- private final String httpDisplaynameHeader;
- private final String httpEmailHeader;
- private final String httpExternalIdHeader;
+ private final AuthConfig auth;
private final HashSet<String> authHeaders;
- private final boolean userNameToLowerCase;
private final SamlMembership samlMembership;
private final GerritApi gApi;
private final Accounts accounts;
@@ -87,7 +86,8 @@
@Inject
SamlWebFilter(
- @GerritServerConfig Config gerritConfig,
+ AuthConfig auth,
+ @CanonicalWebUrl @Nullable String canonicalUrl,
SitePaths sitePaths,
SamlConfig samlConfig,
SamlMembership samlMembership,
@@ -95,6 +95,7 @@
Accounts accounts,
OneOffRequestContext oneOffRequestContext)
throws IOException {
+ this.auth = auth;
this.samlConfig = samlConfig;
this.samlMembership = samlMembership;
log.debug("Max Authentication Lifetime: " + samlConfig.getMaxAuthLifetimeAttr());
@@ -121,12 +122,11 @@
samlClientConfig.setMaximumAuthenticationLifetime(samlConfig.getMaxAuthLifetimeAttr());
saml2Client = new SAML2Client(samlClientConfig);
- String callbackUrl = gerritConfig.getString("gerrit", null, "canonicalWebUrl") + SAML_CALLBACK;
- httpUserNameHeader = getHeaderFromConfig(gerritConfig, "httpHeader");
- httpDisplaynameHeader = getHeaderFromConfig(gerritConfig, "httpDisplaynameHeader");
- httpEmailHeader = getHeaderFromConfig(gerritConfig, "httpEmailHeader");
- httpExternalIdHeader = getHeaderFromConfig(gerritConfig, "httpExternalIdHeader");
- authHeaders = Sets.newHashSet(httpUserNameHeader, httpEmailHeader, httpExternalIdHeader);
+ authHeaders =
+ Sets.newHashSet(
+ auth.getLoginHttpHeader().toUpperCase(),
+ auth.getHttpEmailHeader().toUpperCase(),
+ auth.getHttpExternalIdHeader().toUpperCase());
if (authHeaders.contains("") || authHeaders.contains(null)) {
throw new RuntimeException("All authentication headers must be set.");
}
@@ -135,9 +135,8 @@
"Unique values for httpUserNameHeader, "
+ "httpEmailHeader and httpExternalIdHeader are required.");
}
- userNameToLowerCase = gerritConfig.getBoolean("auth", "userNameToLowerCase", false);
-
- saml2Client.setCallbackUrl(callbackUrl);
+ checkNotNull(canonicalUrl, "gerrit.canonicalWebUrl must be set in gerrit.config");
+ saml2Client.setCallbackUrl(canonicalUrl + SAML_CALLBACK);
this.gApi = gApi;
this.accounts = accounts;
@@ -245,11 +244,6 @@
saml2Client.redirect(context);
}
- private static String getHeaderFromConfig(Config gerritConfig, String name) {
- String s = gerritConfig.getString("auth", null, name);
- return s == null ? "" : s.toUpperCase();
- }
-
private static boolean isGerritLogin(HttpServletRequest request) {
return request.getRequestURI().indexOf(GERRIT_LOGIN) >= 0;
}
@@ -320,7 +314,7 @@
private String getUserName(SAML2Profile user) {
String username = getAttributeOrElseId(user, samlConfig.getUserNameAttr());
- return userNameToLowerCase ? username.toLowerCase(Locale.US) : username;
+ return auth.isUserNameToLowerCase() ? username.toLowerCase(Locale.US) : username;
}
private static Path ensureExists(Path dataDir) throws IOException {
@@ -348,11 +342,11 @@
@Override
public String getHeader(String name) {
String nameUpperCase = name.toUpperCase();
- if (httpUserNameHeader.equals(nameUpperCase)) {
+ if (auth.getLoginHttpHeader().toUpperCase().equals(nameUpperCase)) {
return user.getUsername();
- } else if (httpEmailHeader.equals(nameUpperCase)) {
+ } else if (auth.getHttpEmailHeader().toUpperCase().equals(nameUpperCase)) {
return user.getEmail();
- } else if (httpExternalIdHeader.equals(nameUpperCase)) {
+ } else if (auth.getHttpExternalIdHeader().toUpperCase().equals(nameUpperCase)) {
return user.getExternalId();
} else {
return super.getHeader(name);