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