github.com/pf-qiu/concourse/v6@v6.7.3-0.20201207032516-1f455d73275f/atc/api/auth/check_pipeline_access_handler_test.go (about)

     1  package auth_test
     2  
     3  import (
     4  	"errors"
     5  	"net/http"
     6  	"net/http/httptest"
     7  
     8  	"github.com/pf-qiu/concourse/v6/atc/api/accessor"
     9  	"github.com/pf-qiu/concourse/v6/atc/api/accessor/accessorfakes"
    10  	"github.com/pf-qiu/concourse/v6/atc/api/auth"
    11  	"github.com/pf-qiu/concourse/v6/atc/auditor/auditorfakes"
    12  	"github.com/pf-qiu/concourse/v6/atc/db"
    13  	"github.com/pf-qiu/concourse/v6/atc/db/dbfakes"
    14  
    15  	. "github.com/onsi/ginkgo"
    16  	. "github.com/onsi/gomega"
    17  )
    18  
    19  var _ = Describe("CheckPipelineAccessHandler", func() {
    20  	var (
    21  		response    *http.Response
    22  		server      *httptest.Server
    23  		delegate    *pipelineDelegateHandler
    24  		teamFactory *dbfakes.FakeTeamFactory
    25  		team        *dbfakes.FakeTeam
    26  		pipeline    *dbfakes.FakePipeline
    27  		handler     http.Handler
    28  
    29  		fakeAccessor *accessorfakes.FakeAccessFactory
    30  		fakeaccess   *accessorfakes.FakeAccess
    31  	)
    32  
    33  	BeforeEach(func() {
    34  		teamFactory = new(dbfakes.FakeTeamFactory)
    35  		team = new(dbfakes.FakeTeam)
    36  		teamFactory.FindTeamReturns(team, true, nil)
    37  
    38  		pipeline = new(dbfakes.FakePipeline)
    39  
    40  		handlerFactory := auth.NewCheckPipelineAccessHandlerFactory(teamFactory)
    41  		fakeAccessor = new(accessorfakes.FakeAccessFactory)
    42  		fakeaccess = new(accessorfakes.FakeAccess)
    43  
    44  		delegate = &pipelineDelegateHandler{}
    45  		innerHandler := handlerFactory.HandlerFor(delegate, auth.UnauthorizedRejector{})
    46  
    47  		handler = accessor.NewHandler(
    48  			logger,
    49  			"some-action",
    50  			innerHandler,
    51  			fakeAccessor,
    52  			new(auditorfakes.FakeAuditor),
    53  			map[string]string{},
    54  		)
    55  	})
    56  
    57  	JustBeforeEach(func() {
    58  		fakeAccessor.CreateReturns(fakeaccess, nil)
    59  		server = httptest.NewServer(handler)
    60  
    61  		request, err := http.NewRequest("POST", server.URL+"?:team_name=some-team&:pipeline_name=some-pipeline", nil)
    62  		Expect(err).NotTo(HaveOccurred())
    63  
    64  		response, err = new(http.Client).Do(request)
    65  		Expect(err).NotTo(HaveOccurred())
    66  	})
    67  
    68  	var _ = AfterEach(func() {
    69  		server.Close()
    70  	})
    71  
    72  	Context("When team is not returned", func() {
    73  		Context("when it returns an error", func() {
    74  			BeforeEach(func() {
    75  				teamFactory.FindTeamReturns(nil, false, errors.New("some-error"))
    76  			})
    77  			It("returns an interneral server error", func() {
    78  				Expect(response.StatusCode).To(Equal(http.StatusInternalServerError))
    79  			})
    80  		})
    81  		Context("when team is not found", func() {
    82  			BeforeEach(func() {
    83  				teamFactory.FindTeamReturns(nil, false, nil)
    84  			})
    85  			It("returns not found error", func() {
    86  				Expect(response.StatusCode).To(Equal(http.StatusNotFound))
    87  			})
    88  		})
    89  
    90  	})
    91  
    92  	Context("when pipeline exists", func() {
    93  		BeforeEach(func() {
    94  			pipeline.NameReturns("some-pipeline")
    95  			team.PipelineReturns(pipeline, true, nil)
    96  		})
    97  
    98  		Context("when pipeline is public", func() {
    99  			BeforeEach(func() {
   100  				pipeline.PublicReturns(true)
   101  			})
   102  
   103  			It("calls pipelineScopedHandler with pipelineDB in context", func() {
   104  				Expect(delegate.IsCalled).To(BeTrue())
   105  				Expect(delegate.ContextPipelineDB).To(BeIdenticalTo(pipeline))
   106  			})
   107  
   108  			It("returns 200 OK", func() {
   109  				Expect(response.StatusCode).To(Equal(http.StatusOK))
   110  			})
   111  		})
   112  
   113  		Context("when pipeline is private", func() {
   114  			BeforeEach(func() {
   115  				pipeline.PublicReturns(false)
   116  			})
   117  
   118  			Context("and authorized", func() {
   119  				BeforeEach(func() {
   120  					fakeaccess.IsAuthenticatedReturns(true)
   121  					fakeaccess.IsAuthorizedReturns(true)
   122  				})
   123  
   124  				It("calls pipelineScopedHandler with pipelineDB in context", func() {
   125  					Expect(delegate.IsCalled).To(BeTrue())
   126  					Expect(delegate.ContextPipelineDB).To(BeIdenticalTo(pipeline))
   127  				})
   128  
   129  				It("returns 200 OK", func() {
   130  					Expect(response.StatusCode).To(Equal(http.StatusOK))
   131  				})
   132  			})
   133  
   134  			Context("and unauthorized", func() {
   135  				BeforeEach(func() {
   136  					fakeaccess.IsAuthorizedReturns(false)
   137  				})
   138  
   139  				Context("and is authenticated", func() {
   140  					BeforeEach(func() {
   141  						fakeaccess.IsAuthenticatedReturns(true)
   142  					})
   143  
   144  					It("returns 403 Forbidden", func() {
   145  						Expect(response.StatusCode).To(Equal(http.StatusForbidden))
   146  					})
   147  				})
   148  
   149  				Context("and not authenticated", func() {
   150  					BeforeEach(func() {
   151  						fakeaccess.IsAuthenticatedReturns(false)
   152  					})
   153  
   154  					It("returns 401 Unauthorized", func() {
   155  						Expect(response.StatusCode).To(Equal(http.StatusUnauthorized))
   156  					})
   157  				})
   158  			})
   159  		})
   160  	})
   161  
   162  	Context("when pipeline does not exist", func() {
   163  		BeforeEach(func() {
   164  			team.PipelineReturns(nil, false, nil)
   165  		})
   166  
   167  		It("returns 404", func() {
   168  			Expect(response.StatusCode).To(Equal(http.StatusNotFound))
   169  		})
   170  
   171  		It("does not call the scoped handler", func() {
   172  			Expect(delegate.IsCalled).To(BeFalse())
   173  		})
   174  	})
   175  
   176  	Context("when getting pipeline fails", func() {
   177  		BeforeEach(func() {
   178  			team.PipelineReturns(nil, false, errors.New("disaster"))
   179  		})
   180  
   181  		It("returns 500", func() {
   182  			Expect(response.StatusCode).To(Equal(http.StatusInternalServerError))
   183  		})
   184  
   185  		It("does not call the scoped handler", func() {
   186  			Expect(delegate.IsCalled).To(BeFalse())
   187  		})
   188  	})
   189  })
   190  
   191  type pipelineDelegateHandler struct {
   192  	IsCalled          bool
   193  	ContextPipelineDB db.Pipeline
   194  }
   195  
   196  func (handler *pipelineDelegateHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
   197  	handler.IsCalled = true
   198  	handler.ContextPipelineDB = r.Context().Value(auth.PipelineContextKey).(db.Pipeline)
   199  }