auth.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. package fire
  2. import (
  3. "context"
  4. "net/http"
  5. "strings"
  6. firebase "firebase.google.com/go"
  7. "git.mokkon.com/sainw/server_helper/util"
  8. )
  9. // ContextKey to be used as context key type
  10. type ContextKey string
  11. // UserClaimIDContextKey context key for auth id
  12. const UserClaimIDContextKey = ContextKey("User Claim ID")
  13. // UserClaim holds user information
  14. type UserClaim struct {
  15. UserID string
  16. AuthID string
  17. PhoneNumber string
  18. Status string
  19. Privileges []string
  20. }
  21. // User holds user information
  22. type User struct {
  23. ID string `json:"id"`
  24. UserName string `json:"user_name"`
  25. PhoneNumber string `json:"phone_number"`
  26. Status string `json:"status"`
  27. SysAdmin bool `json:"sys_admin"`
  28. Privileges []string `json:"privileges"`
  29. }
  30. // GetUserClaim returns UserClaim from context
  31. func GetUserClaim(ctx context.Context) (UserClaim, bool) {
  32. userClaim, ok := ctx.Value(UserClaimIDContextKey).(UserClaim)
  33. return userClaim, ok
  34. }
  35. func (c UserClaim) HasPrivileges(ps ...string) bool {
  36. for _, p := range ps {
  37. if util.Contains(c.Privileges, p) {
  38. return true
  39. }
  40. }
  41. return false
  42. }
  43. func Auth(app *firebase.App, h http.Handler) http.Handler {
  44. fn := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
  45. // read token
  46. token := r.Header.Get("Token")
  47. ctx := r.Context()
  48. if token == "" {
  49. util.WriteResponse(w, http.StatusUnauthorized, "Error", "invalid token")
  50. return
  51. }
  52. client, err := app.Auth(ctx)
  53. if err != nil {
  54. util.WriteResponse(w, http.StatusInternalServerError, "Error", err.Error())
  55. return
  56. }
  57. authToken, err := client.VerifyIDToken(ctx, token)
  58. if err != nil {
  59. util.WriteResponse(w, http.StatusUnauthorized, "Error", "unverifiable idToken")
  60. return
  61. }
  62. var privileges []string
  63. if str, ok := authToken.Claims["pr"].(string); ok {
  64. privileges = strings.Split(str, ":")
  65. }
  66. userID := ""
  67. if str, ok := authToken.Claims["cid"].(string); ok {
  68. userID = str
  69. }
  70. phoneNumber := ""
  71. if str, ok := authToken.Claims["phone_number"].(string); ok {
  72. phoneNumber = str
  73. }
  74. status := ""
  75. if str, ok := authToken.Claims["st"].(string); ok {
  76. status = str
  77. }
  78. userClaim := UserClaim{AuthID: authToken.UID, UserID: userID,
  79. PhoneNumber: phoneNumber, Privileges: privileges, Status: status}
  80. ctx = context.WithValue(ctx, UserClaimIDContextKey, userClaim)
  81. r = r.WithContext(ctx)
  82. h.ServeHTTP(w, r)
  83. })
  84. return fn
  85. }