Merge branch 'stable-2.15' into stable-2.16
* stable-2.15:
Switch required bazel version to 0.29.1
Change-Id: Id12b9d7a3382ef34c6ffe8be878b28869e9d8670
diff --git a/BUILD b/BUILD
index 81ab40d..8eb7d2a 100644
--- a/BUILD
+++ b/BUILD
@@ -41,5 +41,6 @@
exports = PLUGIN_DEPS + PLUGIN_TEST_DEPS + [
":lfs__plugin",
"@jgit-lfs//jar",
+ "@joda-time//jar",
],
)
diff --git a/WORKSPACE b/WORKSPACE
index 8dec321..d0e7d52 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,7 +3,7 @@
load("//:bazlets.bzl", "load_bazlets")
load_bazlets(
- commit = "5f03aec7c72e743079ea2ecad5530f4684ca7d45",
+ commit = "6af2e084b72d38a3375925c4586ac2278ef95ee9",
#local_path = "/home/<user>/projects/bazlets",
)
diff --git a/external_plugin_deps.bzl b/external_plugin_deps.bzl
index 3457c2f..a5277e6 100644
--- a/external_plugin_deps.bzl
+++ b/external_plugin_deps.bzl
@@ -1,13 +1,13 @@
load("//tools/bzl:maven_jar.bzl", "GERRIT", "MAVEN_CENTRAL", "MAVEN_LOCAL", "maven_jar")
-JGIT_VERSION = "4.11.9.201909030838-r"
+JGIT_VERSION = "5.1.7.201904200442-r"
REPO = MAVEN_CENTRAL
def external_plugin_deps():
maven_jar(
name = "jgit-http-apache",
artifact = "org.eclipse.jgit:org.eclipse.jgit.http.apache:" + JGIT_VERSION,
- sha1 = "f28a659ca83e2aa644f4ba81d28312d291d385ad",
+ sha1 = "3255f0c211deced0c13fbbfca8bf9f8dd58b69b1",
repository = REPO,
unsign = True,
exclude = [
@@ -19,7 +19,7 @@
maven_jar(
name = "jgit-lfs",
artifact = "org.eclipse.jgit:org.eclipse.jgit.lfs:" + JGIT_VERSION,
- sha1 = "88234aa639497cf725f2a32e47dbd7433975da67",
+ sha1 = "32a44fd5cbe1da07297e60aaeafce3d220b2fc1b",
repository = REPO,
unsign = True,
exclude = [
@@ -31,7 +31,7 @@
maven_jar(
name = "jgit-lfs-server",
artifact = "org.eclipse.jgit:org.eclipse.jgit.lfs.server:" + JGIT_VERSION,
- sha1 = "a1cd4548172c62a24cec195399e2dba877f44d32",
+ sha1 = "b79632ce4c376edd4517410d49ada5ac0b5c4649",
repository = REPO,
unsign = True,
exclude = [
@@ -39,3 +39,9 @@
"plugin.properties",
],
)
+
+ maven_jar(
+ name = "joda-time",
+ artifact = "joda-time:joda-time:2.9.9",
+ sha1 = "f7b520c458572890807d143670c9b24f4de90897",
+ )
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/GetLfsGlobalConfig.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/GetLfsGlobalConfig.java
index 40e00b0..ebbc81c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/GetLfsGlobalConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/GetLfsGlobalConfig.java
@@ -14,19 +14,11 @@
package com.googlesource.gerrit.plugins.lfs;
-import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
-
import com.google.common.collect.Maps;
-import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestReadView;
-import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.config.AllProjectsName;
-import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.project.ProjectResource;
import com.google.inject.Inject;
-import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.util.HashMap;
import java.util.List;
@@ -34,29 +26,17 @@
@Singleton
class GetLfsGlobalConfig implements RestReadView<ProjectResource> {
private final LfsConfigurationFactory lfsConfigFactory;
- private final AllProjectsName allProjectsName;
- private final Provider<CurrentUser> self;
- private final PermissionBackend permissionBackend;
+ private final LfsAdminView adminView;
@Inject
- GetLfsGlobalConfig(
- LfsConfigurationFactory lfsConfigFactory,
- AllProjectsName allProjectsName,
- Provider<CurrentUser> self,
- PermissionBackend permissionBackend) {
+ GetLfsGlobalConfig(LfsConfigurationFactory lfsConfigFactory, LfsAdminView adminView) {
this.lfsConfigFactory = lfsConfigFactory;
- this.allProjectsName = allProjectsName;
- this.self = self;
- this.permissionBackend = permissionBackend;
+ this.adminView = adminView;
}
@Override
public LfsGlobalConfigInfo apply(ProjectResource resource) throws RestApiException {
- IdentifiedUser user = self.get().asIdentifiedUser();
- if (!(resource.getNameKey().equals(allProjectsName)
- && permissionBackend.user(user).testOrFalse(ADMINISTRATE_SERVER))) {
- throw new ResourceNotFoundException();
- }
+ adminView.validate(resource);
LfsGlobalConfigInfo info = new LfsGlobalConfigInfo();
LfsGlobalConfig globalConfig = lfsConfigFactory.getGlobalConfig();
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsAdminView.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsAdminView.java
new file mode 100644
index 0000000..d9d2ad7
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsAdminView.java
@@ -0,0 +1,57 @@
+// 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.lfs;
+
+import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
+
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
+import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.config.AllProjectsName;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.project.ProjectResource;
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.Singleton;
+
+@Singleton
+public class LfsAdminView {
+ private final AllProjectsName allProjectsName;
+ private final PermissionBackend permissionBackend;
+ private final Provider<CurrentUser> self;
+
+ @Inject
+ LfsAdminView(
+ AllProjectsName allProjectsName,
+ PermissionBackend permissionBackend,
+ Provider<CurrentUser> self) {
+ this.allProjectsName = allProjectsName;
+ this.permissionBackend = permissionBackend;
+ this.self = self;
+ }
+
+ /**
+ * Validate REST call.
+ *
+ * @param resource the resource
+ * @throws ResourceNotFoundException if the calling user is not admin, or the resource is not
+ * {@code All-Projects}.
+ */
+ public void validate(ProjectResource resource) throws ResourceNotFoundException {
+ if (!(resource.getNameKey().equals(allProjectsName)
+ && permissionBackend.user(self.get()).testOrFalse(ADMINISTRATE_SERVER))) {
+ throw new ResourceNotFoundException();
+ }
+ }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsApiServlet.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsApiServlet.java
index d5eeddc..8982dbe 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsApiServlet.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsApiServlet.java
@@ -19,18 +19,18 @@
import static com.google.gerrit.extensions.client.ProjectState.HIDDEN;
import static com.google.gerrit.extensions.client.ProjectState.READ_ONLY;
import static com.google.gerrit.server.permissions.ProjectPermission.ACCESS;
+import static com.google.gerrit.server.permissions.ProjectPermission.PUSH_AT_LEAST_ONE_REF;
-import com.google.common.base.Strings;
+import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.ProjectUtil;
-import com.google.gerrit.common.data.Capable;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.permissions.PermissionBackend;
import com.google.gerrit.server.project.ProjectCache;
-import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.lfs.auth.LfsAuthUserProvider;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.jgit.lfs.errors.LfsException;
@@ -42,15 +42,13 @@
import org.eclipse.jgit.lfs.server.LargeFileRepository;
import org.eclipse.jgit.lfs.server.LfsObject;
import org.eclipse.jgit.lfs.server.LfsProtocolServlet;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
@Singleton
public class LfsApiServlet extends LfsProtocolServlet {
public static final String LFS_OBJECTS_REGEX_REST =
String.format(LFS_URL_REGEX_TEMPLATE, LFS_OBJECTS_PATH);
- private static final Logger log = LoggerFactory.getLogger(LfsApiServlet.class);
+ private static final FluentLogger log = FluentLogger.forEnclosingClass();
private static final long serialVersionUID = 1L;
private static final Pattern URL_PATTERN = Pattern.compile(LFS_OBJECTS_REGEX_REST);
@@ -125,18 +123,19 @@
private void authorizeUser(CurrentUser user, ProjectState state, LfsRequest request)
throws LfsUnauthorized {
- ProjectControl control = state.controlFor(user);
+ Project.NameKey projectName = state.getNameKey();
if ((request.isDownload()
+ && !permissionBackend.user(user).project(projectName).testOrFalse(ACCESS))
+ || (request.isUpload()
&& !permissionBackend
.user(user)
- .project(state.getProject().getNameKey())
- .testOrFalse(ACCESS))
- || (request.isUpload() && Capable.OK != control.canPushToAtLeastOneRef())) {
+ .project(projectName)
+ .testOrFalse(PUSH_AT_LEAST_ONE_REF))) {
String op = request.getOperation().toLowerCase();
String project = state.getProject().getName();
- String userName =
- Strings.isNullOrEmpty(user.getUserName()) ? "anonymous" : user.getUserName();
- log.debug("operation {} unauthorized for user {} on project {}", op, userName, project);
+ String userName = user.getUserName().orElse("anonymous");
+ log.atFine().log(
+ "operation %s unauthorized for user %s on project %s", op, userName, project);
throw new LfsUnauthorized(op, project);
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsGson.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsGson.java
new file mode 100644
index 0000000..66398fe
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsGson.java
@@ -0,0 +1,49 @@
+// 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.lfs;
+
+import com.google.gson.FieldNamingPolicy;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonIOException;
+import com.google.gson.JsonSyntaxException;
+import com.google.inject.Singleton;
+import java.io.Reader;
+
+@Singleton
+public class LfsGson {
+ private final Gson gson;
+
+ LfsGson() {
+ this.gson =
+ new GsonBuilder()
+ .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
+ .disableHtmlEscaping()
+ .create();
+ }
+
+ public void toJson(Object src, Appendable writer) throws JsonIOException {
+ gson.toJson(src, writer);
+ }
+
+ public String toJson(Object src) {
+ return gson.toJson(src);
+ }
+
+ public <T> T fromJson(Reader json, Class<T> classOfT)
+ throws JsonSyntaxException, JsonIOException {
+ return gson.fromJson(json, classOfT);
+ }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsProjectsConfig.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsProjectsConfig.java
index 390a65f..ea5e076 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsProjectsConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsProjectsConfig.java
@@ -21,7 +21,7 @@
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.config.AllProjectsName;
-import com.google.gerrit.server.git.VersionedMetaData;
+import com.google.gerrit.server.git.meta.VersionedMetaData;
import com.google.gerrit.server.project.ProjectCache;
import java.io.IOException;
import java.util.ArrayList;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsRepositoryResolver.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsRepositoryResolver.java
index 3e97db3..59cdb13 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsRepositoryResolver.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsRepositoryResolver.java
@@ -15,16 +15,15 @@
package com.googlesource.gerrit.plugins.lfs;
import com.google.common.base.Strings;
+import com.google.common.flogger.FluentLogger;
import com.google.gerrit.reviewdb.client.Project;
import com.google.inject.Inject;
import java.util.Map;
import org.eclipse.jgit.lfs.errors.LfsRepositoryNotFound;
import org.eclipse.jgit.lfs.server.LargeFileRepository;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
public class LfsRepositoryResolver {
- private static final Logger log = LoggerFactory.getLogger(LfsRepositoryResolver.class);
+ private static final FluentLogger log = FluentLogger.forEnclosingClass();
private final LfsRepositoriesCache cache;
private final LfsBackend defaultBackend;
@@ -47,7 +46,8 @@
} else {
backend = backends.get(backendName);
if (backend == null) {
- log.error("Project {} is configured with not existing backend {}", project, backendName);
+ log.atSevere().log(
+ "Project %s is configured with not existing backend %s", project, backendName);
throw new LfsRepositoryNotFound(project.get());
}
}
@@ -58,11 +58,9 @@
}
// this is unlikely situation as cache is pre-populated from config but...
- log.error(
- "Project {} is configured with not existing backend {} of type {}",
- project,
- backend.name(),
- backend.type);
+ log.atSevere().log(
+ "Project %s is configured with not existing backend %s of type %s",
+ project, backend.name(), backend.type);
throw new LfsRepositoryNotFound(project.get());
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/Lifecycle.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/Lifecycle.java
index ec386f1..90347be 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/Lifecycle.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/Lifecycle.java
@@ -15,18 +15,17 @@
package com.googlesource.gerrit.plugins.lfs;
import com.google.common.base.Strings;
+import com.google.common.flogger.FluentLogger;
import com.google.gerrit.extensions.annotations.PluginName;
import com.google.gerrit.extensions.events.LifecycleListener;
import com.google.gerrit.server.config.GerritServerConfig;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.eclipse.jgit.lib.Config;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
@Singleton
public class Lifecycle implements LifecycleListener {
- private static final Logger log = LoggerFactory.getLogger(Lifecycle.class);
+ private static final FluentLogger log = FluentLogger.forEnclosingClass();
private final String name;
private final Config config;
@@ -48,11 +47,10 @@
}
private void warn(String msg) {
- log.warn(
- "{}; LFS will not be enabled. Run site initialization, or manually set"
- + " lfs.plugin to '{}' in gerrit.config",
- msg,
- name);
+ log.atWarning().log(
+ "%s; LFS will not be enabled. Run site initialization, or manually set"
+ + " lfs.plugin to '%s' in gerrit.config",
+ msg, name);
}
@Override
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/PutLfsGlobalConfig.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/PutLfsGlobalConfig.java
index b747925..ea4e44e 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/PutLfsGlobalConfig.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/PutLfsGlobalConfig.java
@@ -14,7 +14,6 @@
package com.googlesource.gerrit.plugins.lfs;
-import static com.google.gerrit.server.permissions.GlobalPermission.ADMINISTRATE_SERVER;
import static com.googlesource.gerrit.plugins.lfs.LfsProjectConfigSection.KEY_BACKEND;
import static com.googlesource.gerrit.plugins.lfs.LfsProjectConfigSection.KEY_ENABLED;
import static com.googlesource.gerrit.plugins.lfs.LfsProjectConfigSection.KEY_MAX_OBJECT_SIZE;
@@ -27,11 +26,7 @@
import com.google.gerrit.extensions.restapi.RestApiException;
import com.google.gerrit.extensions.restapi.RestModifyView;
import com.google.gerrit.reviewdb.client.Project;
-import com.google.gerrit.server.CurrentUser;
-import com.google.gerrit.server.IdentifiedUser;
-import com.google.gerrit.server.config.AllProjectsName;
-import com.google.gerrit.server.git.MetaDataUpdate;
-import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.git.meta.MetaDataUpdate;
import com.google.gerrit.server.project.ProjectResource;
import com.google.inject.Inject;
import com.google.inject.Provider;
@@ -48,9 +43,7 @@
class PutLfsGlobalConfig implements RestModifyView<ProjectResource, LfsGlobalConfigInput> {
private final String pluginName;
- private final AllProjectsName allProjectsName;
- private final PermissionBackend permissionBackend;
- private final Provider<CurrentUser> self;
+ private final LfsAdminView adminView;
private final Provider<MetaDataUpdate.User> metaDataUpdateFactory;
private final LfsConfigurationFactory lfsConfigFactory;
private final GetLfsGlobalConfig get;
@@ -58,16 +51,12 @@
@Inject
PutLfsGlobalConfig(
@PluginName String pluginName,
- AllProjectsName allProjectsName,
- PermissionBackend permissionBackend,
- Provider<CurrentUser> self,
+ LfsAdminView adminView,
Provider<MetaDataUpdate.User> metaDataUpdateFactory,
LfsConfigurationFactory lfsConfigFactory,
GetLfsGlobalConfig get) {
this.pluginName = pluginName;
- this.allProjectsName = allProjectsName;
- this.permissionBackend = permissionBackend;
- this.self = self;
+ this.adminView = adminView;
this.metaDataUpdateFactory = metaDataUpdateFactory;
this.lfsConfigFactory = lfsConfigFactory;
this.get = get;
@@ -76,14 +65,9 @@
@Override
public LfsGlobalConfigInfo apply(ProjectResource resource, LfsGlobalConfigInput input)
throws RestApiException {
- IdentifiedUser user = self.get().asIdentifiedUser();
+ adminView.validate(resource);
Project.NameKey projectName = resource.getNameKey();
- if (!(projectName.equals(allProjectsName)
- && permissionBackend.user(user).testOrFalse(ADMINISTRATE_SERVER))) {
- throw new ResourceNotFoundException();
- }
-
if (input == null) {
input = new LfsGlobalConfigInput();
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/SshModule.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/SshModule.java
index e74e813..931ffce 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/SshModule.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/SshModule.java
@@ -17,6 +17,7 @@
import com.google.gerrit.extensions.registration.DynamicItem;
import com.google.gerrit.sshd.PluginCommandModule;
import com.google.gerrit.sshd.plugin.LfsPluginAuthCommand;
+import com.googlesource.gerrit.plugins.lfs.auth.LfsSshAuth;
public class SshModule extends PluginCommandModule {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/AuthInfo.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/auth/AuthInfo.java
similarity index 93%
rename from src/main/java/com/googlesource/gerrit/plugins/lfs/AuthInfo.java
rename to src/main/java/com/googlesource/gerrit/plugins/lfs/auth/AuthInfo.java
index 4336ed5..9b765d2 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/AuthInfo.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/auth/AuthInfo.java
@@ -12,8 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.googlesource.gerrit.plugins.lfs;
+package com.googlesource.gerrit.plugins.lfs.auth;
+import com.googlesource.gerrit.plugins.lfs.LfsDateTime;
import java.time.Instant;
public class AuthInfo {
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/ExpiringAction.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/auth/ExpiringAction.java
similarity index 95%
rename from src/main/java/com/googlesource/gerrit/plugins/lfs/ExpiringAction.java
rename to src/main/java/com/googlesource/gerrit/plugins/lfs/auth/ExpiringAction.java
index d3255a1..133a386 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/ExpiringAction.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/auth/ExpiringAction.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.googlesource.gerrit.plugins.lfs;
+package com.googlesource.gerrit.plugins.lfs.auth;
import static org.eclipse.jgit.util.HttpSupport.HDR_AUTHORIZATION;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsAuthToken.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/auth/LfsAuthToken.java
similarity index 97%
rename from src/main/java/com/googlesource/gerrit/plugins/lfs/LfsAuthToken.java
rename to src/main/java/com/googlesource/gerrit/plugins/lfs/auth/LfsAuthToken.java
index 909d295..7abce2c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsAuthToken.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/auth/LfsAuthToken.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.googlesource.gerrit.plugins.lfs;
+package com.googlesource.gerrit.plugins.lfs.auth;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
@@ -23,7 +23,6 @@
public abstract class LfsAuthToken {
public abstract static class Processor<T extends LfsAuthToken> {
private static final char DELIMETER = '~';
-
protected final LfsCipher cipher;
protected Processor(LfsCipher cipher) {
@@ -39,7 +38,6 @@
if (!decrypted.isPresent()) {
return Optional.empty();
}
-
return createToken(Splitter.on(DELIMETER).splitToList(decrypted.get()));
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsAuthUserProvider.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/auth/LfsAuthUserProvider.java
similarity index 87%
rename from src/main/java/com/googlesource/gerrit/plugins/lfs/LfsAuthUserProvider.java
rename to src/main/java/com/googlesource/gerrit/plugins/lfs/auth/LfsAuthUserProvider.java
index f7d3078..fcd4736 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsAuthUserProvider.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/auth/LfsAuthUserProvider.java
@@ -12,9 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.googlesource.gerrit.plugins.lfs;
+package com.googlesource.gerrit.plugins.lfs.auth;
-import static com.googlesource.gerrit.plugins.lfs.LfsSshRequestAuthorizer.SSH_AUTH_PREFIX;
+import static com.googlesource.gerrit.plugins.lfs.auth.LfsSshRequestAuthorizer.SSH_AUTH_PREFIX;
import com.google.common.base.Strings;
import com.google.gerrit.server.AnonymousUser;
@@ -55,9 +55,9 @@
sshAuth.getUserFromValidToken(
auth.substring(SSH_AUTH_PREFIX.length()), project, operation);
if (user.isPresent()) {
- AccountState acc = accounts.getByUsername(user.get());
- if (acc != null) {
- return userFactory.create(acc);
+ Optional<AccountState> acc = accounts.getByUsername(user.get());
+ if (acc.isPresent()) {
+ return userFactory.create(acc.get());
}
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsCipher.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/auth/LfsCipher.java
similarity index 88%
rename from src/main/java/com/googlesource/gerrit/plugins/lfs/LfsCipher.java
rename to src/main/java/com/googlesource/gerrit/plugins/lfs/auth/LfsCipher.java
index aec332a..710b3c1 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsCipher.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/auth/LfsCipher.java
@@ -12,11 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.googlesource.gerrit.plugins.lfs;
+package com.googlesource.gerrit.plugins.lfs.auth;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.google.common.base.Strings;
+import com.google.common.flogger.FluentLogger;
import com.google.common.primitives.Bytes;
import com.google.inject.Singleton;
import java.security.AlgorithmParameters;
@@ -30,12 +31,10 @@
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import org.eclipse.jgit.util.Base64;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
@Singleton
public class LfsCipher {
- private static final Logger log = LoggerFactory.getLogger(LfsCipher.class);
+ private static final FluentLogger log = FluentLogger.forEnclosingClass();
private static final int IV_LENGTH = 16;
private static final String ALGORITHM = "AES";
private static final String CIPHER_TYPE = ALGORITHM + "/CBC/PKCS5PADDING";
@@ -56,7 +55,7 @@
Cipher cipher = cipher(initVector, Cipher.ENCRYPT_MODE);
return Base64.encodeBytes(Bytes.concat(initVector, cipher.doFinal(input.getBytes(UTF_8))));
} catch (GeneralSecurityException e) {
- log.error("Token generation failed with error", e);
+ log.atSevere().withCause(e).log("Token generation failed with error");
throw new RuntimeException(e);
}
}
@@ -73,7 +72,7 @@
return Optional.of(
new String(cipher.doFinal(Arrays.copyOfRange(bytes, IV_LENGTH, bytes.length)), UTF_8));
} catch (GeneralSecurityException e) {
- log.error("Exception was thrown during token verification", e);
+ log.atSevere().withCause(e).log("Exception was thrown during token verification");
}
return Optional.empty();
@@ -94,7 +93,7 @@
generator.init(KEY_SIZE, random);
return generator.generateKey();
} catch (NoSuchAlgorithmException e) {
- log.error("Generating key failed with error", e);
+ log.atSevere().withCause(e).log("Generating key failed with error");
throw new RuntimeException(e);
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsSshAuth.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/auth/LfsSshAuth.java
similarity index 84%
rename from src/main/java/com/googlesource/gerrit/plugins/lfs/LfsSshAuth.java
rename to src/main/java/com/googlesource/gerrit/plugins/lfs/auth/LfsSshAuth.java
index 08d7ca7..9fd57b9 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsSshAuth.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/auth/LfsSshAuth.java
@@ -12,19 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.googlesource.gerrit.plugins.lfs;
+package com.googlesource.gerrit.plugins.lfs.auth;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.config.CanonicalWebUrl;
import com.google.gerrit.sshd.BaseCommand.Failure;
import com.google.gerrit.sshd.BaseCommand.UnloggedFailure;
import com.google.gerrit.sshd.plugin.LfsPluginAuthCommand;
-import com.google.gson.FieldNamingPolicy;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.lfs.LfsGson;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
@@ -33,17 +31,16 @@
public class LfsSshAuth implements LfsPluginAuthCommand.LfsSshPluginAuth {
private final LfsSshRequestAuthorizer auth;
private final String canonicalWebUrl;
- private final Gson gson;
+ private final LfsGson gson;
@Inject
- LfsSshAuth(LfsSshRequestAuthorizer auth, @CanonicalWebUrl Provider<String> canonicalWebUrl) {
+ LfsSshAuth(
+ LfsSshRequestAuthorizer auth,
+ @CanonicalWebUrl Provider<String> canonicalWebUrl,
+ LfsGson gson) {
this.auth = auth;
this.canonicalWebUrl = canonicalWebUrl.get();
- this.gson =
- new GsonBuilder()
- .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
- .disableHtmlEscaping()
- .create();
+ this.gson = gson;
}
@Override
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsSshRequestAuthorizer.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/auth/LfsSshRequestAuthorizer.java
similarity index 86%
rename from src/main/java/com/googlesource/gerrit/plugins/lfs/LfsSshRequestAuthorizer.java
rename to src/main/java/com/googlesource/gerrit/plugins/lfs/auth/LfsSshRequestAuthorizer.java
index 12c5552..14803ed 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/LfsSshRequestAuthorizer.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/auth/LfsSshRequestAuthorizer.java
@@ -12,17 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.googlesource.gerrit.plugins.lfs;
+package com.googlesource.gerrit.plugins.lfs.auth;
+import com.google.common.flogger.FluentLogger;
import com.google.gerrit.server.CurrentUser;
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.lfs.LfsConfigurationFactory;
+import com.googlesource.gerrit.plugins.lfs.LfsDateTime;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
@Singleton
class LfsSshRequestAuthorizer {
@@ -32,10 +33,9 @@
}
}
- private static final Logger log = LoggerFactory.getLogger(LfsSshRequestAuthorizer.class);
+ private static final FluentLogger log = FluentLogger.forEnclosingClass();
private static final int DEFAULT_SSH_TIMEOUT = 10;
static final String SSH_AUTH_PREFIX = "Ssh: ";
-
private final Processor processor;
private final Long expiresIn;
@@ -49,17 +49,16 @@
.getGlobalConfig()
.getInt("auth", null, "sshExpirationSeconds", DEFAULT_SSH_TIMEOUT);
} catch (IllegalArgumentException e) {
- log.warn(
- "Reading expiration timeout failed with error." + " Falling back to default {}",
- DEFAULT_SSH_TIMEOUT,
- e);
+ log.atWarning().withCause(e).log(
+ "Reading expiration timeout failed with error. Falling back to default %d",
+ DEFAULT_SSH_TIMEOUT);
}
this.expiresIn = timeout;
}
SshAuthInfo generateAuthInfo(CurrentUser user, String project, String operation) {
LfsSshAuthToken token =
- new LfsSshAuthToken(user.getUserName(), project, operation, Instant.now(), expiresIn);
+ new LfsSshAuthToken(user.getUserName().get(), project, operation, Instant.now(), expiresIn);
return new SshAuthInfo(processor.serialize(token), token.issued, token.expiresIn);
}
@@ -68,13 +67,11 @@
if (!token.isPresent()) {
return Optional.empty();
}
-
Verifier verifier = new Verifier(token.get(), project, operation);
if (!verifier.verify()) {
- log.error("Invalid data was provided with auth token {}.", authToken);
+ log.atSevere().log("Invalid data was provided with auth token %s.", authToken);
return Optional.empty();
}
-
return Optional.of(token.get().user);
}
@@ -100,7 +97,6 @@
if (values.size() != 5) {
return Optional.empty();
}
-
return Optional.of(
new LfsSshAuthToken(
values.get(0),
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/fs/LfsFsDataDirectoryManager.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/fs/LfsFsDataDirectoryManager.java
new file mode 100644
index 0000000..d8e6366
--- /dev/null
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/fs/LfsFsDataDirectoryManager.java
@@ -0,0 +1,68 @@
+// 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.lfs.fs;
+
+import com.google.common.base.Strings;
+import com.google.gerrit.extensions.annotations.PluginData;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.lfs.LfsBackend;
+import com.googlesource.gerrit.plugins.lfs.LfsConfigurationFactory;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+@Singleton
+public class LfsFsDataDirectoryManager {
+ private static final String KEY_DIRECTORY = "directory";
+
+ private final LfsConfigurationFactory configFactory;
+ private final Path defaultDataDir;
+
+ @Inject
+ LfsFsDataDirectoryManager(
+ LfsConfigurationFactory configFactory, @PluginData Path defaultDataDir) {
+ this.configFactory = configFactory;
+ this.defaultDataDir = defaultDataDir;
+ }
+
+ public Path ensureForBackend(LfsBackend backend) throws IOException {
+ return getForBackend(backend, true);
+ }
+
+ public Path getForBackend(LfsBackend backend, boolean ensure) throws IOException {
+ String dataDir =
+ configFactory.getGlobalConfig().getString(backend.type.name(), backend.name, KEY_DIRECTORY);
+ if (Strings.isNullOrEmpty(dataDir)) {
+ return defaultDataDir;
+ }
+
+ if (ensure) {
+ // note that the following method not only creates missing
+ // directory/directories but throws exception when path
+ // exists and points to file
+ Path ensured = Files.createDirectories(Paths.get(dataDir));
+
+ // we should at least make sure that directory is readable
+ if (!Files.isReadable(ensured)) {
+ throw new IOException("Path '" + ensured.toAbsolutePath() + "' cannot be accessed");
+ }
+
+ return ensured;
+ }
+ return Paths.get(dataDir);
+ }
+}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/fs/LfsFsRequestAuthorizer.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/fs/LfsFsRequestAuthorizer.java
index 7e982b5..279217b 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/fs/LfsFsRequestAuthorizer.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/fs/LfsFsRequestAuthorizer.java
@@ -16,10 +16,10 @@
import com.google.inject.Inject;
import com.google.inject.Singleton;
-import com.googlesource.gerrit.plugins.lfs.AuthInfo;
-import com.googlesource.gerrit.plugins.lfs.LfsAuthToken;
-import com.googlesource.gerrit.plugins.lfs.LfsCipher;
import com.googlesource.gerrit.plugins.lfs.LfsDateTime;
+import com.googlesource.gerrit.plugins.lfs.auth.AuthInfo;
+import com.googlesource.gerrit.plugins.lfs.auth.LfsAuthToken;
+import com.googlesource.gerrit.plugins.lfs.auth.LfsCipher;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
@@ -47,7 +47,6 @@
if (!token.isPresent()) {
return false;
}
-
return new Verifier(token.get(), operation, id).verify();
}
@@ -72,7 +71,6 @@
if (values.size() != 4) {
return Optional.empty();
}
-
return Optional.of(
new LfsFsAuthToken(
values.get(0),
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/fs/LocalLargeFileRepository.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/fs/LocalLargeFileRepository.java
index 0a6ef34..069d163 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/fs/LocalLargeFileRepository.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/fs/LocalLargeFileRepository.java
@@ -17,20 +17,14 @@
import static org.eclipse.jgit.lfs.lib.Constants.DOWNLOAD;
import static org.eclipse.jgit.lfs.lib.Constants.UPLOAD;
-import com.google.common.base.Strings;
import com.google.gerrit.extensions.annotations.PluginCanonicalWebUrl;
-import com.google.gerrit.extensions.annotations.PluginData;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
-import com.googlesource.gerrit.plugins.lfs.AuthInfo;
-import com.googlesource.gerrit.plugins.lfs.ExpiringAction;
import com.googlesource.gerrit.plugins.lfs.LfsBackend;
import com.googlesource.gerrit.plugins.lfs.LfsConfigurationFactory;
-import com.googlesource.gerrit.plugins.lfs.LfsGlobalConfig;
+import com.googlesource.gerrit.plugins.lfs.auth.AuthInfo;
+import com.googlesource.gerrit.plugins.lfs.auth.ExpiringAction;
import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.nio.file.Paths;
import java.time.Instant;
import org.eclipse.jgit.lfs.lib.AnyLongObjectId;
import org.eclipse.jgit.lfs.server.Response;
@@ -50,15 +44,13 @@
@Inject
LocalLargeFileRepository(
+ LfsFsDataDirectoryManager dataDirManager,
LfsConfigurationFactory configFactory,
LfsFsRequestAuthorizer authorizer,
@PluginCanonicalWebUrl String url,
- @PluginData Path defaultDataDir,
@Assisted LfsBackend backend)
throws IOException {
- super(
- getContentUrl(url, backend),
- getOrCreateDataDir(configFactory.getGlobalConfig(), backend, defaultDataDir));
+ super(getContentUrl(url, backend), dataDirManager.ensureForBackend(backend));
this.authorizer = authorizer;
this.servletUrlPattern = "/" + getContentPath(backend) + "*";
this.expiresIn =
@@ -99,24 +91,4 @@
private static String getContentPath(LfsBackend backend) {
return String.format(CONTENT_PATH_TEMPLATE, backend.name());
}
-
- private static Path getOrCreateDataDir(
- LfsGlobalConfig config, LfsBackend backendConfig, Path defaultDataDir) throws IOException {
- String dataDir = config.getString(backendConfig.type.name(), backendConfig.name, "directory");
- if (Strings.isNullOrEmpty(dataDir)) {
- return defaultDataDir;
- }
-
- // note that the following method not only creates missing
- // directory/directories but throws exception when path
- // exists and points to file
- Path ensured = Files.createDirectories(Paths.get(dataDir));
-
- // we should at least make sure that directory is readable
- if (!Files.isReadable(ensured)) {
- throw new IOException("Path '" + ensured.toAbsolutePath() + "' cannot be accessed");
- }
-
- return ensured;
- }
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsGetLocksAction.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsGetLocksAction.java
index 32616f6..a84d458 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsGetLocksAction.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsGetLocksAction.java
@@ -23,18 +23,17 @@
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackend.ForProject;
import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ProjectCache;
-import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
-import com.googlesource.gerrit.plugins.lfs.LfsAuthUserProvider;
+import com.googlesource.gerrit.plugins.lfs.auth.LfsAuthUserProvider;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.jgit.lfs.errors.LfsException;
-import org.eclipse.jgit.lfs.errors.LfsUnauthorized;
public class LfsGetLocksAction extends LfsLocksAction {
interface Factory extends LfsLocksAction.Factory<LfsGetLocksAction> {}
@@ -42,8 +41,6 @@
static final Pattern LFS_LOCKS_URL_PATTERN =
Pattern.compile(String.format(LFS_URL_REGEX_TEMPLATE, LFS_LOCKS_PATH_REGEX));
- private final PermissionBackend permissionBackend;
-
@Inject
LfsGetLocksAction(
PermissionBackend permissionBackend,
@@ -51,8 +48,7 @@
LfsAuthUserProvider userProvider,
LfsLocksHandler handler,
@Assisted LfsLocksContext context) {
- super(projectCache, userProvider, handler, context);
- this.permissionBackend = permissionBackend;
+ super(permissionBackend, projectCache, userProvider, handler, context);
}
@Override
@@ -66,15 +62,14 @@
}
@Override
- protected void authorizeUser(ProjectControl control) throws LfsUnauthorized {
- try {
- permissionBackend
- .user(control.getUser())
- .project(control.getProject().getNameKey())
- .check(ACCESS);
- } catch (AuthException | PermissionBackendException e) {
- throwUnauthorizedOp("list locks", control);
- }
+ protected void authorizeUser(ForProject project)
+ throws AuthException, PermissionBackendException {
+ project.check(ACCESS);
+ }
+
+ @Override
+ protected String getAction() {
+ return "list-locks";
}
@Override
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsLocksAction.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsLocksAction.java
index 4fa8680..4b6afb4 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsLocksAction.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsLocksAction.java
@@ -21,28 +21,29 @@
import static org.apache.http.HttpStatus.SC_UNAUTHORIZED;
import static org.eclipse.jgit.util.HttpSupport.HDR_AUTHORIZATION;
-import com.google.common.base.Strings;
+import com.google.common.flogger.FluentLogger;
import com.google.gerrit.common.ProjectUtil;
+import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackend.ForProject;
+import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ProjectCache;
-import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.ProjectState;
-import com.googlesource.gerrit.plugins.lfs.LfsAuthUserProvider;
+import com.googlesource.gerrit.plugins.lfs.auth.LfsAuthUserProvider;
import com.googlesource.gerrit.plugins.lfs.locks.LfsLocksHandler.LfsLockExistsException;
import java.io.IOException;
import org.eclipse.jgit.lfs.errors.LfsException;
import org.eclipse.jgit.lfs.errors.LfsRepositoryNotFound;
import org.eclipse.jgit.lfs.errors.LfsUnauthorized;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
abstract class LfsLocksAction {
interface Factory<T extends LfsLocksAction> {
T create(LfsLocksContext context);
}
- private static final Logger log = LoggerFactory.getLogger(LfsLocksAction.class);
+ private static final FluentLogger log = FluentLogger.forEnclosingClass();
/** Git LFS client uses 'upload' operation to authorize SSH Lock requests */
private static final String LFS_LOCKING_OPERATION = "upload";
@@ -50,12 +51,15 @@
protected final LfsAuthUserProvider userProvider;
protected final LfsLocksHandler handler;
protected final LfsLocksContext context;
+ protected final PermissionBackend permissionBackend;
protected LfsLocksAction(
+ PermissionBackend permissionBackend,
ProjectCache projectCache,
LfsAuthUserProvider userProvider,
LfsLocksHandler handler,
LfsLocksContext context) {
+ this.permissionBackend = permissionBackend;
this.projectCache = projectCache;
this.userProvider = userProvider;
this.handler = handler;
@@ -67,8 +71,12 @@
String name = getProjectName();
ProjectState project = getProject(name);
CurrentUser user = getUser(name);
- ProjectControl control = project.controlFor(user);
- authorizeUser(control);
+ ProjectState state = projectCache.checkedGet(project.getNameKey());
+ try {
+ authorizeUser(permissionBackend.user(user).project(state.getNameKey()));
+ } catch (AuthException | PermissionBackendException e) {
+ throwUnauthorizedOp(getAction(), project, user);
+ }
doRun(project, user);
} catch (LfsUnauthorized e) {
context.sendError(SC_UNAUTHORIZED, e.getMessage());
@@ -83,7 +91,10 @@
protected abstract String getProjectName() throws LfsException;
- protected abstract void authorizeUser(ProjectControl control) throws LfsUnauthorized;
+ protected abstract String getAction();
+
+ protected abstract void authorizeUser(ForProject project)
+ throws AuthException, PermissionBackendException;
protected abstract void doRun(ProjectState project, CurrentUser user)
throws LfsException, IOException;
@@ -102,13 +113,11 @@
context.getHeader(HDR_AUTHORIZATION), project, LFS_LOCKING_OPERATION);
}
- protected void throwUnauthorizedOp(String op, ProjectControl control) throws LfsUnauthorized {
- String project = control.getProject().getName();
- String userName =
- Strings.isNullOrEmpty(control.getUser().getUserName())
- ? "anonymous"
- : control.getUser().getUserName();
- log.debug("operation {} unauthorized for user {} on project {}", op, userName, project);
+ private void throwUnauthorizedOp(String op, ProjectState state, CurrentUser user)
+ throws LfsUnauthorized {
+ String project = state.getProject().getName();
+ String userName = user.getUserName().orElse("anonymous");
+ log.atFine().log("operation %s unauthorized for user %s on project %s", op, userName, project);
throw new LfsUnauthorized(op, project);
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsLocksContext.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsLocksContext.java
index fa5f360..5e4094c 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsLocksContext.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsLocksContext.java
@@ -20,9 +20,8 @@
import com.google.common.base.Supplier;
import com.google.common.base.Suppliers;
-import com.google.gson.FieldNamingPolicy;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
+import com.google.common.flogger.FluentLogger;
+import com.googlesource.gerrit.plugins.lfs.LfsGson;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
@@ -32,11 +31,9 @@
import java.io.Writer;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
class LfsLocksContext {
- private static final Logger log = LoggerFactory.getLogger(LfsLocksContext.class);
+ private static final FluentLogger log = FluentLogger.forEnclosingClass();
public final String path;
@@ -44,9 +41,9 @@
private final HttpServletResponse res;
private final Supplier<Writer> writer;
private final Supplier<Reader> reader;
- private final Gson gson;
+ private final LfsGson gson;
- LfsLocksContext(final HttpServletRequest req, final HttpServletResponse res) {
+ LfsLocksContext(LfsGson gson, final HttpServletRequest req, final HttpServletResponse res) {
this.path = req.getPathInfo().startsWith("/") ? req.getPathInfo() : "/" + req.getPathInfo();
this.req = req;
this.res = res;
@@ -74,7 +71,7 @@
}
}
});
- this.gson = createGson();
+ this.gson = gson;
setLfsResponseType();
}
@@ -101,7 +98,7 @@
}
void sendError(int status, Error error) throws IOException {
- log.error(error.message);
+ log.atSevere().log(error.message);
res.setStatus(status);
gson.toJson(error, getWriter());
getWriter().flush();
@@ -119,13 +116,6 @@
res.setContentType(CONTENTTYPE_VND_GIT_LFS_JSON);
}
- private Gson createGson() {
- return new GsonBuilder()
- .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
- .disableHtmlEscaping()
- .create();
- }
-
/** copied from org.eclipse.jgit.lfs.server.LfsProtocolServlet.Error */
static class Error {
String message;
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsLocksHandler.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsLocksHandler.java
index 3692374..1de28f4 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsLocksHandler.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsLocksHandler.java
@@ -17,6 +17,7 @@
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.ImmutableList;
+import com.google.common.flogger.FluentLogger;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.cache.CacheModule;
@@ -30,8 +31,6 @@
import java.util.Optional;
import java.util.stream.Collectors;
import org.eclipse.jgit.lfs.errors.LfsException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
@Singleton
class LfsLocksHandler {
@@ -55,7 +54,7 @@
}
}
- private static final Logger log = LoggerFactory.getLogger(LfsLocksHandler.class);
+ private static final FluentLogger log = FluentLogger.forEnclosingClass();
private static final String CACHE_NAME = "lfs_project_locks";
static Module module() {
@@ -80,7 +79,7 @@
LfsLockResponse createLock(Project.NameKey project, CurrentUser user, LfsCreateLockInput input)
throws LfsException {
- log.debug("Create lock for {} in project {}", input.path, project);
+ log.atFine().log("Create lock for %s in project %s", input.path, project);
LfsProjectLocks locks = projectLocks.getUnchecked(project);
LfsLock lock = locks.createLock(user, input);
return new LfsLockResponse(lock);
@@ -89,11 +88,9 @@
LfsLockResponse deleteLock(
Project.NameKey project, CurrentUser user, String lockId, LfsDeleteLockInput input)
throws LfsException {
- log.debug(
- "Delete (-f {}) lock for {} in project {}",
- Boolean.TRUE.equals(input.force),
- lockId,
- project);
+ log.atFine().log(
+ "Delete (-f %s) lock for %s in project %s",
+ Boolean.TRUE.equals(input.force), lockId, project);
LfsProjectLocks locks = projectLocks.getUnchecked(project);
Optional<LfsLock> hasLock = locks.getLock(lockId);
if (!hasLock.isPresent()) {
@@ -102,7 +99,7 @@
}
LfsLock lock = hasLock.get();
- if (lock.owner.name.equals(user.getUserName())) {
+ if (lock.owner.name.equals(user.getUserName().get())) {
locks.deleteLock(lock);
return new LfsLockResponse(lock);
} else if (input.force) {
@@ -115,26 +112,26 @@
}
LfsVerifyLocksResponse verifyLocks(Project.NameKey project, final CurrentUser user) {
- log.debug("Verify list of locks for {} project and user {}", project, user);
+ log.atFine().log("Verify list of locks for %s project and user %s", project, user);
LfsProjectLocks locks = projectLocks.getUnchecked(project);
Map<Boolean, List<LfsLock>> groupByOurs =
locks.getLocks().stream()
.collect(
Collectors.groupingBy(
(in) -> {
- return in.owner.name.equals(user.getUserName());
+ return in.owner.name.equals(user.getUserName().get());
}));
return new LfsVerifyLocksResponse(groupByOurs.get(true), groupByOurs.get(false), null);
}
LfsGetLocksResponse listLocksByPath(Project.NameKey project, String path) {
- log.debug("Get lock for {} path in {} project", path, project);
+ log.atFine().log("Get lock for %s path in %s project", path, project);
String lockId = toLockId.apply(path);
return listLocksById(project, lockId);
}
LfsGetLocksResponse listLocksById(Project.NameKey project, String id) {
- log.debug("Get lock for {} id in {} project", id, project);
+ log.atFine().log("Get lock for %s id in %s project", id, project);
LfsProjectLocks locks = projectLocks.getUnchecked(project);
Optional<LfsLock> lock = locks.getLock(id);
List<LfsLock> locksById =
@@ -143,7 +140,7 @@
}
LfsGetLocksResponse listLocks(Project.NameKey project) {
- log.debug("Get locks for {} project", project);
+ log.atFine().log("Get locks for %s project", project);
return new LfsGetLocksResponse(projectLocks.getUnchecked(project).getLocks(), null);
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsLocksServlet.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsLocksServlet.java
index 9cdeb62..1e6146d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsLocksServlet.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsLocksServlet.java
@@ -20,6 +20,7 @@
import com.google.inject.Inject;
import com.google.inject.Singleton;
+import com.googlesource.gerrit.plugins.lfs.LfsGson;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
@@ -35,24 +36,27 @@
private final LfsGetLocksAction.Factory getters;
private final LfsPutLocksAction.Factory putters;
+ private final LfsGson gson;
@Inject
- LfsLocksServlet(LfsGetLocksAction.Factory getters, LfsPutLocksAction.Factory putters) {
+ LfsLocksServlet(
+ LfsGetLocksAction.Factory getters, LfsPutLocksAction.Factory putters, LfsGson gson) {
this.getters = getters;
this.putters = putters;
+ this.gson = gson;
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
- LfsLocksContext context = new LfsLocksContext(req, resp);
+ LfsLocksContext context = new LfsLocksContext(gson, req, resp);
getters.create(context).run();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
- LfsLocksContext context = new LfsLocksContext(req, resp);
+ LfsLocksContext context = new LfsLocksContext(gson, req, resp);
putters.create(context).run();
}
}
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsProjectLocks.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsProjectLocks.java
index a578736..4526fa4 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsProjectLocks.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsProjectLocks.java
@@ -16,14 +16,13 @@
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
+import com.google.common.flogger.FluentLogger;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.CurrentUser;
-import com.google.gson.FieldNamingPolicy;
-import com.google.gson.Gson;
-import com.google.gson.GsonBuilder;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
import com.googlesource.gerrit.plugins.lfs.LfsDateTime;
+import com.googlesource.gerrit.plugins.lfs.LfsGson;
import com.googlesource.gerrit.plugins.lfs.locks.LfsLocksHandler.LfsLockExistsException;
import java.io.IOException;
import java.io.OutputStreamWriter;
@@ -36,21 +35,14 @@
import java.util.stream.Stream;
import org.eclipse.jgit.internal.storage.file.LockFile;
import org.eclipse.jgit.lfs.errors.LfsException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
class LfsProjectLocks {
interface Factory {
LfsProjectLocks create(Project.NameKey project);
}
- private static final Logger log = LoggerFactory.getLogger(LfsProjectLocks.class);
- private static final Gson gson =
- new GsonBuilder()
- .setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES)
- .disableHtmlEscaping()
- .create();
-
+ private static final FluentLogger log = FluentLogger.forEnclosingClass();
+ private final LfsGson gson;
private final PathToLockId toLockId;
private final String project;
private final Path locksPath;
@@ -58,7 +50,11 @@
@Inject
LfsProjectLocks(
- PathToLockId toLockId, LfsLocksPathProvider locksPath, @Assisted Project.NameKey project) {
+ LfsGson gson,
+ PathToLockId toLockId,
+ LfsLocksPathProvider locksPath,
+ @Assisted Project.NameKey project) {
+ this.gson = gson;
this.toLockId = toLockId;
this.project = project.get();
this.locksPath = Paths.get(locksPath.get(), this.project);
@@ -75,7 +71,8 @@
.forEach(
path -> {
if (!Files.isReadable(path)) {
- log.warn("Lock file [{}] in project {} is not readable", path, project);
+ log.atWarning().log(
+ "Lock file [%s] in project %s is not readable", path, project);
return;
}
@@ -83,11 +80,11 @@
LfsLock lock = gson.fromJson(in, LfsLock.class);
locks.put(lock.id, lock);
} catch (IOException e) {
- log.warn("Reading lock [{}] failed", path, e);
+ log.atWarning().withCause(e).log("Reading lock [%s] failed", path);
}
});
} catch (IOException e) {
- log.warn("Reading locks in project {} failed", project, e);
+ log.atWarning().withCause(e).log("Reading locks in project %s failed", project);
}
}
@@ -96,18 +93,20 @@
}
LfsLock createLock(CurrentUser user, LfsCreateLockInput input) throws LfsException {
- log.debug("Create lock for {} in project {}", input.path, project);
+ log.atFine().log("Create lock for %s in project %s", input.path, project);
String lockId = toLockId.apply(input.path);
LfsLock lock = locks.getIfPresent(lockId);
if (lock != null) {
throw new LfsLockExistsException(lock);
}
- lock = new LfsLock(lockId, input.path, LfsDateTime.now(), new LfsLockOwner(user.getUserName()));
+ lock =
+ new LfsLock(
+ lockId, input.path, LfsDateTime.now(), new LfsLockOwner(user.getUserName().get()));
LockFile fileLock = new LockFile(locksPath.resolve(lockId).toFile());
try {
if (!fileLock.lock()) {
- log.warn("Cannot lock path [{}] in project {}", input.path, project);
+ log.atWarning().log("Cannot lock path [%s] in project %s", input.path, project);
throw new LfsLockExistsException(lock);
}
} catch (IOException e) {
@@ -115,7 +114,7 @@
String.format(
"Locking path [%s] in project %s failed with error %s",
input.path, project, e.getMessage());
- log.warn(error);
+ log.atWarning().log(error);
throw new LfsException(error);
}
@@ -127,13 +126,13 @@
String.format(
"Locking path [%s] in project %s failed during write with error %s",
input.path, project, e.getMessage());
- log.warn(error);
+ log.atWarning().log(error);
throw new LfsException(error);
}
if (!fileLock.commit()) {
String error =
String.format("Committing lock to path [%s] in project %s failed", input.path, project);
- log.warn(error);
+ log.atWarning().log(error);
throw new LfsException(error);
}
// put lock object to cache while file lock is being hold so that
@@ -155,7 +154,7 @@
String error =
String.format(
"Deleting lock on path [%s] in project %s is not possible", lock.path, project);
- log.warn(error);
+ log.atWarning().log(error);
throw new LfsException(error);
}
} catch (IOException e) {
@@ -163,7 +162,7 @@
String.format(
"Getting lock on path [%s] in project %s failed with error %s",
lock.path, project, e.getMessage());
- log.warn(error);
+ log.atWarning().log(error);
throw new LfsException(error);
}
@@ -175,7 +174,7 @@
String.format(
"Deleting lock on path [%s] in project %s failed with error %s",
lock.path, project, e.getMessage());
- log.warn(error);
+ log.atWarning().log(error);
throw new LfsException(error);
} finally {
fileLock.unlock();
diff --git a/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsPutLocksAction.java b/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsPutLocksAction.java
index ffbcc8d..9e0e23d 100644
--- a/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsPutLocksAction.java
+++ b/src/main/java/com/googlesource/gerrit/plugins/lfs/locks/LfsPutLocksAction.java
@@ -16,22 +16,24 @@
import static com.google.gerrit.extensions.api.lfs.LfsDefinitions.LFS_URL_REGEX_TEMPLATE;
import static com.google.gerrit.extensions.api.lfs.LfsDefinitions.LFS_VERIFICATION_PATH;
+import static com.google.gerrit.server.permissions.ProjectPermission.PUSH_AT_LEAST_ONE_REF;
import static com.googlesource.gerrit.plugins.lfs.locks.LfsGetLocksAction.LFS_LOCKS_URL_PATTERN;
import com.google.common.base.Strings;
-import com.google.gerrit.common.data.Capable;
+import com.google.gerrit.extensions.restapi.AuthException;
import com.google.gerrit.server.CurrentUser;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackend.ForProject;
+import com.google.gerrit.server.permissions.PermissionBackendException;
import com.google.gerrit.server.project.ProjectCache;
-import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.ProjectState;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
-import com.googlesource.gerrit.plugins.lfs.LfsAuthUserProvider;
+import com.googlesource.gerrit.plugins.lfs.auth.LfsAuthUserProvider;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.jgit.lfs.errors.LfsException;
-import org.eclipse.jgit.lfs.errors.LfsUnauthorized;
public class LfsPutLocksAction extends LfsLocksAction {
interface Factory extends LfsLocksAction.Factory<LfsPutLocksAction> {}
@@ -43,11 +45,12 @@
@Inject
LfsPutLocksAction(
+ PermissionBackend permissionBackend,
ProjectCache projectCache,
LfsAuthUserProvider userProvider,
LfsLocksHandler handler,
@Assisted LfsLocksContext context) {
- super(projectCache, userProvider, handler, context);
+ super(permissionBackend, projectCache, userProvider, handler, context);
}
@Override
@@ -74,11 +77,15 @@
}
@Override
- protected void authorizeUser(ProjectControl control) throws LfsUnauthorized {
+ protected void authorizeUser(ForProject project)
+ throws AuthException, PermissionBackendException {
// all operations require push permission
- if (Capable.OK != control.canPushToAtLeastOneRef()) {
- throwUnauthorizedOp(action.getName(), control);
- }
+ project.check(PUSH_AT_LEAST_ONE_REF);
+ }
+
+ @Override
+ protected String getAction() {
+ return action.getName();
}
@Override
diff --git a/src/test/java/com/googlesource/gerrit/plugins/lfs/LfsIT.java b/src/test/java/com/googlesource/gerrit/plugins/lfs/LfsIT.java
new file mode 100644
index 0000000..c71a83c
--- /dev/null
+++ b/src/test/java/com/googlesource/gerrit/plugins/lfs/LfsIT.java
@@ -0,0 +1,55 @@
+// 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.lfs;
+
+import com.google.gerrit.acceptance.LightweightPluginDaemonTest;
+import com.google.gerrit.acceptance.TestPlugin;
+import com.google.gerrit.reviewdb.client.Project;
+import com.google.gerrit.testing.ConfigSuite;
+import org.eclipse.jgit.lib.Config;
+import org.junit.Test;
+
+@TestPlugin(
+ name = "lfs",
+ sysModule = "com.googlesource.gerrit.plugins.lfs.Module",
+ httpModule = "com.googlesource.gerrit.plugins.lfs.HttpModule",
+ sshModule = "com.googlesource.gerrit.plugins.lfs.SshModule")
+public class LfsIT extends LightweightPluginDaemonTest {
+ @ConfigSuite.Default
+ public static Config enablePlugin() {
+ Config cfg = new Config();
+ cfg.setString("lfs", null, "plugin", "lfs");
+ return cfg;
+ }
+
+ @Test
+ public void globalConfigCanBeReadByAdmin() throws Exception {
+ adminRestSession.get(globalConfig(allProjects)).assertOK();
+ }
+
+ @Test
+ public void globalConfigCannotBeReadByNonAdmin() throws Exception {
+ userRestSession.get(globalConfig(allProjects)).assertNotFound();
+ }
+
+ @Test
+ public void globalConfigCannotBeReadOnOtherProject() throws Exception {
+ adminRestSession.get(globalConfig(project)).assertNotFound();
+ }
+
+ private static String globalConfig(Project.NameKey name) {
+ return String.format("/projects/%s/lfs:config-global", name.get());
+ }
+}
diff --git a/src/test/java/com/googlesource/gerrit/plugins/lfs/LfsAuthTokenTest.java b/src/test/java/com/googlesource/gerrit/plugins/lfs/auth/LfsAuthTokenTest.java
similarity index 96%
rename from src/test/java/com/googlesource/gerrit/plugins/lfs/LfsAuthTokenTest.java
rename to src/test/java/com/googlesource/gerrit/plugins/lfs/auth/LfsAuthTokenTest.java
index f41307b..bdf7c21 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/lfs/LfsAuthTokenTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/lfs/auth/LfsAuthTokenTest.java
@@ -12,10 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.googlesource.gerrit.plugins.lfs;
+package com.googlesource.gerrit.plugins.lfs.auth;
import static com.google.common.truth.Truth.assertThat;
+import com.googlesource.gerrit.plugins.lfs.LfsDateTime;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
@@ -30,9 +31,7 @@
TestTokenProessor processor = new TestTokenProessor(cipher);
TestToken token = new TestToken(Instant.now(), 0L);
String serialized = processor.serialize(token);
-
assertThat(serialized).isNotEmpty();
-
Optional<TestToken> deserialized = processor.deserialize(serialized);
assertThat(deserialized.isPresent()).isTrue();
assertThat(token.issued).isEqualTo(deserialized.get().issued);
diff --git a/src/test/java/com/googlesource/gerrit/plugins/lfs/LfsCipherTest.java b/src/test/java/com/googlesource/gerrit/plugins/lfs/auth/LfsCipherTest.java
similarity index 97%
rename from src/test/java/com/googlesource/gerrit/plugins/lfs/LfsCipherTest.java
rename to src/test/java/com/googlesource/gerrit/plugins/lfs/auth/LfsCipherTest.java
index b092a48..08d8dc8 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/lfs/LfsCipherTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/lfs/auth/LfsCipherTest.java
@@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package com.googlesource.gerrit.plugins.lfs;
+package com.googlesource.gerrit.plugins.lfs.auth;
import static com.google.common.truth.Truth.assertThat;
diff --git a/src/test/java/com/googlesource/gerrit/plugins/lfs/fs/LfsFsRequestAuthorizerTest.java b/src/test/java/com/googlesource/gerrit/plugins/lfs/fs/LfsFsRequestAuthorizerTest.java
index 8cd7225..d2b38c2 100644
--- a/src/test/java/com/googlesource/gerrit/plugins/lfs/fs/LfsFsRequestAuthorizerTest.java
+++ b/src/test/java/com/googlesource/gerrit/plugins/lfs/fs/LfsFsRequestAuthorizerTest.java
@@ -17,8 +17,8 @@
import static com.google.common.truth.Truth.assertThat;
import static org.eclipse.jgit.lfs.lib.LongObjectId.zeroId;
-import com.googlesource.gerrit.plugins.lfs.AuthInfo;
-import com.googlesource.gerrit.plugins.lfs.LfsCipher;
+import com.googlesource.gerrit.plugins.lfs.auth.AuthInfo;
+import com.googlesource.gerrit.plugins.lfs.auth.LfsCipher;
import com.googlesource.gerrit.plugins.lfs.fs.LfsFsRequestAuthorizer.Processor;
import java.time.Instant;
import org.eclipse.jgit.lfs.lib.LongObjectId;