github.com/chenbh/concourse/v6@v6.4.2/atc/wrappa/api_auth_wrappa_test.go (about) 1 package wrappa_test 2 3 import ( 4 "net/http" 5 6 "github.com/chenbh/concourse/v6/atc" 7 "github.com/chenbh/concourse/v6/atc/api/auth" 8 "github.com/chenbh/concourse/v6/atc/db/dbfakes" 9 "github.com/chenbh/concourse/v6/atc/wrappa" 10 . "github.com/onsi/ginkgo" 11 . "github.com/onsi/gomega" 12 "github.com/tedsuo/rata" 13 ) 14 15 var _ = Describe("APIAuthWrappa", func() { 16 var ( 17 rejector auth.Rejector 18 fakeCheckPipelineAccessHandlerFactory auth.CheckPipelineAccessHandlerFactory 19 fakeCheckBuildReadAccessHandlerFactory auth.CheckBuildReadAccessHandlerFactory 20 fakeCheckBuildWriteAccessHandlerFactory auth.CheckBuildWriteAccessHandlerFactory 21 fakeCheckWorkerTeamAccessHandlerFactory auth.CheckWorkerTeamAccessHandlerFactory 22 fakeBuildFactory *dbfakes.FakeBuildFactory 23 ) 24 25 BeforeEach(func() { 26 fakeTeamFactory := new(dbfakes.FakeTeamFactory) 27 workerFactory := new(dbfakes.FakeWorkerFactory) 28 fakeBuildFactory = new(dbfakes.FakeBuildFactory) 29 fakeCheckPipelineAccessHandlerFactory = auth.NewCheckPipelineAccessHandlerFactory( 30 fakeTeamFactory, 31 ) 32 rejector = auth.UnauthorizedRejector{} 33 34 fakeCheckBuildReadAccessHandlerFactory = auth.NewCheckBuildReadAccessHandlerFactory(fakeBuildFactory) 35 fakeCheckBuildWriteAccessHandlerFactory = auth.NewCheckBuildWriteAccessHandlerFactory(fakeBuildFactory) 36 fakeCheckWorkerTeamAccessHandlerFactory = auth.NewCheckWorkerTeamAccessHandlerFactory(workerFactory) 37 }) 38 39 authenticateIfTokenProvided := func(handler http.Handler) http.Handler { 40 return auth.CheckAuthenticationIfProvidedHandler( 41 handler, 42 rejector, 43 ) 44 } 45 46 authenticated := func(handler http.Handler) http.Handler { 47 return auth.CheckAuthenticationHandler( 48 handler, 49 rejector, 50 ) 51 } 52 53 authenticatedAndAdmin := func(handler http.Handler) http.Handler { 54 return auth.CheckAdminHandler( 55 handler, 56 rejector, 57 ) 58 } 59 60 authorized := func(handler http.Handler) http.Handler { 61 return auth.CheckAuthorizationHandler( 62 handler, 63 rejector, 64 ) 65 } 66 67 openForPublicPipelineOrAuthorized := func(handler http.Handler) http.Handler { 68 return fakeCheckPipelineAccessHandlerFactory.HandlerFor( 69 handler, 70 rejector, 71 ) 72 } 73 74 doesNotCheckIfPrivateJob := func(handler http.Handler) http.Handler { 75 return fakeCheckBuildReadAccessHandlerFactory.AnyJobHandler( 76 handler, 77 rejector, 78 ) 79 } 80 81 checksIfPrivateJob := func(handler http.Handler) http.Handler { 82 return fakeCheckBuildReadAccessHandlerFactory.CheckIfPrivateJobHandler( 83 handler, 84 rejector, 85 ) 86 } 87 88 checkWritePermissionForBuild := func(handler http.Handler) http.Handler { 89 return fakeCheckBuildWriteAccessHandlerFactory.HandlerFor( 90 handler, 91 rejector, 92 ) 93 } 94 95 checkTeamAccessForWorker := func(handler http.Handler) http.Handler { 96 return fakeCheckWorkerTeamAccessHandlerFactory.HandlerFor( 97 handler, 98 rejector, 99 ) 100 } 101 102 Describe("Wrap", func() { 103 var ( 104 inputHandlers rata.Handlers 105 expectedHandlers rata.Handlers 106 107 wrappedHandlers rata.Handlers 108 ) 109 110 BeforeEach(func() { 111 inputHandlers = rata.Handlers{} 112 113 for _, route := range atc.Routes { 114 inputHandlers[route.Name] = &stupidHandler{} 115 } 116 117 expectedHandlers = rata.Handlers{ 118 119 // authorized or public pipeline 120 atc.GetBuild: doesNotCheckIfPrivateJob(inputHandlers[atc.GetBuild]), 121 atc.BuildResources: doesNotCheckIfPrivateJob(inputHandlers[atc.BuildResources]), 122 123 // authorized or public pipeline and public job 124 atc.BuildEvents: checksIfPrivateJob(inputHandlers[atc.BuildEvents]), 125 atc.ListBuildArtifacts: checksIfPrivateJob(inputHandlers[atc.ListBuildArtifacts]), 126 atc.GetBuildPreparation: checksIfPrivateJob(inputHandlers[atc.GetBuildPreparation]), 127 atc.GetBuildPlan: checksIfPrivateJob(inputHandlers[atc.GetBuildPlan]), 128 129 // resource belongs to authorized team 130 atc.AbortBuild: checkWritePermissionForBuild(inputHandlers[atc.AbortBuild]), 131 132 // resource belongs to authorized team 133 atc.PruneWorker: checkTeamAccessForWorker(inputHandlers[atc.PruneWorker]), 134 atc.LandWorker: checkTeamAccessForWorker(inputHandlers[atc.LandWorker]), 135 atc.ReportWorkerContainers: checkTeamAccessForWorker(inputHandlers[atc.ReportWorkerContainers]), 136 atc.ReportWorkerVolumes: checkTeamAccessForWorker(inputHandlers[atc.ReportWorkerVolumes]), 137 atc.RetireWorker: checkTeamAccessForWorker(inputHandlers[atc.RetireWorker]), 138 atc.ListDestroyingContainers: checkTeamAccessForWorker(inputHandlers[atc.ListDestroyingContainers]), 139 atc.ListDestroyingVolumes: checkTeamAccessForWorker(inputHandlers[atc.ListDestroyingVolumes]), 140 141 // belongs to public pipeline or authorized 142 atc.GetPipeline: openForPublicPipelineOrAuthorized(inputHandlers[atc.GetPipeline]), 143 atc.GetJobBuild: openForPublicPipelineOrAuthorized(inputHandlers[atc.GetJobBuild]), 144 atc.PipelineBadge: openForPublicPipelineOrAuthorized(inputHandlers[atc.PipelineBadge]), 145 atc.JobBadge: openForPublicPipelineOrAuthorized(inputHandlers[atc.JobBadge]), 146 atc.ListJobs: openForPublicPipelineOrAuthorized(inputHandlers[atc.ListJobs]), 147 atc.GetJob: openForPublicPipelineOrAuthorized(inputHandlers[atc.GetJob]), 148 atc.ListJobBuilds: openForPublicPipelineOrAuthorized(inputHandlers[atc.ListJobBuilds]), 149 atc.ListPipelineBuilds: openForPublicPipelineOrAuthorized(inputHandlers[atc.ListPipelineBuilds]), 150 atc.GetResource: openForPublicPipelineOrAuthorized(inputHandlers[atc.GetResource]), 151 atc.ListBuildsWithVersionAsInput: openForPublicPipelineOrAuthorized(inputHandlers[atc.ListBuildsWithVersionAsInput]), 152 atc.ListBuildsWithVersionAsOutput: openForPublicPipelineOrAuthorized(inputHandlers[atc.ListBuildsWithVersionAsOutput]), 153 atc.ListResources: openForPublicPipelineOrAuthorized(inputHandlers[atc.ListResources]), 154 atc.ListResourceTypes: openForPublicPipelineOrAuthorized(inputHandlers[atc.ListResourceTypes]), 155 atc.ListResourceVersions: openForPublicPipelineOrAuthorized(inputHandlers[atc.ListResourceVersions]), 156 atc.GetResourceCausality: openForPublicPipelineOrAuthorized(inputHandlers[atc.GetResourceCausality]), 157 atc.GetResourceVersion: openForPublicPipelineOrAuthorized(inputHandlers[atc.GetResourceVersion]), 158 159 // authenticated 160 atc.CreateBuild: authenticated(inputHandlers[atc.CreateBuild]), 161 atc.GetContainer: authenticated(inputHandlers[atc.GetContainer]), 162 atc.HijackContainer: authenticated(inputHandlers[atc.HijackContainer]), 163 atc.ListContainers: authenticated(inputHandlers[atc.ListContainers]), 164 atc.ListVolumes: authenticated(inputHandlers[atc.ListVolumes]), 165 atc.ListTeamBuilds: authenticated(inputHandlers[atc.ListTeamBuilds]), 166 atc.ListWorkers: authenticated(inputHandlers[atc.ListWorkers]), 167 atc.RegisterWorker: authenticated(inputHandlers[atc.RegisterWorker]), 168 atc.HeartbeatWorker: authenticated(inputHandlers[atc.HeartbeatWorker]), 169 atc.DeleteWorker: authenticated(inputHandlers[atc.DeleteWorker]), 170 atc.GetTeam: authenticated(inputHandlers[atc.GetTeam]), 171 atc.SetTeam: authenticated(inputHandlers[atc.SetTeam]), 172 atc.RenameTeam: authenticated(inputHandlers[atc.RenameTeam]), 173 atc.DestroyTeam: authenticated(inputHandlers[atc.DestroyTeam]), 174 atc.GetUser: authenticated(inputHandlers[atc.GetUser]), 175 176 //authenticateIfTokenProvided / delegating to handler 177 atc.GetInfo: authenticateIfTokenProvided(inputHandlers[atc.GetInfo]), 178 atc.GetCheck: authenticateIfTokenProvided(inputHandlers[atc.GetCheck]), 179 atc.DownloadCLI: authenticateIfTokenProvided(inputHandlers[atc.DownloadCLI]), 180 atc.CheckResourceWebHook: authenticateIfTokenProvided(inputHandlers[atc.CheckResourceWebHook]), 181 atc.ListAllPipelines: authenticateIfTokenProvided(inputHandlers[atc.ListAllPipelines]), 182 atc.ListBuilds: authenticateIfTokenProvided(inputHandlers[atc.ListBuilds]), 183 atc.ListPipelines: authenticateIfTokenProvided(inputHandlers[atc.ListPipelines]), 184 atc.ListAllJobs: authenticateIfTokenProvided(inputHandlers[atc.ListAllJobs]), 185 atc.ListAllResources: authenticateIfTokenProvided(inputHandlers[atc.ListAllResources]), 186 atc.ListTeams: authenticateIfTokenProvided(inputHandlers[atc.ListTeams]), 187 atc.MainJobBadge: authenticateIfTokenProvided(inputHandlers[atc.MainJobBadge]), 188 atc.GetWall: authenticateIfTokenProvided(inputHandlers[atc.GetWall]), 189 190 // authenticated and is admin 191 atc.GetLogLevel: authenticatedAndAdmin(inputHandlers[atc.GetLogLevel]), 192 atc.SetLogLevel: authenticatedAndAdmin(inputHandlers[atc.SetLogLevel]), 193 atc.GetInfoCreds: authenticatedAndAdmin(inputHandlers[atc.GetInfoCreds]), 194 atc.ListActiveUsersSince: authenticatedAndAdmin(inputHandlers[atc.ListActiveUsersSince]), 195 atc.SetWall: authenticatedAndAdmin(inputHandlers[atc.SetWall]), 196 atc.ClearWall: authenticatedAndAdmin(inputHandlers[atc.ClearWall]), 197 198 // authorized (requested team matches resource team) 199 atc.CheckResource: authorized(inputHandlers[atc.CheckResource]), 200 atc.CheckResourceType: authorized(inputHandlers[atc.CheckResourceType]), 201 atc.CreateJobBuild: authorized(inputHandlers[atc.CreateJobBuild]), 202 atc.RerunJobBuild: authorized(inputHandlers[atc.RerunJobBuild]), 203 atc.DeletePipeline: authorized(inputHandlers[atc.DeletePipeline]), 204 atc.DisableResourceVersion: authorized(inputHandlers[atc.DisableResourceVersion]), 205 atc.EnableResourceVersion: authorized(inputHandlers[atc.EnableResourceVersion]), 206 atc.PinResourceVersion: authorized(inputHandlers[atc.PinResourceVersion]), 207 atc.UnpinResource: authorized(inputHandlers[atc.UnpinResource]), 208 atc.SetPinCommentOnResource: authorized(inputHandlers[atc.SetPinCommentOnResource]), 209 atc.GetConfig: authorized(inputHandlers[atc.GetConfig]), 210 atc.GetCC: authorized(inputHandlers[atc.GetCC]), 211 atc.GetVersionsDB: authorized(inputHandlers[atc.GetVersionsDB]), 212 atc.ListJobInputs: authorized(inputHandlers[atc.ListJobInputs]), 213 atc.OrderPipelines: authorized(inputHandlers[atc.OrderPipelines]), 214 atc.PauseJob: authorized(inputHandlers[atc.PauseJob]), 215 atc.PausePipeline: authorized(inputHandlers[atc.PausePipeline]), 216 atc.ArchivePipeline: authorized(inputHandlers[atc.ArchivePipeline]), 217 atc.RenamePipeline: authorized(inputHandlers[atc.RenamePipeline]), 218 atc.SaveConfig: authorized(inputHandlers[atc.SaveConfig]), 219 atc.UnpauseJob: authorized(inputHandlers[atc.UnpauseJob]), 220 atc.ScheduleJob: authorized(inputHandlers[atc.ScheduleJob]), 221 atc.UnpausePipeline: authorized(inputHandlers[atc.UnpausePipeline]), 222 atc.ExposePipeline: authorized(inputHandlers[atc.ExposePipeline]), 223 atc.HidePipeline: authorized(inputHandlers[atc.HidePipeline]), 224 atc.CreatePipelineBuild: authorized(inputHandlers[atc.CreatePipelineBuild]), 225 atc.ClearTaskCache: authorized(inputHandlers[atc.ClearTaskCache]), 226 atc.CreateArtifact: authorized(inputHandlers[atc.CreateArtifact]), 227 atc.GetArtifact: authorized(inputHandlers[atc.GetArtifact]), 228 } 229 }) 230 231 JustBeforeEach(func() { 232 wrappedHandlers = wrappa.NewAPIAuthWrappa( 233 fakeCheckPipelineAccessHandlerFactory, 234 fakeCheckBuildReadAccessHandlerFactory, 235 fakeCheckBuildWriteAccessHandlerFactory, 236 fakeCheckWorkerTeamAccessHandlerFactory, 237 ).Wrap(inputHandlers) 238 239 }) 240 241 It("validates sensitive routes, and noop validates public routes", func() { 242 for name, _ := range inputHandlers { 243 Expect(wrappedHandlers[name]).To(BeIdenticalTo(expectedHandlers[name])) 244 } 245 }) 246 }) 247 })