(ctx context.Context, req *adminv1.PullVirtualRepoRequest)
| 95 | } |
| 96 | |
| 97 | func (s *Server) PullVirtualRepo(ctx context.Context, req *adminv1.PullVirtualRepoRequest) (*adminv1.PullVirtualRepoResponse, error) { |
| 98 | observability.AddRequestAttributes(ctx, |
| 99 | attribute.String("args.project_id", req.ProjectId), |
| 100 | attribute.Int("args.page_size", int(req.PageSize)), |
| 101 | attribute.String("args.page_token", req.PageToken), |
| 102 | ) |
| 103 | |
| 104 | proj, err := s.admin.DB.FindProject(ctx, req.ProjectId) |
| 105 | if err != nil { |
| 106 | return nil, err |
| 107 | } |
| 108 | |
| 109 | claims := auth.GetClaims(ctx) |
| 110 | permissions := claims.ProjectPermissions(ctx, proj.OrganizationID, proj.ID) |
| 111 | forceAccess := claims.Superuser(ctx) && req.SuperuserForceAccess |
| 112 | if !permissions.ReadProdStatus && !permissions.ReadDevStatus && !forceAccess { |
| 113 | return nil, status.Error(codes.PermissionDenied, "does not have permission to read project repo") |
| 114 | } |
| 115 | |
| 116 | var depl *database.Deployment |
| 117 | if claims.OwnerType() == auth.OwnerTypeDeployment { |
| 118 | var err error |
| 119 | depl, err = s.admin.DB.FindDeployment(ctx, claims.OwnerID()) |
| 120 | if err != nil { |
| 121 | return nil, err |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | environment := "prod" |
| 126 | if depl != nil { |
| 127 | environment = depl.Environment |
| 128 | } |
| 129 | |
| 130 | pageToken, err := unmarshalStringTimestampPageToken(req.PageToken) |
| 131 | if err != nil { |
| 132 | return nil, err |
| 133 | } |
| 134 | pageSize := validPageSize(req.PageSize) |
| 135 | |
| 136 | vfs, err := s.admin.DB.FindVirtualFiles(ctx, proj.ID, environment, pageToken.Ts.AsTime(), pageToken.Str, pageSize) |
| 137 | if err != nil { |
| 138 | return nil, err |
| 139 | } |
| 140 | |
| 141 | // If no files were found, we return the same page token as the next page token. |
| 142 | // This enables the client to poll for new changes continuously. (The client is responsible for pausing when an empty page is returned.) |
| 143 | nextToken := req.PageToken |
| 144 | if len(vfs) > 0 { |
| 145 | f := vfs[len(vfs)-1] |
| 146 | nextToken = marshalStringTimestampPageToken(f.Path, f.UpdatedOn) |
| 147 | } |
| 148 | |
| 149 | dtos := make([]*adminv1.VirtualFile, len(vfs)) |
| 150 | for i, vf := range vfs { |
| 151 | dtos[i] = virtualFileToDTO(vf) |
| 152 | } |
| 153 | |
| 154 | return &adminv1.PullVirtualRepoResponse{ |
nothing calls this directly
no test coverage detected