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.extensions.restapi.AuthException; 18 : import com.google.gerrit.extensions.restapi.ResourceNotFoundException; 19 : import com.google.gerrit.extensions.restapi.Response; 20 : import com.google.gerrit.extensions.restapi.RestReadView; 21 : import com.google.gerrit.server.git.GitRepositoryManager; 22 : import com.google.gerrit.server.permissions.PermissionBackend; 23 : import com.google.gerrit.server.permissions.PermissionBackendException; 24 : import com.google.gerrit.server.permissions.ProjectPermission; 25 : import com.google.gerrit.server.permissions.RefPermission; 26 : import com.google.gerrit.server.project.ProjectResource; 27 : import com.google.inject.Inject; 28 : import com.google.inject.Singleton; 29 : import java.io.IOException; 30 : import org.eclipse.jgit.errors.IncorrectObjectTypeException; 31 : import org.eclipse.jgit.errors.MissingObjectException; 32 : import org.eclipse.jgit.errors.RepositoryNotFoundException; 33 : import org.eclipse.jgit.lib.Constants; 34 : import org.eclipse.jgit.lib.Ref; 35 : import org.eclipse.jgit.lib.Repository; 36 : import org.eclipse.jgit.revwalk.RevCommit; 37 : import org.eclipse.jgit.revwalk.RevWalk; 38 : 39 : @Singleton 40 : public class GetHead implements RestReadView<ProjectResource> { 41 : private final GitRepositoryManager repoManager; 42 : private final CommitsCollection commits; 43 : private final PermissionBackend permissionBackend; 44 : 45 : @Inject 46 : GetHead( 47 : GitRepositoryManager repoManager, 48 : CommitsCollection commits, 49 146 : PermissionBackend permissionBackend) { 50 146 : this.repoManager = repoManager; 51 146 : this.commits = commits; 52 146 : this.permissionBackend = permissionBackend; 53 146 : } 54 : 55 : @Override 56 : public Response<String> apply(ProjectResource rsrc) 57 : throws AuthException, ResourceNotFoundException, IOException, PermissionBackendException { 58 3 : rsrc.getProjectState().statePermitsRead(); 59 3 : try (Repository repo = repoManager.openRepository(rsrc.getNameKey())) { 60 3 : Ref head = repo.getRefDatabase().exactRef(Constants.HEAD); 61 3 : if (head == null) { 62 0 : throw new ResourceNotFoundException(Constants.HEAD); 63 3 : } else if (head.isSymbolic()) { 64 3 : String n = head.getTarget().getName(); 65 3 : permissionBackend 66 3 : .user(rsrc.getUser()) 67 3 : .project(rsrc.getNameKey()) 68 3 : .ref(n) 69 3 : .check(RefPermission.READ); 70 3 : return Response.ok(n); 71 0 : } else if (head.getObjectId() != null) { 72 0 : try (RevWalk rw = new RevWalk(repo)) { 73 0 : RevCommit commit = rw.parseCommit(head.getObjectId()); 74 0 : if (commits.canRead(rsrc.getProjectState(), repo, commit)) { 75 0 : return Response.ok(head.getObjectId().name()); 76 : } 77 0 : throw new AuthException("not allowed to see HEAD"); 78 0 : } catch (MissingObjectException | IncorrectObjectTypeException e) { 79 : try { 80 0 : permissionBackend 81 0 : .user(rsrc.getUser()) 82 0 : .project(rsrc.getNameKey()) 83 0 : .check(ProjectPermission.WRITE_CONFIG); 84 0 : } catch (AuthException ae) { 85 0 : throw new AuthException("not allowed to see HEAD", ae); 86 0 : } 87 : } 88 : } 89 0 : throw new ResourceNotFoundException(Constants.HEAD); 90 3 : } catch (RepositoryNotFoundException e) { 91 0 : throw new ResourceNotFoundException(rsrc.getName(), e); 92 : } 93 : } 94 : }