Auth: check the ability to authenticate users Make sure that users can be successfully authenticated by Gerrit and are able to login. Feature: Issue 10409 Change-Id: Icbe92bcbec2c765cdd55efbc8b00499dcc7f4484
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckConfig.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckConfig.java index 98df366..5e1c7ea 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckConfig.java +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckConfig.java
@@ -38,6 +38,8 @@ private static final long HEALTHCHECK_TIMEOUT_DEFAULT = 500L; private static final String QUERY_DEFAULT = "status:open"; private static final int LIMIT_DEFAULT = 10; + private static final String USERNAME_DEFAULT = "healthcheck"; + private static final String PASSWORD_DEFAULT = ""; private final AllProjectsName allProjectsName; private final AllUsersName allUsersName; @@ -79,9 +81,7 @@ } public String getQuery(String healthCheckName) { - String defaultQuery = healthCheckName == null ? QUERY_DEFAULT : getQuery(null); - return MoreObjects.firstNonNull( - config.getString(HEALTHCHECK, healthCheckName, "query"), defaultQuery); + return getStringWithFallback("query", healthCheckName, QUERY_DEFAULT); } public int getLimit(String healthCheckName) { @@ -98,4 +98,22 @@ repos.add(allUsersName); return repos; } + + public String getUsername(String healthCheckName) { + return getStringWithFallback("userame", healthCheckName, USERNAME_DEFAULT); + } + + public String getPassword(String healthCheckName) { + return getStringWithFallback("password", healthCheckName, PASSWORD_DEFAULT); + } + + private String getStringWithFallback( + String parameter, String healthCheckName, String defaultValue) { + String fallbackDefault = + healthCheckName == null + ? defaultValue + : getStringWithFallback(parameter, null, defaultValue); + return MoreObjects.firstNonNull( + config.getString(HEALTHCHECK, healthCheckName, parameter), fallbackDefault); + } }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckSubsystemsModule.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckSubsystemsModule.java index ab2ad91..6426fa1 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckSubsystemsModule.java +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckSubsystemsModule.java
@@ -17,6 +17,7 @@ import com.google.gerrit.extensions.events.LifecycleListener; import com.google.gerrit.extensions.registration.DynamicSet; import com.google.inject.AbstractModule; +import com.googlesource.gerrit.plugins.healthcheck.check.AuthHealthCheck; import com.googlesource.gerrit.plugins.healthcheck.check.HealthCheck; import com.googlesource.gerrit.plugins.healthcheck.check.JGitHealthCheck; import com.googlesource.gerrit.plugins.healthcheck.check.ProjectsListHealthCheck; @@ -31,6 +32,7 @@ bindChecker(JGitHealthCheck.class); bindChecker(ProjectsListHealthCheck.class); bindChecker(QueryChangesHealthCheck.class); + bindChecker(AuthHealthCheck.class); bind(LifecycleListener.class).to(HealthCheckMetrics.class); }
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/AuthHealthCheck.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/AuthHealthCheck.java new file mode 100644 index 0000000..4003351 --- /dev/null +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/AuthHealthCheck.java
@@ -0,0 +1,69 @@ +// Copyright (C) 2019 The Android Open Source Project +// +// 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.googlesource.gerrit.plugins.healthcheck.check; + +import static com.googlesource.gerrit.plugins.healthcheck.check.HealthCheckNames.AUTH; + +import com.google.common.util.concurrent.ListeningExecutorService; +import com.google.gerrit.server.account.AccountCache; +import com.google.gerrit.server.account.AccountState; +import com.google.gerrit.server.account.AuthRequest; +import com.google.gerrit.server.account.Realm; +import com.google.inject.Inject; +import com.google.inject.Singleton; +import com.googlesource.gerrit.plugins.healthcheck.HealthCheckConfig; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +@Singleton +public class AuthHealthCheck extends AbstractHealthCheck { + private static final Logger log = LoggerFactory.getLogger(AuthHealthCheck.class); + private final Realm realm; + private final AccountCache byIdCache; + private final String username; + private final String password; + + @Inject + public AuthHealthCheck( + ListeningExecutorService executor, + HealthCheckConfig config, + Realm realm, + AccountCache byIdCache) { + super(executor, config, AUTH); + + this.realm = realm; + this.byIdCache = byIdCache; + this.username = config.getUsername(AUTH); + this.password = config.getPassword(AUTH); + } + + @Override + protected Result doCheck() throws Exception { + AuthRequest authRequest = AuthRequest.forUser(username); + authRequest.setPassword(password); + realm.authenticate(authRequest); + + AccountState accountState = byIdCache.getByUsername(username); + if (accountState == null) { + log.error("Cannot load account state for username " + username); + return Result.FAILED; + } + if (!accountState.getAccount().isActive()) { + log.error("Authentication error, account " + username + " is inactive"); + return Result.FAILED; + } + return Result.PASSED; + } +}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/HealthCheckNames.java b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/HealthCheckNames.java index 402fa35..b160fc4 100644 --- a/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/HealthCheckNames.java +++ b/src/main/java/com/googlesource/gerrit/plugins/healthcheck/check/HealthCheckNames.java
@@ -19,4 +19,5 @@ String JGIT = "jgit"; String PROJECTSLIST = "projectslist"; String QUERYCHANGES = "querychanges"; + String AUTH = "auth"; }
diff --git a/src/main/resources/Documentation/config.md b/src/main/resources/Documentation/config.md index c064bc3..c150f93 100644 --- a/src/main/resources/Documentation/config.md +++ b/src/main/resources/Documentation/config.md
@@ -47,6 +47,7 @@ - `reviewdb` : check connectivity and ability to query ReviewDb - `jgit` : check connectivity to the filesystem and ability to open a JGit ref and object - `projectslist` : check the ability to list projects with their descriptions +- `auth`: check the ability to authenticate with username and password The follwing parameters are available: @@ -69,4 +70,12 @@ Multiple occurrences are allowed to configure more projects, in addition to the default ones that are always included. - Default: All-Projects, All-Users \ No newline at end of file + Default: All-Projects, All-Users + + - `healthcheck.auth.username` : Username to use for authentication + + Default: healthcheck + + - `healthcheck.auth.password` : Password to use for authentication + + Default: no password \ No newline at end of file
diff --git a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckIT.java b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckIT.java index 2c63ed7..9f481ff 100644 --- a/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckIT.java +++ b/src/test/java/com/googlesource/gerrit/plugins/healthcheck/HealthCheckIT.java
@@ -59,6 +59,7 @@ for (int i = 0; i < numChanges; i++) { createChange("refs/for/master"); } + accounts.create(config.getUsername(HealthCheckNames.AUTH)); } @Test