Skip to content

Commit 7f0717e

Browse files
committed
Auth: Prevent login if additional accounts may not be created photoprism#4266
Signed-off-by: Michael Mayer <michael@photoprism.app>
1 parent bfc6cb2 commit 7f0717e

File tree

4 files changed

+35
-3
lines changed

4 files changed

+35
-3
lines changed

internal/api/oidc_redirect.go

+6
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,12 @@ func OIDCRedirect(router *gin.RouterGroup) {
225225
} else if err = avatar.SetUserImageURL(user, avatarUrl, entity.SrcOIDC, conf.ThumbCachePath()); err != nil {
226226
event.AuditWarn([]string{clientIp, "create session", "oidc", userName, "failed to set avatar image", err.Error()})
227227
}
228+
} else if conf.UsersQuotaExceeded() {
229+
userName = oidcUser.Username()
230+
event.AuditWarn([]string{clientIp, "create session", "oidc", "create user", userName, authn.ErrUsersQuotaExceeded.Error()})
231+
event.LoginError(clientIp, "oidc", userName, userAgent, authn.ErrUsersQuotaExceeded.Error())
232+
c.HTML(http.StatusUnauthorized, "auth.gohtml", CreateSessionError(http.StatusUnauthorized, i18n.Error(i18n.ErrQuotaExceeded)))
233+
return
228234
} else if conf.OIDCRegister() {
229235
// Create new user record.
230236
user = &oidcUser

internal/config/config_usage.go

+8-3
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func (c *Config) Usage() Usage {
9797

9898
// UsageInfo returns true if resource usage information should be displayed in the user interface.
9999
func (c *Config) UsageInfo() bool {
100-
return c.options.UsageInfo || c.options.FilesQuota > 0
100+
return c.options.UsageInfo || c.options.FilesQuota > 0 || c.options.UsersQuota > 0
101101
}
102102

103103
// FilesQuota returns the maximum aggregated size of all indexed files in gigabytes, or 0 if no limit exists.
@@ -118,16 +118,21 @@ func (c *Config) FilesQuotaBytes() uint64 {
118118
return c.options.FilesQuota * fs.GB
119119
}
120120

121-
// FilesQuotaExceeded checks if the filesystem usage has been reached or exceeded.
121+
// FilesQuotaExceeded checks whether the filesystem usage has been reached or exceeded.
122122
func (c *Config) FilesQuotaExceeded() bool {
123123
return c.Usage().FilesUsedPct >= 100
124124
}
125125

126-
// UsersQuota returns the maximum number of registered user accounts, or 0 if no quota exists.
126+
// UsersQuota returns the maximum number of user accounts without guests, or 0 if unlimited.
127127
func (c *Config) UsersQuota() int {
128128
if c.options.UsersQuota <= 0 {
129129
return 0
130130
}
131131

132132
return c.options.UsersQuota
133133
}
134+
135+
// UsersQuotaExceeded checks whether the maximum number of user accounts has been reached or exceeded.
136+
func (c *Config) UsersQuotaExceeded() bool {
137+
return c.Usage().UsersUsedPct >= 100
138+
}

internal/config/config_usage_test.go

+20
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55

66
"github.com/stretchr/testify/assert"
77

8+
"github.com/photoprism/photoprism/pkg/fs"
89
"github.com/photoprism/photoprism/pkg/fs/duf"
910
)
1011

@@ -49,7 +50,9 @@ func TestConfig_Quota(t *testing.T) {
4950

5051
c.options.FilesQuota = uint64(1)
5152
c.options.UsersQuota = 10
53+
5254
assert.Equal(t, uint64(1), c.FilesQuota())
55+
assert.Equal(t, uint64(fs.GB), c.FilesQuotaBytes())
5356
assert.Equal(t, 10, c.UsersQuota())
5457

5558
c.options.FilesQuota = uint64(0)
@@ -72,3 +75,20 @@ func TestConfig_FilesQuotaExceeded(t *testing.T) {
7275

7376
c.options.FilesQuota = uint64(0)
7477
}
78+
79+
func TestConfig_UsersQuotaExceeded(t *testing.T) {
80+
c := TestConfig()
81+
82+
FlushUsageCache()
83+
assert.False(t, c.UsersQuotaExceeded())
84+
85+
c.options.UsersQuota = 1
86+
FlushUsageCache()
87+
assert.True(t, c.UsersQuotaExceeded())
88+
89+
c.options.UsersQuota = 100000
90+
FlushUsageCache()
91+
assert.False(t, c.UsersQuotaExceeded())
92+
93+
c.options.UsersQuota = 0
94+
}

pkg/authn/errors.go

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ var (
2828
ErrDisabledInPublicMode = errors.New("disabled in public mode")
2929
ErrAuthenticationDisabled = errors.New("authentication disabled")
3030
ErrRateLimitExceeded = errors.New("rate limit exceeded")
31+
ErrUsersQuotaExceeded = errors.New("users quota exceeded")
3132
)
3233

3334
// OIDC and OAuth2-related error messages:

0 commit comments

Comments
 (0)