github.com/sap/cf-mta-plugin@v2.6.3+incompatible/clients/csrf/default_csrf_token_manager.go (about) 1 package csrf 2 3 import ( 4 "net/http" 5 ) 6 7 const XCsrfHeader = "X-Csrf-Header" 8 const XCsrfToken = "X-Csrf-Token" 9 const CsrfTokenHeaderRequiredValue = "Required" 10 11 type DefaultCsrfTokenManager struct { 12 request *http.Request 13 transport *Transport 14 csrfTokenFetcher CsrfTokenFetcher 15 } 16 17 func NewDefaultCsrfTokenManager(transport *Transport, request *http.Request) *DefaultCsrfTokenManager { 18 return &DefaultCsrfTokenManager{request: request, transport: transport, csrfTokenFetcher: NewDefaultCsrfTokenFetcher(transport)} 19 } 20 21 func NewDefaultCsrfTokenManagerWithFetcher(transport *Transport, request *http.Request, csrfTokenFetcher CsrfTokenFetcher) *DefaultCsrfTokenManager { 22 return &DefaultCsrfTokenManager{request: request, transport: transport, csrfTokenFetcher: csrfTokenFetcher} 23 } 24 25 func (c *DefaultCsrfTokenManager) updateToken() error { 26 if !c.shouldInitialize() { 27 return nil 28 } 29 err := c.initializeToken(false) 30 if err != nil { 31 return err 32 } 33 34 c.updateTokenInRequest() 35 36 return nil 37 } 38 39 func (c *DefaultCsrfTokenManager) initializeToken(forceInitializing bool) error { 40 if forceInitializing || !c.transport.Csrf.IsInitialized { 41 var err error 42 csrfToken, err := c.csrfTokenFetcher.FetchCsrfToken(getCsrfTokenUrl(c.request), c.request) 43 if csrfToken == nil { 44 return nil 45 } 46 c.transport.Csrf.Header, c.transport.Csrf.Token = csrfToken.CsrfTokenHeader, csrfToken.CsrfTokenValue 47 if err != nil { 48 return err 49 } 50 c.transport.Csrf.IsInitialized = true 51 } 52 53 return nil 54 } 55 56 func (c *DefaultCsrfTokenManager) refreshTokenIfNeeded(response *http.Response) (bool, error) { 57 if !c.isProtectionRequired(c.request, c.transport) { 58 return false, nil 59 } 60 if c.transport.Csrf.IsInitialized && (response.StatusCode == http.StatusForbidden) { 61 csrfToken := response.Header.Get(XCsrfToken) 62 63 if CsrfTokenHeaderRequiredValue == csrfToken { 64 err := c.initializeToken(true) 65 if err != nil { 66 return false, err 67 } 68 // the token was refreshed successfully so the client should retry the request 69 return c.transport.Csrf.Token != "", nil 70 } 71 } 72 73 return false, nil 74 } 75 76 func (c *DefaultCsrfTokenManager) updateTokenInRequest() { 77 if c.transport.Csrf.Token != "" && c.transport.Csrf.Header != "" { 78 c.request.Header.Set(XCsrfToken, c.transport.Csrf.Token) 79 c.request.Header.Set(XCsrfHeader, c.transport.Csrf.Header) 80 } 81 } 82 83 func (c *DefaultCsrfTokenManager) isProtectionRequired(req *http.Request, t *Transport) bool { 84 return !t.Csrf.NonProtectedMethods[req.Method] 85 } 86 87 func (c *DefaultCsrfTokenManager) shouldInitialize() bool { 88 return c.request != nil && c.isProtectionRequired(c.request, c.transport) 89 }