Line data Source code
1 : // Copyright (C) 2013 The Android Open Source Project 2 : // 3 : // Licensed under the Apache License, Version 2.0 (the "License"); 4 : // you may not use this file except in compliance with the License. 5 : // You may obtain a copy of the License at 6 : // 7 : // http://www.apache.org/licenses/LICENSE-2.0 8 : // 9 : // Unless required by applicable law or agreed to in writing, software 10 : // distributed under the License is distributed on an "AS IS" BASIS, 11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 : // See the License for the specific language governing permissions and 13 : // limitations under the License. 14 : 15 : package com.google.gerrit.server.restapi.project; 16 : 17 : import com.google.gerrit.entities.Project; 18 : import com.google.gerrit.entities.RefNames; 19 : import com.google.gerrit.extensions.registration.DynamicMap; 20 : import com.google.gerrit.extensions.restapi.ChildCollection; 21 : import com.google.gerrit.extensions.restapi.IdString; 22 : import com.google.gerrit.extensions.restapi.ResourceNotFoundException; 23 : import com.google.gerrit.extensions.restapi.RestApiException; 24 : import com.google.gerrit.extensions.restapi.RestView; 25 : import com.google.gerrit.server.git.GitRepositoryManager; 26 : import com.google.gerrit.server.permissions.PermissionBackend; 27 : import com.google.gerrit.server.permissions.PermissionBackendException; 28 : import com.google.gerrit.server.permissions.RefPermission; 29 : import com.google.gerrit.server.project.BranchResource; 30 : import com.google.gerrit.server.project.ProjectResource; 31 : import com.google.inject.Inject; 32 : import com.google.inject.Provider; 33 : import com.google.inject.Singleton; 34 : import java.io.IOException; 35 : import org.eclipse.jgit.errors.RepositoryNotFoundException; 36 : import org.eclipse.jgit.lib.Ref; 37 : import org.eclipse.jgit.lib.Repository; 38 : 39 : @Singleton 40 : public class BranchesCollection implements ChildCollection<ProjectResource, BranchResource> { 41 : private final DynamicMap<RestView<BranchResource>> views; 42 : private final Provider<ListBranches> list; 43 : private final PermissionBackend permissionBackend; 44 : private final GitRepositoryManager repoManager; 45 : 46 : @Inject 47 : BranchesCollection( 48 : DynamicMap<RestView<BranchResource>> views, 49 : Provider<ListBranches> list, 50 : PermissionBackend permissionBackend, 51 144 : GitRepositoryManager repoManager) { 52 144 : this.views = views; 53 144 : this.list = list; 54 144 : this.permissionBackend = permissionBackend; 55 144 : this.repoManager = repoManager; 56 144 : } 57 : 58 : @Override 59 : public RestView<ProjectResource> list() { 60 1 : return list.get(); 61 : } 62 : 63 : @Override 64 : public BranchResource parse(ProjectResource parent, IdString id) 65 : throws RestApiException, IOException, PermissionBackendException { 66 19 : parent.getProjectState().checkStatePermitsRead(); 67 19 : Project.NameKey project = parent.getNameKey(); 68 19 : try (Repository repo = repoManager.openRepository(project)) { 69 19 : Ref ref = repo.exactRef(RefNames.fullName(id.get())); 70 19 : if (ref == null) { 71 6 : throw new ResourceNotFoundException(id); 72 : } 73 : 74 : // ListBranches checks the target of a symbolic reference to determine access 75 : // rights on the symbolic reference itself. This check prevents seeing a hidden 76 : // branch simply because the symbolic reference name was visible. 77 18 : boolean canRead = 78 : permissionBackend 79 18 : .currentUser() 80 18 : .project(project) 81 18 : .ref(ref.isSymbolic() ? ref.getTarget().getName() : ref.getName()) 82 18 : .test(RefPermission.READ); 83 18 : if (canRead) { 84 18 : return new BranchResource(parent.getProjectState(), parent.getUser(), ref); 85 : } 86 3 : throw new ResourceNotFoundException(id); 87 0 : } catch (RepositoryNotFoundException noRepo) { 88 0 : throw new ResourceNotFoundException(id, noRepo); 89 : } 90 : } 91 : 92 : @Override 93 : public DynamicMap<RestView<BranchResource>> views() { 94 7 : return views; 95 : } 96 : }