summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/config-accounts.txt9
-rw-r--r--java/com/google/gerrit/server/account/externalids/ExternalId.java9
-rw-r--r--java/com/google/gerrit/server/auth/openid/OpenIdRealm.java49
-rw-r--r--java/com/google/gerrit/server/config/AuthModule.java9
-rw-r--r--javatests/com/google/gerrit/server/auth/ldap/LdapRealmTest.java6
-rw-r--r--javatests/com/google/gerrit/server/auth/oauth/OAuthRealmTest.java6
-rw-r--r--javatests/com/google/gerrit/server/auth/openid/OpenIdRealmTest.java93
7 files changed, 179 insertions, 2 deletions
diff --git a/Documentation/config-accounts.txt b/Documentation/config-accounts.txt
index b4a5ceffba..67159f45b3 100644
--- a/Documentation/config-accounts.txt
+++ b/Documentation/config-accounts.txt
@@ -359,6 +359,15 @@ branch. However Gerrit rejects pushes if:
* hashed passwords of external IDs with scheme `username` cannot be
decoded
+Users can edit some external IDs via the user settings page or the
+REST API. Note that email addresses cannot be deleted if they are
+associated with the user's login credentials external ID, for
+example the email address associated with an OpenId or OAUTH external
+ID. If users wish to remove these email addresses from Gerrit they must
+first update the external authentication record in that system,
+log in to Gerrit, then Gerrit will update the external ID record with
+the new email address.
+
[[starred-changes]]
== Starred Changes
diff --git a/java/com/google/gerrit/server/account/externalids/ExternalId.java b/java/com/google/gerrit/server/account/externalids/ExternalId.java
index 2d501ad37f..1d31da9eef 100644
--- a/java/com/google/gerrit/server/account/externalids/ExternalId.java
+++ b/java/com/google/gerrit/server/account/externalids/ExternalId.java
@@ -136,6 +136,15 @@ public abstract class ExternalId implements Serializable {
/** Scheme for external auth used during authentication, e.g. OAuth Token */
public static final String SCHEME_EXTERNAL = "external";
+ /** Scheme for http resources. OpenID in particular makes use of these external IDs. */
+ public static final String SCHEME_HTTP = "http";
+
+ /** Scheme for https resources. OpenID in particular makes use of these external IDs. */
+ public static final String SCHEME_HTTPS = "https";
+
+ /** Scheme for xri resources. OpenID in particular makes use of these external IDs. */
+ public static final String SCHEME_XRI = "xri";
+
@AutoValue
public abstract static class Key implements Serializable {
private static final long serialVersionUID = 1L;
diff --git a/java/com/google/gerrit/server/auth/openid/OpenIdRealm.java b/java/com/google/gerrit/server/auth/openid/OpenIdRealm.java
new file mode 100644
index 0000000000..4e1a1cec37
--- /dev/null
+++ b/java/com/google/gerrit/server/auth/openid/OpenIdRealm.java
@@ -0,0 +1,49 @@
+// Copyright (C) 2021 Open Infrastructure Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.auth.openid;
+
+import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_HTTP;
+import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_HTTPS;
+import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_XRI;
+
+import com.google.common.annotations.VisibleForTesting;
+import com.google.gerrit.server.account.DefaultRealm;
+import com.google.gerrit.server.account.EmailExpander;
+import com.google.gerrit.server.account.Emails;
+import com.google.gerrit.server.account.externalids.ExternalId;
+import com.google.gerrit.server.config.AuthConfig;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+import java.util.Collection;
+
+@Singleton
+public class OpenIdRealm extends DefaultRealm {
+ @Inject
+ @VisibleForTesting
+ public OpenIdRealm(EmailExpander emailExpander, Provider<Emails> emails, AuthConfig authConfig) {
+ super(emailExpander, emails, authConfig);
+ }
+
+ @Override
+ public boolean accountBelongsToRealm(Collection<ExternalId> externalIds) {
+ for (ExternalId id : externalIds) {
+ if (id.isScheme(SCHEME_HTTP) || id.isScheme(SCHEME_HTTPS) || id.isScheme(SCHEME_XRI)) {
+ return true;
+ }
+ }
+ return false;
+ }
+}
diff --git a/java/com/google/gerrit/server/config/AuthModule.java b/java/com/google/gerrit/server/config/AuthModule.java
index 5b0f73d6c2..56f2e2aee3 100644
--- a/java/com/google/gerrit/server/config/AuthModule.java
+++ b/java/com/google/gerrit/server/config/AuthModule.java
@@ -22,6 +22,7 @@ import com.google.gerrit.server.auth.AuthBackend;
import com.google.gerrit.server.auth.InternalAuthBackend;
import com.google.gerrit.server.auth.ldap.LdapModule;
import com.google.gerrit.server.auth.oauth.OAuthRealm;
+import com.google.gerrit.server.auth.openid.OpenIdRealm;
import com.google.inject.AbstractModule;
import com.google.inject.Inject;
@@ -50,10 +51,14 @@ public class AuthModule extends AbstractModule {
case CUSTOM_EXTENSION:
break;
- case DEVELOPMENT_BECOME_ANY_ACCOUNT:
- case HTTP:
case OPENID:
case OPENID_SSO:
+ bind(Realm.class).to(OpenIdRealm.class);
+ DynamicSet.bind(binder(), AuthBackend.class).to(InternalAuthBackend.class);
+ break;
+
+ case DEVELOPMENT_BECOME_ANY_ACCOUNT:
+ case HTTP:
default:
bind(Realm.class).to(DefaultRealm.class);
DynamicSet.bind(binder(), AuthBackend.class).to(InternalAuthBackend.class);
diff --git a/javatests/com/google/gerrit/server/auth/ldap/LdapRealmTest.java b/javatests/com/google/gerrit/server/auth/ldap/LdapRealmTest.java
index ba40d8c211..042222fdc3 100644
--- a/javatests/com/google/gerrit/server/auth/ldap/LdapRealmTest.java
+++ b/javatests/com/google/gerrit/server/auth/ldap/LdapRealmTest.java
@@ -16,8 +16,11 @@ package com.google.gerrit.server.auth.ldap;
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_GERRIT;
+import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_HTTP;
+import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_HTTPS;
import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_MAILTO;
import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_USERNAME;
+import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_XRI;
import static com.google.gerrit.server.auth.ldap.LdapModule.GROUP_CACHE;
import static com.google.gerrit.server.auth.ldap.LdapModule.GROUP_EXIST_CACHE;
import static com.google.gerrit.server.auth.ldap.LdapModule.PARENT_GROUPS_CACHE;
@@ -90,5 +93,8 @@ public final class LdapRealmTest {
assertThat(accountBelongsToRealm(SCHEME_USERNAME, "xxgerritxx")).isFalse();
assertThat(accountBelongsToRealm(SCHEME_MAILTO, "gerrit.foo@bar.com")).isFalse();
assertThat(accountBelongsToRealm(SCHEME_MAILTO, "bar.gerrit@bar.com")).isFalse();
+ assertThat(accountBelongsToRealm(SCHEME_HTTP, "example.org/test")).isFalse();
+ assertThat(accountBelongsToRealm(SCHEME_HTTPS, "example.org/test")).isFalse();
+ assertThat(accountBelongsToRealm(SCHEME_XRI, "example.org/test")).isFalse();
}
}
diff --git a/javatests/com/google/gerrit/server/auth/oauth/OAuthRealmTest.java b/javatests/com/google/gerrit/server/auth/oauth/OAuthRealmTest.java
index dc62a61017..8f7cc35b24 100644
--- a/javatests/com/google/gerrit/server/auth/oauth/OAuthRealmTest.java
+++ b/javatests/com/google/gerrit/server/auth/oauth/OAuthRealmTest.java
@@ -16,8 +16,11 @@ package com.google.gerrit.server.auth.oauth;
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_EXTERNAL;
+import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_HTTP;
+import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_HTTPS;
import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_MAILTO;
import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_USERNAME;
+import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_XRI;
import com.google.gerrit.entities.Account;
import com.google.gerrit.server.account.externalids.ExternalId;
@@ -65,5 +68,8 @@ public final class OAuthRealmTest {
assertThat(accountBelongsToRealm(SCHEME_USERNAME, "xxexternalxx")).isFalse();
assertThat(accountBelongsToRealm(SCHEME_MAILTO, "external.foo@bar.com")).isFalse();
assertThat(accountBelongsToRealm(SCHEME_MAILTO, "bar.external@bar.com")).isFalse();
+ assertThat(accountBelongsToRealm(SCHEME_HTTP, "example.org/test")).isFalse();
+ assertThat(accountBelongsToRealm(SCHEME_HTTPS, "example.org/test")).isFalse();
+ assertThat(accountBelongsToRealm(SCHEME_XRI, "example.org/test")).isFalse();
}
}
diff --git a/javatests/com/google/gerrit/server/auth/openid/OpenIdRealmTest.java b/javatests/com/google/gerrit/server/auth/openid/OpenIdRealmTest.java
new file mode 100644
index 0000000000..f5373add86
--- /dev/null
+++ b/javatests/com/google/gerrit/server/auth/openid/OpenIdRealmTest.java
@@ -0,0 +1,93 @@
+// Copyright (C) 2021 Open Infrastructure Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.auth.openid;
+
+import static com.google.common.truth.Truth.assertThat;
+import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_EXTERNAL;
+import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_GERRIT;
+import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_HTTP;
+import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_HTTPS;
+import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_MAILTO;
+import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_USERNAME;
+import static com.google.gerrit.server.account.externalids.ExternalId.SCHEME_XRI;
+
+import com.google.gerrit.entities.Account;
+import com.google.gerrit.server.account.externalids.ExternalId;
+import com.google.gerrit.testing.InMemoryModule;
+import com.google.inject.Guice;
+import com.google.inject.Inject;
+import com.google.inject.Injector;
+import java.util.Arrays;
+import org.junit.Before;
+import org.junit.Test;
+
+public final class OpenIdRealmTest {
+ @Inject private OpenIdRealm openidRealm = null;
+
+ @Before
+ public void setUpInjector() throws Exception {
+ Injector injector = Guice.createInjector(new InMemoryModule());
+ injector.injectMembers(this);
+ }
+
+ private ExternalId id(String scheme, String id) {
+ return ExternalId.create(scheme, id, Account.id(1000));
+ }
+
+ private boolean accountBelongsToRealm(ExternalId... ids) {
+ return openidRealm.accountBelongsToRealm(Arrays.asList(ids));
+ }
+
+ private boolean accountBelongsToRealm(String scheme, String id) {
+ return accountBelongsToRealm(id(scheme, id));
+ }
+
+ @Test
+ public void accountBelongsToRealm() throws Exception {
+ assertThat(accountBelongsToRealm(SCHEME_HTTP, "example.org/test")).isTrue();
+ assertThat(accountBelongsToRealm(SCHEME_HTTPS, "example.org/test")).isTrue();
+ assertThat(accountBelongsToRealm(SCHEME_XRI, "example.org/test")).isTrue();
+ assertThat(
+ accountBelongsToRealm(id(SCHEME_USERNAME, "test"), id(SCHEME_HTTP, "example.org/test")))
+ .isTrue();
+ assertThat(
+ accountBelongsToRealm(
+ id(SCHEME_USERNAME, "test"), id(SCHEME_HTTPS, "example.org/test")))
+ .isTrue();
+ assertThat(
+ accountBelongsToRealm(id(SCHEME_USERNAME, "test"), id(SCHEME_XRI, "example.org/test")))
+ .isTrue();
+ assertThat(
+ accountBelongsToRealm(id(SCHEME_HTTP, "example.org/test"), id(SCHEME_USERNAME, "test")))
+ .isTrue();
+ assertThat(
+ accountBelongsToRealm(
+ id(SCHEME_HTTPS, "example.org/test"), id(SCHEME_USERNAME, "test")))
+ .isTrue();
+ assertThat(
+ accountBelongsToRealm(id(SCHEME_XRI, "test"), id(SCHEME_USERNAME, "example.org/test")))
+ .isTrue();
+
+ assertThat(accountBelongsToRealm(SCHEME_EXTERNAL, "test")).isFalse();
+ assertThat(accountBelongsToRealm(SCHEME_GERRIT, "test")).isFalse();
+ assertThat(accountBelongsToRealm(SCHEME_USERNAME, "test")).isFalse();
+ assertThat(accountBelongsToRealm(SCHEME_MAILTO, "foo@bar.com")).isFalse();
+
+ assertThat(accountBelongsToRealm(SCHEME_USERNAME, "gerrit")).isFalse();
+ assertThat(accountBelongsToRealm(SCHEME_USERNAME, "xxgerritxx")).isFalse();
+ assertThat(accountBelongsToRealm(SCHEME_MAILTO, "gerrit.foo@bar.com")).isFalse();
+ assertThat(accountBelongsToRealm(SCHEME_MAILTO, "bar.gerrit@bar.com")).isFalse();
+ }
+}