basic.go 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. package authn
  2. import (
  3. "context"
  4. "fmt"
  5. "net/http"
  6. "strconv"
  7. "github.com/porter-dev/porter/api/server/shared/apierrors"
  8. "github.com/porter-dev/porter/provisioner/server/config"
  9. )
  10. // AuthNFactory generates a middleware handler `AuthN`
  11. type AuthNBasicFactory struct {
  12. config *config.Config
  13. }
  14. // NewAuthNBasicFactory returns an `AuthNBasicFactory` that uses the passed-in server
  15. // config
  16. func NewAuthNBasicFactory(
  17. config *config.Config,
  18. ) *AuthNBasicFactory {
  19. return &AuthNBasicFactory{config}
  20. }
  21. // NewAuthenticated creates a new instance of `AuthN` that implements the http.Handler
  22. // interface.
  23. func (f *AuthNBasicFactory) NewAuthenticated(next http.Handler) http.Handler {
  24. return &AuthNBasic{next, f.config}
  25. }
  26. // AuthNStatic implements the authentication middleware
  27. type AuthNBasic struct {
  28. next http.Handler
  29. config *config.Config
  30. }
  31. // ServeHTTP calls next if the authentication token is valid,
  32. // or serves a forbidden error.
  33. func (authn *AuthNBasic) ServeHTTP(w http.ResponseWriter, r *http.Request) {
  34. porterTokenIDStr, porterToken, ok := r.BasicAuth()
  35. if ok {
  36. if porterToken == "" {
  37. authn.sendForbiddenError(fmt.Errorf("porter token does not exist"), w, r)
  38. return
  39. }
  40. porterTokenID, err := strconv.ParseUint(porterTokenIDStr, 10, 64)
  41. if err != nil {
  42. authn.sendForbiddenError(err, w, r)
  43. return
  44. }
  45. ceToken, err := ValidatePorterToken(authn.config, uint(porterTokenID), porterToken)
  46. if err != nil {
  47. authn.sendForbiddenError(err, w, r)
  48. return
  49. }
  50. // attach ce token to context
  51. ctx := r.Context()
  52. ctx = context.WithValue(ctx, "ce_token", ceToken)
  53. r = r.Clone(ctx)
  54. authn.next.ServeHTTP(w, r)
  55. return
  56. }
  57. authn.sendForbiddenError(fmt.Errorf("no basic auth credentials"), w, r)
  58. return
  59. }
  60. func (authn *AuthNBasic) sendForbiddenError(err error, w http.ResponseWriter, r *http.Request) {
  61. w.Header().Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
  62. reqErr := apierrors.NewErrForbidden(err)
  63. apierrors.HandleAPIError(authn.config.Logger, authn.config.Alerter, w, r, reqErr, true)
  64. return
  65. }