Disable account page in public mode

Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
Michael Mayer 2020-06-30 08:50:44 +02:00
parent 56cf8e95e0
commit 0e426a547b
9 changed files with 42 additions and 16 deletions

View file

@ -17,7 +17,7 @@
<translate key="Sync">Sync</translate>
</v-tab>
<v-tab id="tab-settings-account" ripple @click="changePath('/settings/account')">
<v-tab id="tab-settings-account" ripple @click="changePath('/settings/account')" v-if="!public">
<translate key="Account">Account</translate>
</v-tab>
@ -28,7 +28,7 @@
<v-tab-item lazy>
<p-settings-sync></p-settings-sync>
</v-tab-item>
<v-tab-item lazy>
<v-tab-item lazy v-if="!public">
<p-settings-account></p-settings-account>
</v-tab-item>
</v-tabs-items>
@ -53,6 +53,7 @@
},
data() {
return {
public: this.$config.get("public"),
readonly: this.$config.get("readonly"),
active: this.tab,
}

View file

@ -7,7 +7,7 @@
<v-layout wrap align-top>
<v-flex xs12 class="px-2 pt-2 pb-4">
<v-text-field
hide-details
hide-details required
:disabled="busy"
browser-autocomplete="off"
label="Current Password"
@ -20,7 +20,7 @@
<v-flex xs12 class="pa-2">
<v-text-field
hide-details
hide-details required
:disabled="busy"
browser-autocomplete="off"
label="New Password"
@ -33,7 +33,7 @@
<v-flex xs12 class="pa-2">
<v-text-field
hide-details
hide-details required
:disabled="busy"
browser-autocomplete="off"
label="Confirm Password"
@ -45,7 +45,7 @@
</v-flex>
<v-flex xs12 text-xs-left class="px-2 pt-4 pb-2">
<v-btn depressed dark color="secondary-dark" @click.stop="confirm"
class="action-confirm ma-0">
class="action-confirm ma-0" :disabled="busy">
<translate>Change Password</translate>
<v-icon right dark>vpn_key</v-icon>
</v-btn>
@ -70,6 +70,9 @@
};
},
methods: {
disabled() {
return (this.oldPassword === "" || this.newPassword === "" || (this.newPassword !== this.confirmPassword));
},
confirm() {
this.busy = true;
this.$session.getUser().changePassword(this.oldPassword, this.newPassword).then(() => {

View file

@ -12,6 +12,7 @@ var (
ErrUnauthorized = gin.H{"code": http.StatusUnauthorized, "error": txt.UcFirst(config.ErrUnauthorized.Error())}
ErrReadOnly = gin.H{"code": http.StatusForbidden, "error": txt.UcFirst(config.ErrReadOnly.Error())}
ErrUploadNSFW = gin.H{"code": http.StatusForbidden, "error": txt.UcFirst(config.ErrUploadNSFW.Error())}
ErrPublic = gin.H{"code": http.StatusForbidden, "error": "Not available in public mode"}
ErrAccountNotFound = gin.H{"code": http.StatusNotFound, "error": "Account not found"}
ErrConnectionFailed = gin.H{"code": http.StatusConflict, "error": "Failed to connect"}
ErrAlbumNotFound = gin.H{"code": http.StatusNotFound, "error": "Album not found"}
@ -25,4 +26,5 @@ var (
ErrFormInvalid = gin.H{"code": http.StatusBadRequest, "error": "Changes could not be saved"}
ErrFeatureDisabled = gin.H{"code": http.StatusForbidden, "error": "Feature disabled"}
ErrNotFound = gin.H{"code": http.StatusNotFound, "error": "Not found"}
ErrInvalidPassword = gin.H{"code": http.StatusBadRequest, "error": "Invalid password"}
)

View file

@ -7,11 +7,19 @@ import (
"github.com/photoprism/photoprism/internal/acl"
"github.com/photoprism/photoprism/internal/entity"
"github.com/photoprism/photoprism/internal/form"
"github.com/photoprism/photoprism/internal/service"
)
// PUT /api/v1/users/:uid/password
func ChangePassword(router *gin.RouterGroup) {
router.PUT("/users/:uid/password", func(c *gin.Context) {
conf := service.Config()
if conf.Public() {
c.AbortWithStatusJSON(http.StatusForbidden, ErrPublic)
return
}
s := Auth(SessionID(c), acl.ResourcePeople, acl.ActionUpdateSelf)
if s.Invalid() {
@ -23,24 +31,27 @@ func ChangePassword(router *gin.RouterGroup) {
m := entity.FindPersonByUID(uid)
if m == nil {
c.AbortWithStatusJSON(http.StatusNotFound, ErrPhotoNotFound)
log.Errorf("change password: user not found")
c.AbortWithStatusJSON(http.StatusNotFound, ErrInvalidPassword)
return
}
f := form.ChangePassword{}
if err := c.BindJSON(&f); err != nil {
log.Errorf("user: %s", err.Error())
c.AbortWithStatusJSON(http.StatusBadRequest, ErrFormInvalid)
log.Errorf("change password: %s", err)
c.AbortWithStatusJSON(http.StatusBadRequest, ErrInvalidPassword)
return
}
if m.InvalidPassword(f.OldPassword) {
c.AbortWithStatusJSON(http.StatusBadRequest, ErrFormInvalid)
log.Errorf("change password: invalid password")
c.AbortWithStatusJSON(http.StatusBadRequest, ErrInvalidPassword)
return
}
if err := m.SetPassword(f.NewPassword); err != nil {
log.Errorf("change password: %s", err)
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"code": http.StatusBadRequest, "error": err.Error()})
return
}

View file

@ -180,10 +180,6 @@ func (c *Config) UploadNSFW() bool {
// AdminPassword returns the initial admin password.
func (c *Config) AdminPassword() string {
if c.params.AdminPassword == "" {
return "photoprism"
}
return c.params.AdminPassword
}

View file

@ -34,7 +34,6 @@ var GlobalFlags = []cli.Flag{
cli.StringFlag{
Name: "admin-password",
Usage: "initial admin password (can be changed in settings)",
Value: "photoprism",
EnvVar: "PHOTOPRISM_ADMIN_PASSWORD",
},
cli.IntFlag{

View file

@ -72,6 +72,7 @@ func NewTestParams() *Params {
SettingsPath: testDataPath + "/settings",
DatabaseDriver: dbDriver,
DatabaseDsn: dbDsn,
AdminPassword: "photoprism",
}
return c
@ -172,6 +173,7 @@ func CliTestContext() *cli.Context {
globalSet.String("temp-path", config.OriginalsPath, "doc")
globalSet.String("cache-path", config.OriginalsPath, "doc")
globalSet.String("darktable-cli", config.DarktableBin, "doc")
globalSet.String("admin-password", config.DarktableBin, "doc")
globalSet.Bool("detect-nsfw", config.DetectNSFW, "doc")
app := cli.NewApp()
@ -187,6 +189,7 @@ func CliTestContext() *cli.Context {
LogError(c.Set("temp-path", config.TempPath))
LogError(c.Set("cache-path", config.CachePath))
LogError(c.Set("darktable-cli", config.DarktableBin))
LogError(c.Set("admin-password", config.AdminPassword))
LogError(c.Set("detect-nsfw", "true"))
return c

View file

@ -2,6 +2,10 @@ package entity
// CreateTestFixtures inserts all known entities into the database for testing.
func CreateTestFixtures() {
if err := Admin.SetPassword("photoprism"); err != nil {
log.Error(err)
}
CreateLabelFixtures()
CreateCameraFixtures()
CreateCountryFixtures()

View file

@ -83,7 +83,6 @@ var Guest = Person{
func CreateDefaultUsers() {
if user := FirstOrCreatePerson(&Admin); user != nil {
Admin = *user
Admin.InitPassword("photoprism")
}
if user := FirstOrCreatePerson(&UnknownPerson); user != nil {
@ -211,6 +210,10 @@ func (m *Person) InitPassword(password string) {
return
}
if password == "" {
return
}
existing := FindPassword(m.PersonUID)
if existing != nil {
@ -231,6 +234,10 @@ func (m *Person) InvalidPassword(password string) bool {
return true
}
if password == "" {
return true
}
pw := FindPassword(m.PersonUID)
if pw == nil {