
Gerrit had some trouble with enabling Git Protocol V2 with refs-in-wants support at the end of 2018. The origin for this trouble was that JGit and Gerrit maintainers had no defined API for how visiblity is enforced. In fact, JGit doesn't promise any visibility enforcements. Gerrit previously used an AdvertiseRefsHook to filter refs by visibility before advertising them. Only advertised refs were fetchable (given that no additional settings were provided). With the Git Protocol advancing, this assumption is not safe anymore and we need stronger guarantees to make sure Gerrit and JGit play well together when it comes to security. This change is a proposal to solve the dilemma by providing a custom repository to JGit. The repository provides a RefDatabase that is permission-aware and will only ever return refs that the user has access to. This way, Gerrit is resilient against whatever changes are made in JGit because we never expose invisible refs or rely on any JGit filter functionality. JGit's Repository object was unfortunately not meant to be extended and wrapped. It is an abstract class (not an interface) that has two direct implementations in JGit: FileRepository and DFSRepository (abstract). We can either subclass Repository directly - which is what this change is doing - or subclass the two implementations separately. Best case, we would change Repository to be an interface instead and stop bothering, but this seems unfeasible at least for now. This change preserves advertise refs hook: DefaultAdvertiseRefsHook. So that the checks are performed twice. Follow-up change will introduce a configuration option to select between DefaultAdvertiseRefsHook or permission aware ref database. Change-Id: Id10f74f20b79a2b7851fc462d6f64acb0c7413a4
40 lines
1.4 KiB
Java
40 lines
1.4 KiB
Java
// 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.google.gerrit.server.git;
|
|
|
|
import com.google.gerrit.server.permissions.PermissionBackend;
|
|
import org.eclipse.jgit.lib.RefDatabase;
|
|
import org.eclipse.jgit.lib.Repository;
|
|
|
|
/**
|
|
* Wrapper around {@link DelegateRepository} that overwrites {@link #getRefDatabase()} to return a
|
|
* {@link PermissionAwareReadOnlyRefDatabase}.
|
|
*/
|
|
public class PermissionAwareRepository extends DelegateRepository {
|
|
|
|
private final PermissionAwareReadOnlyRefDatabase permissionAwareReadOnlyRefDatabase;
|
|
|
|
public PermissionAwareRepository(Repository delegate, PermissionBackend.ForProject forProject) {
|
|
super(delegate);
|
|
this.permissionAwareReadOnlyRefDatabase =
|
|
new PermissionAwareReadOnlyRefDatabase(delegate, forProject);
|
|
}
|
|
|
|
@Override
|
|
public RefDatabase getRefDatabase() {
|
|
return permissionAwareReadOnlyRefDatabase;
|
|
}
|
|
}
|