discord: fix admin-check for /inv

it was being checked in the EmailAddress record, only set if Jellyfin
login is disabled, or "access jfa-go" is checked for a
non-Jellyfin-admin user in Accounts. Instead, i've factored out the
actual auth code into a "canAccessAdminPage"-ish function, which is
called for this too. Should fix #378.
This commit is contained in:
Harvey Tindall
2025-05-15 17:49:06 +01:00
parent 01a75c3e23
commit 07d02f8302
3 changed files with 42 additions and 17 deletions

43
auth.go
View File

@@ -165,6 +165,31 @@ func (app *appContext) decodeValidateLoginHeader(gc *gin.Context, userpage bool)
return
}
func (app *appContext) canAccessAdminPage(user mediabrowser.User, emailStore EmailAddress) bool {
// 1. "Allow all" is enabled, so simply being a user implies access.
if app.config.Section("ui").Key("allow_all").MustBool(false) && user.ID != "" {
return true
}
// 2. You've been made an "accounts admin" from the accounts tab.
if emailStore.Admin {
return true
}
// 3. (Jellyfin) "Admins only" is enabled, and you're one.
if app.config.Section("ui").Key("admin_only").MustBool(true) && user.ID != "" && user.Policy.IsAdministrator {
return true
}
return false
}
func (app *appContext) canAccessAdminPageByID(jfID string) bool {
user, err := app.jf.UserByID(jfID, false)
if err != nil {
return false
}
emailStore, _ := app.storage.GetEmailsKey(jfID)
return app.canAccessAdminPage(user, emailStore)
}
func (app *appContext) validateJellyfinCredentials(username, password string, gc *gin.Context, userpage bool) (user mediabrowser.User, ok bool) {
ok = false
user, err := app.authJf.Authenticate(username, password)
@@ -220,18 +245,12 @@ func (app *appContext) getTokenLogin(gc *gin.Context) {
return
}
jfID = user.ID
if !app.config.Section("ui").Key("allow_all").MustBool(false) {
accountsAdmin := false
adminOnly := app.config.Section("ui").Key("admin_only").MustBool(true)
if emailStore, ok := app.storage.GetEmailsKey(jfID); ok {
accountsAdmin = emailStore.Admin
}
accountsAdmin = accountsAdmin || (adminOnly && user.Policy.IsAdministrator)
if !accountsAdmin {
app.authLog(fmt.Sprintf(lm.NonAdminUser, username))
respond(401, "Unauthorized", gc)
return
}
emailStore, _ := app.storage.GetEmailsKey(jfID)
accountsAdmin := app.canAccessAdminPage(user, emailStore)
if !accountsAdmin {
app.authLog(fmt.Sprintf(lm.NonAdminUser, username))
respond(401, "Unauthorized", gc)
return
}
// New users are only added when using jellyfinLogin.
userID = shortuuid.New()

View File

@@ -612,11 +612,16 @@ func (d *DiscordDaemon) cmdInvite(s *dg.Session, i *dg.InteractionCreate, lang s
//if mins > 0 {
// expmin = mins
//}
// Check whether requestor is linked to the admin account
requesterEmail, ok := d.app.storage.GetEmailsKey(requester.JellyfinID)
if !(ok && requesterEmail.Admin) {
// We want the same criteria for running this command as accessing the admin page (i.e. an "admin" of some sort)
if !(d.app.canAccessAdminPageByID(requester.JellyfinID)) {
d.app.err.Printf(lm.FailedGenerateInvite, fmt.Sprintf(lm.NonAdminUser, requester.JellyfinID))
// FIXME: add response message
s.InteractionRespond(i.Interaction, &dg.InteractionResponse{
Type: dg.InteractionResponseChannelMessageWithSource,
Data: &dg.InteractionResponseData{
Content: d.app.storage.lang.Telegram[lang].Strings.get("noPermission"),
Flags: 64, // Ephemeral
},
})
return
}

View File

@@ -13,6 +13,7 @@
"languageSet": "Language set to {language}.",
"discordDMs": "Please check your DMs for a response.",
"sentInvite": "Sent invite.",
"sentInviteFailure": "Failed to send invite, check logs."
"sentInviteFailure": "Failed to send invite, check logs.",
"noPermission": "You do not have permissions for this action."
}
}