users.go 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. package sso
  2. import (
  3. "encoding/json"
  4. "time"
  5. "github.com/xlzd/gotp"
  6. "imuslab.com/zoraxy/mod/auth"
  7. )
  8. /*
  9. users.go
  10. This file contains the user structure and user management
  11. functions for the SSO module.
  12. If you are looking for handlers, please refer to handlers.go.
  13. */
  14. type SubdomainAccessRule struct {
  15. Subdomain string
  16. AllowAccess bool
  17. }
  18. type UserEntry struct {
  19. UserID string //User ID, in UUIDv4 format
  20. Username string //Username
  21. PasswordHash string //Password hash
  22. TOTPCode string //2FA TOTP code
  23. Enable2FA bool //Enable 2FA for this user
  24. Subdomains map[string]*SubdomainAccessRule //Subdomain and access rule
  25. parent *SSOHandler //Parent SSO handler
  26. }
  27. func (s *SSOHandler) SSOUserExists(userid string) bool {
  28. //Check if the user exists in the database
  29. var userEntry UserEntry
  30. err := s.Config.Database.Read("sso_users", userid, &userEntry)
  31. return err == nil
  32. }
  33. func (s *SSOHandler) GetSSOUser(userid string) (UserEntry, error) {
  34. //Load the user entry from database
  35. var userEntry UserEntry
  36. err := s.Config.Database.Read("sso_users", userid, &userEntry)
  37. if err != nil {
  38. return UserEntry{}, err
  39. }
  40. userEntry.parent = s
  41. return userEntry, nil
  42. }
  43. func (s *SSOHandler) ListSSOUsers() ([]*UserEntry, error) {
  44. entries, err := s.Config.Database.ListTable("sso_users")
  45. if err != nil {
  46. return nil, err
  47. }
  48. ssoUsers := []*UserEntry{}
  49. for _, keypairs := range entries {
  50. group := new(UserEntry)
  51. json.Unmarshal(keypairs[1], &group)
  52. group.parent = s
  53. ssoUsers = append(ssoUsers, group)
  54. }
  55. return ssoUsers, nil
  56. }
  57. // Validate the username and password
  58. func (s *SSOHandler) ValidateUsernameAndPassword(username string, password string) bool {
  59. //Validate the username and password
  60. var userEntry UserEntry
  61. err := s.Config.Database.Read("sso_users", username, &userEntry)
  62. if err != nil {
  63. return false
  64. }
  65. //TODO: Remove after testing
  66. if (username == "test") && (password == "test") {
  67. return true
  68. }
  69. return userEntry.VerifyPassword(password)
  70. }
  71. func (s *UserEntry) VerifyPassword(password string) bool {
  72. return s.PasswordHash == auth.Hash(password)
  73. }
  74. // Write changes in the user entry back to the database
  75. func (u *UserEntry) Update() error {
  76. js, _ := json.Marshal(u)
  77. err := u.parent.Config.Database.Write("sso_users", u.UserID, string(js))
  78. if err != nil {
  79. return err
  80. }
  81. return nil
  82. }
  83. // Reset and update the TOTP code for the current user
  84. // Return the provision uri of the new TOTP code for Google Authenticator
  85. func (u *UserEntry) ResetTotp(accountName string, issuerName string) (string, error) {
  86. u.TOTPCode = gotp.RandomSecret(16)
  87. totp := gotp.NewDefaultTOTP(u.TOTPCode)
  88. err := u.Update()
  89. if err != nil {
  90. return "", err
  91. }
  92. return totp.ProvisioningUri(accountName, issuerName), nil
  93. }
  94. // Verify the TOTP code at current time
  95. func (u *UserEntry) VerifyTotp(enteredCode string) bool {
  96. totp := gotp.NewDefaultTOTP(u.TOTPCode)
  97. return totp.Verify(enteredCode, time.Now().Unix())
  98. }