users.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  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) SSO_UserExists(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) SSO_GetUser(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. // Validate the username and password
  44. func (s *SSOHandler) ValidateUsernameAndPassword(username string, password string) bool {
  45. //Validate the username and password
  46. var userEntry UserEntry
  47. err := s.Config.Database.Read("sso_users", username, &userEntry)
  48. if err != nil {
  49. return false
  50. }
  51. //TODO: Remove after testing
  52. if (username == "test") && (password == "test") {
  53. return true
  54. }
  55. return userEntry.VerifyPassword(password)
  56. }
  57. func (s *UserEntry) VerifyPassword(password string) bool {
  58. return s.PasswordHash == auth.Hash(password)
  59. }
  60. // Write changes in the user entry back to the database
  61. func (u *UserEntry) Update() error {
  62. js, _ := json.Marshal(u)
  63. err := u.parent.Config.Database.Write("sso_users", u.UserID, string(js))
  64. if err != nil {
  65. return err
  66. }
  67. return nil
  68. }
  69. // Reset and update the TOTP code for the current user
  70. // Return the provision uri of the new TOTP code for Google Authenticator
  71. func (u *UserEntry) ResetTotp(accountName string, issuerName string) (string, error) {
  72. u.TOTPCode = gotp.RandomSecret(16)
  73. totp := gotp.NewDefaultTOTP(u.TOTPCode)
  74. err := u.Update()
  75. if err != nil {
  76. return "", err
  77. }
  78. return totp.ProvisioningUri(accountName, issuerName), nil
  79. }
  80. // Verify the TOTP code at current time
  81. func (u *UserEntry) VerifyTotp(enteredCode string) bool {
  82. totp := gotp.NewDefaultTOTP(u.TOTPCode)
  83. return totp.Verify(enteredCode, time.Now().Unix())
  84. }