auth.go 1.5 KB

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