Files
gerrit/java/com/google/gerrit/server/git/PermissionAwareRepository.java
Patrick Hiesel 04f1abe7b5 Implement PermissionAwareRefDatabase
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
2019-10-01 15:30:51 +00:00

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;
}
}