auth.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package api
  2. import (
  3. "fmt"
  4. "strings"
  5. "github.com/Sirupsen/logrus"
  6. "github.com/cad/ovpm"
  7. "github.com/cad/ovpm/permset"
  8. gcontext "golang.org/x/net/context"
  9. "google.golang.org/grpc"
  10. "google.golang.org/grpc/codes"
  11. "google.golang.org/grpc/metadata"
  12. )
  13. func authRequired(ctx gcontext.Context, req interface{}, handler grpc.UnaryHandler) (resp interface{}, err error) {
  14. logrus.Debugln("rpc: auth applied")
  15. token, err := authzTokenFromContext(ctx)
  16. if err != nil {
  17. logrus.Debugln("rpc: auth denied because token can not be gathered from header contest")
  18. return nil, grpc.Errorf(codes.Unauthenticated, err.Error())
  19. }
  20. user, err := ovpm.GetUserByToken(token)
  21. if err != nil {
  22. logrus.Debugln("rpc: auth denied because user with this token can not be found")
  23. return nil, grpc.Errorf(codes.Unauthenticated, "access denied")
  24. }
  25. // Set user's permissions according to it's criterias.
  26. var permissions permset.Permset
  27. if user.IsAdmin() {
  28. permissions = permset.New(ovpm.AdminPerms()...)
  29. } else {
  30. permissions = permset.New(ovpm.UserPerms()...)
  31. }
  32. newCtx := NewUsernameContext(ctx, user.GetUsername())
  33. newCtx = permset.NewContext(newCtx, permissions)
  34. return handler(newCtx, req)
  35. }
  36. func authzTokenFromContext(ctx gcontext.Context) (string, error) {
  37. // retrieve metadata from context
  38. md, ok := metadata.FromIncomingContext(ctx)
  39. if !ok {
  40. return "", fmt.Errorf("authentication required")
  41. }
  42. if len(md["authorization"]) != 1 {
  43. return "", fmt.Errorf("authentication required (length)")
  44. }
  45. authHeader := md["authorization"][0]
  46. // split authorization header into two
  47. splitToken := strings.Split(authHeader, "Bearer")
  48. if len(splitToken) != 2 {
  49. return "", fmt.Errorf("invalid Authorization header. it should be in the form of 'Bearer <token>': %s", authHeader)
  50. }
  51. // get token
  52. token := splitToken[1]
  53. token = strings.TrimSpace(token)
  54. return token, nil
  55. }