Browse Source

Refuse to update manually created users

binwiederhier 7 months ago
parent
commit
f3c67f1d71
5 changed files with 50 additions and 13 deletions
  1. 2 2
      cmd/serve.go
  2. 2 2
      server/config.go
  3. 2 2
      server/server.go
  4. 11 7
      user/manager.go
  5. 33 0
      user/manager_test.go

+ 2 - 2
cmd/serve.go

@@ -416,8 +416,8 @@ func execServe(c *cli.Context) error {
 	conf.AuthFile = authFile
 	conf.AuthStartupQueries = authStartupQueries
 	conf.AuthDefault = authDefault
-	conf.AuthProvisionedUsers = authProvisionUsers
-	conf.AuthProvisionedAccess = authProvisionAccess
+	conf.AuthProvisionUsers = authProvisionUsers
+	conf.AuthProvisionAccess = authProvisionAccess
 	conf.AttachmentCacheDir = attachmentCacheDir
 	conf.AttachmentTotalSizeLimit = attachmentTotalSizeLimit
 	conf.AttachmentFileSizeLimit = attachmentFileSizeLimit

+ 2 - 2
server/config.go

@@ -95,8 +95,8 @@ type Config struct {
 	AuthFile                             string
 	AuthStartupQueries                   string
 	AuthDefault                          user.Permission
-	AuthProvisionedUsers                 []*user.User
-	AuthProvisionedAccess                map[string][]*user.Grant
+	AuthProvisionUsers                   []*user.User
+	AuthProvisionAccess                  map[string][]*user.Grant
 	AuthBcryptCost                       int
 	AuthStatsQueueWriterInterval         time.Duration
 	AttachmentCacheDir                   string

+ 2 - 2
server/server.go

@@ -201,8 +201,8 @@ func New(conf *Config) (*Server, error) {
 			StartupQueries:      conf.AuthStartupQueries,
 			DefaultAccess:       conf.AuthDefault,
 			ProvisionEnabled:    true, // Enable provisioning of users and access
-			ProvisionUsers:      conf.AuthProvisionedUsers,
-			ProvisionAccess:     conf.AuthProvisionedAccess,
+			ProvisionUsers:      conf.AuthProvisionUsers,
+			ProvisionAccess:     conf.AuthProvisionAccess,
 			BcryptCost:          conf.AuthBcryptCost,
 			QueueWriterInterval: conf.AuthStatsQueueWriterInterval,
 		}

+ 11 - 7
user/manager.go

@@ -1697,13 +1697,17 @@ func (a *Manager) maybeProvisionUsersAndAccess() error {
 				if err := a.addUserTx(tx, user.Name, user.Hash, user.Role, true, true); err != nil && !errors.Is(err, ErrUserExists) {
 					return fmt.Errorf("failed to add provisioned user %s: %v", user.Name, err)
 				}
-			} else if existingUser.Provisioned && (existingUser.Hash != user.Hash || existingUser.Role != user.Role) {
-				log.Tag(tag).Info("Updating provisioned user %s", user.Name)
-				if err := a.changePasswordTx(tx, user.Name, user.Hash, true); err != nil {
-					return fmt.Errorf("failed to change password for provisioned user %s: %v", user.Name, err)
-				}
-				if err := a.changeRoleTx(tx, user.Name, user.Role); err != nil {
-					return fmt.Errorf("failed to change role for provisioned user %s: %v", user.Name, err)
+			} else {
+				if !existingUser.Provisioned {
+					log.Tag(tag).Warn("Refusing to update manually user %s", user.Name)
+				} else if existingUser.Hash != user.Hash || existingUser.Role != user.Role {
+					log.Tag(tag).Info("Updating provisioned user %s", user.Name)
+					if err := a.changePasswordTx(tx, user.Name, user.Hash, true); err != nil {
+						return fmt.Errorf("failed to change password for provisioned user %s: %v", user.Name, err)
+					}
+					if err := a.changeRoleTx(tx, user.Name, user.Role); err != nil {
+						return fmt.Errorf("failed to change role for provisioned user %s: %v", user.Name, err)
+					}
 				}
 			}
 		}

+ 33 - 0
user/manager_test.go

@@ -1193,6 +1193,39 @@ func TestManager_WithProvisionedUsers(t *testing.T) {
 	require.Equal(t, "*", users[1].Name)
 }
 
+func TestManager_DoNotUpdateNonProvisionedUsers(t *testing.T) {
+	f := filepath.Join(t.TempDir(), "user.db")
+	conf := &Config{
+		Filename:         f,
+		DefaultAccess:    PermissionReadWrite,
+		ProvisionEnabled: true,
+		ProvisionUsers:   []*User{},
+		ProvisionAccess:  map[string][]*Grant{},
+	}
+	a, err := NewManager(conf)
+	require.Nil(t, err)
+
+	// Manually add user
+	require.Nil(t, a.AddUser("philuser", "manual", RoleUser, false))
+
+	// Re-open the DB (second app start)
+	require.Nil(t, a.db.Close())
+	conf.ProvisionUsers = []*User{
+		{Name: "philuser", Hash: "$2a$10$AAAU21sX1uhZamTLJXHuxgVC0Z/GKISibrKCLohPgtG7yIxSk4C", Role: RoleAdmin},
+	}
+	conf.ProvisionAccess = map[string][]*Grant{}
+	a, err = NewManager(conf)
+	require.Nil(t, err)
+
+	// Check that the provisioned users are there
+	users, err := a.Users()
+	require.Nil(t, err)
+	require.Len(t, users, 2)
+	require.Equal(t, "philuser", users[0].Name)
+	require.Equal(t, RoleUser, users[0].Role) // Should not have been updated
+	require.NotEqual(t, "$2a$10$AAAU21sX1uhZamTLJXHuxgVC0Z/GKISibrKCLohPgtG7yIxSk4C", users[0].Hash)
+}
+
 func TestToFromSQLWildcard(t *testing.T) {
 	require.Equal(t, "up%", toSQLWildcard("up*"))
 	require.Equal(t, "up\\_%", toSQLWildcard("up_*"))