mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-11-09 20:00:12 +00:00
api clients: return data, error, no status
jellyseerr already did this, but it's been standardised a little more. Mediabrowser uses it's own genericErr function and error types due to being a separate package, while jellyseerr and ombi now share errors defined in common/.
This commit is contained in:
parent
284312713c
commit
2310130e6b
2
Makefile
2
Makefile
@ -211,7 +211,7 @@ $(COPY_TARGET): $(INLINE_TARGET) $(STATIC_SRC)
|
|||||||
|
|
||||||
GO_SRC = $(shell find ./ -name "*.go")
|
GO_SRC = $(shell find ./ -name "*.go")
|
||||||
GO_TARGET = build/jfa-go
|
GO_TARGET = build/jfa-go
|
||||||
$(GO_TARGET): $(CONFIG_DESCRIPTION) $(CONFIG_DEFAULT) $(EMAIL_TARGET) $(COPY_TARGET) $(SWAGGER_TARGET) $(GO_SRC)
|
$(GO_TARGET): $(CONFIG_DESCRIPTION) $(CONFIG_DEFAULT) $(EMAIL_TARGET) $(COPY_TARGET) $(SWAGGER_TARGET) $(GO_SRC) go.mod go.sum
|
||||||
$(info Downloading deps)
|
$(info Downloading deps)
|
||||||
$(GOBINARY) mod download
|
$(GOBINARY) mod download
|
||||||
$(info Building)
|
$(info Building)
|
||||||
|
@ -144,13 +144,13 @@ func (app *appContext) GetActivities(gc *gin.Context) {
|
|||||||
if act.Type == ActivityDeletion || act.Type == ActivityCreation {
|
if act.Type == ActivityDeletion || act.Type == ActivityCreation {
|
||||||
resp.Activities[i].Username = act.Value
|
resp.Activities[i].Username = act.Value
|
||||||
resp.Activities[i].Value = ""
|
resp.Activities[i].Value = ""
|
||||||
} else if user, status, err := app.jf.UserByID(act.UserID, false); status == 200 && err == nil {
|
} else if user, err := app.jf.UserByID(act.UserID, false); err == nil {
|
||||||
resp.Activities[i].Username = user.Name
|
resp.Activities[i].Username = user.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
if (act.SourceType == ActivityUser || act.SourceType == ActivityAdmin) && act.Source != "" {
|
if (act.SourceType == ActivityUser || act.SourceType == ActivityAdmin) && act.Source != "" {
|
||||||
user, status, err := app.jf.UserByID(act.Source, false)
|
user, err := app.jf.UserByID(act.Source, false)
|
||||||
if status == 200 && err == nil {
|
if err == nil {
|
||||||
resp.Activities[i].SourceUsername = user.Name
|
resp.Activities[i].SourceUsername = user.Name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
74
api-ombi.go
74
api-ombi.go
@ -1,34 +1,35 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"github.com/hrfee/jfa-go/common"
|
||||||
lm "github.com/hrfee/jfa-go/logmessages"
|
lm "github.com/hrfee/jfa-go/logmessages"
|
||||||
"github.com/hrfee/jfa-go/ombi"
|
"github.com/hrfee/jfa-go/ombi"
|
||||||
"github.com/hrfee/mediabrowser"
|
"github.com/hrfee/mediabrowser"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (app *appContext) getOmbiUser(jfID string) (map[string]interface{}, int, error) {
|
func (app *appContext) getOmbiUser(jfID string) (map[string]interface{}, error) {
|
||||||
jfUser, code, err := app.jf.UserByID(jfID, false)
|
jfUser, err := app.jf.UserByID(jfID, false)
|
||||||
if err != nil || code != 200 {
|
if err != nil {
|
||||||
return nil, code, err
|
return nil, err
|
||||||
}
|
}
|
||||||
username := jfUser.Name
|
username := jfUser.Name
|
||||||
email := ""
|
email := ""
|
||||||
if e, ok := app.storage.GetEmailsKey(jfID); ok {
|
if e, ok := app.storage.GetEmailsKey(jfID); ok {
|
||||||
email = e.Addr
|
email = e.Addr
|
||||||
}
|
}
|
||||||
return app.ombi.getUser(username, email)
|
user, err := app.ombi.getUser(username, email)
|
||||||
|
return user, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ombi *OmbiWrapper) getUser(username string, email string) (map[string]interface{}, int, error) {
|
func (ombi *OmbiWrapper) getUser(username string, email string) (map[string]interface{}, error) {
|
||||||
ombiUsers, code, err := ombi.GetUsers()
|
ombiUsers, err := ombi.GetUsers()
|
||||||
if err != nil || code != 200 {
|
if err != nil {
|
||||||
return nil, code, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, ombiUser := range ombiUsers {
|
for _, ombiUser := range ombiUsers {
|
||||||
ombiAddr := ""
|
ombiAddr := ""
|
||||||
@ -36,18 +37,19 @@ func (ombi *OmbiWrapper) getUser(username string, email string) (map[string]inte
|
|||||||
ombiAddr = a.(string)
|
ombiAddr = a.(string)
|
||||||
}
|
}
|
||||||
if ombiUser["userName"].(string) == username || (ombiAddr == email && email != "") {
|
if ombiUser["userName"].(string) == username || (ombiAddr == email && email != "") {
|
||||||
return ombiUser, code, err
|
return ombiUser, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, 400, errors.New(lm.NotFound)
|
// Gets a generic "not found" type error
|
||||||
|
return nil, common.GenericErr(404, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a user with the given name who has been imported from Jellyfin/Emby by Ombi
|
// Returns a user with the given name who has been imported from Jellyfin/Emby by Ombi
|
||||||
func (ombi *OmbiWrapper) getImportedUser(name string) (map[string]interface{}, int, error) {
|
func (ombi *OmbiWrapper) getImportedUser(name string) (map[string]interface{}, error) {
|
||||||
// Ombi User Types: 3/4 = Emby, 5 = Jellyfin
|
// Ombi User Types: 3/4 = Emby, 5 = Jellyfin
|
||||||
ombiUsers, code, err := ombi.GetUsers()
|
ombiUsers, err := ombi.GetUsers()
|
||||||
if err != nil || code != 200 {
|
if err != nil {
|
||||||
return nil, code, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for _, ombiUser := range ombiUsers {
|
for _, ombiUser := range ombiUsers {
|
||||||
if ombiUser["userName"].(string) == name {
|
if ombiUser["userName"].(string) == name {
|
||||||
@ -60,10 +62,11 @@ func (ombi *OmbiWrapper) getImportedUser(name string) (map[string]interface{}, i
|
|||||||
} else if uType != 3 && uType != 4 { // Emby
|
} else if uType != 3 && uType != 4 { // Emby
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
return ombiUser, code, err
|
return ombiUser, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil, 400, fmt.Errorf("couldn't find user")
|
// Gets a generic "not found" type error
|
||||||
|
return nil, common.GenericErr(404, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Summary Get a list of Ombi users.
|
// @Summary Get a list of Ombi users.
|
||||||
@ -74,8 +77,8 @@ func (ombi *OmbiWrapper) getImportedUser(name string) (map[string]interface{}, i
|
|||||||
// @Security Bearer
|
// @Security Bearer
|
||||||
// @tags Ombi
|
// @tags Ombi
|
||||||
func (app *appContext) OmbiUsers(gc *gin.Context) {
|
func (app *appContext) OmbiUsers(gc *gin.Context) {
|
||||||
users, status, err := app.ombi.GetUsers()
|
users, err := app.ombi.GetUsers()
|
||||||
if err != nil || status != 200 {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetUsers, lm.Ombi, err)
|
app.err.Printf(lm.FailedGetUsers, lm.Ombi, err)
|
||||||
respond(500, "Couldn't get users", gc)
|
respond(500, "Couldn't get users", gc)
|
||||||
return
|
return
|
||||||
@ -110,8 +113,8 @@ func (app *appContext) SetOmbiProfile(gc *gin.Context) {
|
|||||||
respondBool(400, false, gc)
|
respondBool(400, false, gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
template, code, err := app.ombi.TemplateByID(req.ID)
|
template, err := app.ombi.TemplateByID(req.ID)
|
||||||
if err != nil || code != 200 || len(template) == 0 {
|
if err != nil || len(template) == 0 {
|
||||||
app.err.Printf(lm.FailedGetUsers, lm.Ombi, err)
|
app.err.Printf(lm.FailedGetUsers, lm.Ombi, err)
|
||||||
respond(500, "Couldn't get user", gc)
|
respond(500, "Couldn't get user", gc)
|
||||||
return
|
return
|
||||||
@ -147,7 +150,7 @@ type OmbiWrapper struct {
|
|||||||
*ombi.Ombi
|
*ombi.Ombi
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ombi *OmbiWrapper) applyProfile(user map[string]interface{}, profile map[string]interface{}) (status int, err error) {
|
func (ombi *OmbiWrapper) applyProfile(user map[string]interface{}, profile map[string]interface{}) (err error) {
|
||||||
for k, v := range profile {
|
for k, v := range profile {
|
||||||
switch v.(type) {
|
switch v.(type) {
|
||||||
case map[string]interface{}, []interface{}:
|
case map[string]interface{}, []interface{}:
|
||||||
@ -158,22 +161,21 @@ func (ombi *OmbiWrapper) applyProfile(user map[string]interface{}, profile map[s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
status, err = ombi.ModifyUser(user)
|
err = ombi.ModifyUser(user)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ombi *OmbiWrapper) ImportUser(jellyfinID string, req newUserDTO, profile Profile) (err error, ok bool) {
|
func (ombi *OmbiWrapper) ImportUser(jellyfinID string, req newUserDTO, profile Profile) (err error, ok bool) {
|
||||||
errors, code, err := ombi.NewUser(req.Username, req.Password, req.Email, profile.Ombi)
|
errors, err := ombi.NewUser(req.Username, req.Password, req.Email, profile.Ombi)
|
||||||
var ombiUser map[string]interface{}
|
var ombiUser map[string]interface{}
|
||||||
var status int
|
if err != nil {
|
||||||
if err != nil || code != 200 {
|
|
||||||
// Check if on the off chance, Ombi's user importer has already added the account.
|
// Check if on the off chance, Ombi's user importer has already added the account.
|
||||||
ombiUser, status, err = ombi.getImportedUser(req.Username)
|
ombiUser, err = ombi.getImportedUser(req.Username)
|
||||||
if status == 200 && err == nil {
|
if err == nil {
|
||||||
// app.info.Println(lm.Ombi + " " + lm.UserExists)
|
// app.info.Println(lm.Ombi + " " + lm.UserExists)
|
||||||
profile.Ombi["password"] = req.Password
|
profile.Ombi["password"] = req.Password
|
||||||
status, err = ombi.applyProfile(ombiUser, profile.Ombi)
|
err = ombi.applyProfile(ombiUser, profile.Ombi)
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
err = fmt.Errorf(lm.FailedApplyProfile, lm.Ombi, req.Username, err)
|
err = fmt.Errorf(lm.FailedApplyProfile, lm.Ombi, req.Username, err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -189,9 +191,8 @@ func (ombi *OmbiWrapper) ImportUser(jellyfinID string, req newUserDTO, profile P
|
|||||||
|
|
||||||
func (ombi *OmbiWrapper) AddContactMethods(jellyfinID string, req newUserDTO, discord *DiscordUser, telegram *TelegramUser) (err error) {
|
func (ombi *OmbiWrapper) AddContactMethods(jellyfinID string, req newUserDTO, discord *DiscordUser, telegram *TelegramUser) (err error) {
|
||||||
var ombiUser map[string]interface{}
|
var ombiUser map[string]interface{}
|
||||||
var status int
|
ombiUser, err = ombi.getUser(req.Username, req.Email)
|
||||||
ombiUser, status, err = ombi.getUser(req.Username, req.Email)
|
if err != nil {
|
||||||
if status != 200 || err != nil {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if discordEnabled || telegramEnabled {
|
if discordEnabled || telegramEnabled {
|
||||||
@ -204,9 +205,8 @@ func (ombi *OmbiWrapper) AddContactMethods(jellyfinID string, req newUserDTO, di
|
|||||||
tUser = telegram.Username
|
tUser = telegram.Username
|
||||||
}
|
}
|
||||||
var resp string
|
var resp string
|
||||||
var status int
|
resp, err = ombi.SetNotificationPrefs(ombiUser, dID, tUser)
|
||||||
resp, status, err = ombi.SetNotificationPrefs(ombiUser, dID, tUser)
|
if err != nil {
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
|
||||||
if resp != "" {
|
if resp != "" {
|
||||||
err = fmt.Errorf("%v, %s", err, resp)
|
err = fmt.Errorf("%v, %s", err, resp)
|
||||||
}
|
}
|
||||||
|
@ -84,8 +84,8 @@ func (app *appContext) CreateProfile(gc *gin.Context) {
|
|||||||
var req newProfileDTO
|
var req newProfileDTO
|
||||||
gc.BindJSON(&req)
|
gc.BindJSON(&req)
|
||||||
app.jf.CacheExpiry = time.Now()
|
app.jf.CacheExpiry = time.Now()
|
||||||
user, status, err := app.jf.UserByID(req.ID, false)
|
user, err := app.jf.UserByID(req.ID, false)
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetUsers, lm.Jellyfin, err)
|
app.err.Printf(lm.FailedGetUsers, lm.Jellyfin, err)
|
||||||
respond(500, "Couldn't get user", gc)
|
respond(500, "Couldn't get user", gc)
|
||||||
return
|
return
|
||||||
@ -98,8 +98,8 @@ func (app *appContext) CreateProfile(gc *gin.Context) {
|
|||||||
app.debug.Printf(lm.CreateProfileFromUser, user.Name)
|
app.debug.Printf(lm.CreateProfileFromUser, user.Name)
|
||||||
if req.Homescreen {
|
if req.Homescreen {
|
||||||
profile.Configuration = user.Configuration
|
profile.Configuration = user.Configuration
|
||||||
profile.Displayprefs, status, err = app.jf.GetDisplayPreferences(req.ID)
|
profile.Displayprefs, err = app.jf.GetDisplayPreferences(req.ID)
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetJellyfinDisplayPrefs, req.ID, err)
|
app.err.Printf(lm.FailedGetJellyfinDisplayPrefs, req.ID, err)
|
||||||
respond(500, "Couldn't get displayprefs", gc)
|
respond(500, "Couldn't get displayprefs", gc)
|
||||||
return
|
return
|
||||||
|
@ -29,8 +29,8 @@ func (app *appContext) MyDetails(gc *gin.Context) {
|
|||||||
Id: gc.GetString("jfId"),
|
Id: gc.GetString("jfId"),
|
||||||
}
|
}
|
||||||
|
|
||||||
user, status, err := app.jf.UserByID(resp.Id, false)
|
user, err := app.jf.UserByID(resp.Id, false)
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetUsers, lm.Jellyfin, err)
|
app.err.Printf(lm.FailedGetUsers, lm.Jellyfin, err)
|
||||||
respond(500, "Failed to get user", gc)
|
respond(500, "Failed to get user", gc)
|
||||||
return
|
return
|
||||||
@ -259,9 +259,9 @@ func (app *appContext) ModifyMyEmail(gc *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if emailEnabled && app.config.Section("email_confirmation").Key("enabled").MustBool(false) {
|
if emailEnabled && app.config.Section("email_confirmation").Key("enabled").MustBool(false) {
|
||||||
user, status, err := app.jf.UserByID(id, false)
|
user, err := app.jf.UserByID(id, false)
|
||||||
name := ""
|
name := ""
|
||||||
if status == 200 && err == nil {
|
if err == nil {
|
||||||
name = user.Name
|
name = user.Name
|
||||||
}
|
}
|
||||||
app.debug.Printf(lm.EmailConfirmationRequired, id)
|
app.debug.Printf(lm.EmailConfirmationRequired, id)
|
||||||
@ -688,20 +688,20 @@ func (app *appContext) ChangeMyPassword(gc *gin.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
user, status, err := app.jf.UserByID(gc.GetString("jfId"), false)
|
user, err := app.jf.UserByID(gc.GetString("jfId"), false)
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetUser, gc.GetString("jfId"), lm.Jellyfin, err)
|
app.err.Printf(lm.FailedGetUser, gc.GetString("jfId"), lm.Jellyfin, err)
|
||||||
respondBool(500, false, gc)
|
respondBool(500, false, gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
// Authenticate as user to confirm old password.
|
// Authenticate as user to confirm old password.
|
||||||
user, status, err = app.authJf.Authenticate(user.Name, req.Old)
|
user, err = app.authJf.Authenticate(user.Name, req.Old)
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
respondBool(401, false, gc)
|
respondBool(401, false, gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
status, err = app.jf.SetPassword(gc.GetString("jfId"), req.Old, req.New)
|
err = app.jf.SetPassword(gc.GetString("jfId"), req.Old, req.New)
|
||||||
if (status != 200 && status != 204) || err != nil {
|
if err != nil {
|
||||||
respondBool(500, false, gc)
|
respondBool(500, false, gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -716,14 +716,14 @@ func (app *appContext) ChangeMyPassword(gc *gin.Context) {
|
|||||||
|
|
||||||
if app.config.Section("ombi").Key("enabled").MustBool(false) {
|
if app.config.Section("ombi").Key("enabled").MustBool(false) {
|
||||||
func() {
|
func() {
|
||||||
ombiUser, status, err := app.getOmbiUser(gc.GetString("jfId"))
|
ombiUser, err := app.getOmbiUser(gc.GetString("jfId"))
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetUser, user.Name, lm.Ombi, err)
|
app.err.Printf(lm.FailedGetUser, user.Name, lm.Ombi, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ombiUser["password"] = req.New
|
ombiUser["password"] = req.New
|
||||||
status, err = app.ombi.ModifyUser(ombiUser)
|
err = app.ombi.ModifyUser(ombiUser)
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedChangePassword, lm.Ombi, ombiUser["userName"], err)
|
app.err.Printf(lm.FailedChangePassword, lm.Ombi, ombiUser["userName"], err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
82
api-users.go
82
api-users.go
@ -379,9 +379,9 @@ func (app *appContext) EnableDisableUsers(gc *gin.Context) {
|
|||||||
activityType = ActivityEnabled
|
activityType = ActivityEnabled
|
||||||
}
|
}
|
||||||
for _, userID := range req.Users {
|
for _, userID := range req.Users {
|
||||||
user, status, err := app.jf.UserByID(userID, false)
|
user, err := app.jf.UserByID(userID, false)
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
errors["GetUser"][user.ID] = fmt.Sprintf("%d %v", status, err)
|
errors["GetUser"][user.ID] = err.Error()
|
||||||
app.err.Printf(lm.FailedGetUser, user.ID, lm.Jellyfin, err)
|
app.err.Printf(lm.FailedGetUser, user.ID, lm.Jellyfin, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -440,10 +440,7 @@ func (app *appContext) DeleteUsers(gc *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, userID := range req.Users {
|
for _, userID := range req.Users {
|
||||||
user, status, err := app.jf.UserByID(userID, false)
|
user, err := app.jf.UserByID(userID, false)
|
||||||
if status != 200 && err == nil {
|
|
||||||
err = fmt.Errorf("failed (code %d)", status)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetUser, user.ID, lm.Jellyfin, err)
|
app.err.Printf(lm.FailedGetUser, user.ID, lm.Jellyfin, err)
|
||||||
errors[userID] = err.Error()
|
errors[userID] = err.Error()
|
||||||
@ -522,8 +519,8 @@ func (app *appContext) ExtendExpiry(gc *gin.Context) {
|
|||||||
app.storage.SetUserExpiryKey(id, expiry)
|
app.storage.SetUserExpiryKey(id, expiry)
|
||||||
if messagesEnabled && req.Notify {
|
if messagesEnabled && req.Notify {
|
||||||
go func(uid string, exp time.Time) {
|
go func(uid string, exp time.Time) {
|
||||||
user, status, err := app.jf.UserByID(uid, false)
|
user, err := app.jf.UserByID(uid, false)
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
msg, err := app.email.constructExpiryAdjusted(user.Name, exp, req.Reason, app, false)
|
msg, err := app.email.constructExpiryAdjusted(user.Name, exp, req.Reason, app, false)
|
||||||
@ -655,8 +652,8 @@ func (app *appContext) Announce(gc *gin.Context) {
|
|||||||
unique := strings.Contains(req.Message, "{username}")
|
unique := strings.Contains(req.Message, "{username}")
|
||||||
if unique {
|
if unique {
|
||||||
for _, userID := range req.Users {
|
for _, userID := range req.Users {
|
||||||
user, status, err := app.jf.UserByID(userID, false)
|
user, err := app.jf.UserByID(userID, false)
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetUser, userID, lm.Jellyfin, err)
|
app.err.Printf(lm.FailedGetUser, userID, lm.Jellyfin, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -835,9 +832,9 @@ func (app *appContext) AdminPasswordReset(gc *gin.Context) {
|
|||||||
// @tags Users
|
// @tags Users
|
||||||
func (app *appContext) GetUsers(gc *gin.Context) {
|
func (app *appContext) GetUsers(gc *gin.Context) {
|
||||||
var resp getUsersDTO
|
var resp getUsersDTO
|
||||||
users, status, err := app.jf.GetUsers(false)
|
users, err := app.jf.GetUsers(false)
|
||||||
resp.UserList = make([]respUser, len(users))
|
resp.UserList = make([]respUser, len(users))
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetUsers, lm.Jellyfin, err)
|
app.err.Printf(lm.FailedGetUsers, lm.Jellyfin, err)
|
||||||
respond(500, "Couldn't get users", gc)
|
respond(500, "Couldn't get users", gc)
|
||||||
return
|
return
|
||||||
@ -910,8 +907,8 @@ func (app *appContext) GetUsers(gc *gin.Context) {
|
|||||||
func (app *appContext) SetAccountsAdmin(gc *gin.Context) {
|
func (app *appContext) SetAccountsAdmin(gc *gin.Context) {
|
||||||
var req setAccountsAdminDTO
|
var req setAccountsAdminDTO
|
||||||
gc.BindJSON(&req)
|
gc.BindJSON(&req)
|
||||||
users, status, err := app.jf.GetUsers(false)
|
users, err := app.jf.GetUsers(false)
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetUsers, lm.Jellyfin, err)
|
app.err.Printf(lm.FailedGetUsers, lm.Jellyfin, err)
|
||||||
respond(500, "Couldn't get users", gc)
|
respond(500, "Couldn't get users", gc)
|
||||||
return
|
return
|
||||||
@ -942,8 +939,8 @@ func (app *appContext) SetAccountsAdmin(gc *gin.Context) {
|
|||||||
func (app *appContext) ModifyLabels(gc *gin.Context) {
|
func (app *appContext) ModifyLabels(gc *gin.Context) {
|
||||||
var req modifyEmailsDTO
|
var req modifyEmailsDTO
|
||||||
gc.BindJSON(&req)
|
gc.BindJSON(&req)
|
||||||
users, status, err := app.jf.GetUsers(false)
|
users, err := app.jf.GetUsers(false)
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetUsers, lm.Jellyfin, err)
|
app.err.Printf(lm.FailedGetUsers, lm.Jellyfin, err)
|
||||||
respond(500, "Couldn't get users", gc)
|
respond(500, "Couldn't get users", gc)
|
||||||
return
|
return
|
||||||
@ -976,11 +973,11 @@ func (app *appContext) modifyEmail(jfID string, addr string) {
|
|||||||
emailStore.Addr = addr
|
emailStore.Addr = addr
|
||||||
app.storage.SetEmailsKey(jfID, emailStore)
|
app.storage.SetEmailsKey(jfID, emailStore)
|
||||||
if app.config.Section("ombi").Key("enabled").MustBool(false) {
|
if app.config.Section("ombi").Key("enabled").MustBool(false) {
|
||||||
ombiUser, code, err := app.getOmbiUser(jfID)
|
ombiUser, err := app.getOmbiUser(jfID)
|
||||||
if code == 200 && err == nil {
|
if err == nil {
|
||||||
ombiUser["emailAddress"] = addr
|
ombiUser["emailAddress"] = addr
|
||||||
code, err = app.ombi.ModifyUser(ombiUser)
|
err = app.ombi.ModifyUser(ombiUser)
|
||||||
if code != 200 || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedSetEmailAddress, lm.Ombi, jfID, err)
|
app.err.Printf(lm.FailedSetEmailAddress, lm.Ombi, jfID, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1012,8 +1009,8 @@ func (app *appContext) modifyEmail(jfID string, addr string) {
|
|||||||
func (app *appContext) ModifyEmails(gc *gin.Context) {
|
func (app *appContext) ModifyEmails(gc *gin.Context) {
|
||||||
var req modifyEmailsDTO
|
var req modifyEmailsDTO
|
||||||
gc.BindJSON(&req)
|
gc.BindJSON(&req)
|
||||||
users, status, err := app.jf.GetUsers(false)
|
users, err := app.jf.GetUsers(false)
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetUsers, lm.Jellyfin, err)
|
app.err.Printf(lm.FailedGetUsers, lm.Jellyfin, err)
|
||||||
respond(500, "Couldn't get users", gc)
|
respond(500, "Couldn't get users", gc)
|
||||||
return
|
return
|
||||||
@ -1099,8 +1096,8 @@ func (app *appContext) ApplySettings(gc *gin.Context) {
|
|||||||
} else if req.From == "user" {
|
} else if req.From == "user" {
|
||||||
applyingFromType = lm.User
|
applyingFromType = lm.User
|
||||||
app.jf.CacheExpiry = time.Now()
|
app.jf.CacheExpiry = time.Now()
|
||||||
user, status, err := app.jf.UserByID(req.ID, false)
|
user, err := app.jf.UserByID(req.ID, false)
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetUser, req.ID, lm.Jellyfin, err)
|
app.err.Printf(lm.FailedGetUser, req.ID, lm.Jellyfin, err)
|
||||||
respond(500, "Couldn't get user", gc)
|
respond(500, "Couldn't get user", gc)
|
||||||
return
|
return
|
||||||
@ -1110,8 +1107,8 @@ func (app *appContext) ApplySettings(gc *gin.Context) {
|
|||||||
policy = user.Policy
|
policy = user.Policy
|
||||||
}
|
}
|
||||||
if req.Homescreen {
|
if req.Homescreen {
|
||||||
displayprefs, status, err = app.jf.GetDisplayPreferences(req.ID)
|
displayprefs, err = app.jf.GetDisplayPreferences(req.ID)
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetJellyfinDisplayPrefs, req.ID, err)
|
app.err.Printf(lm.FailedGetJellyfinDisplayPrefs, req.ID, err)
|
||||||
respond(500, "Couldn't get displayprefs", gc)
|
respond(500, "Couldn't get displayprefs", gc)
|
||||||
return
|
return
|
||||||
@ -1136,26 +1133,25 @@ func (app *appContext) ApplySettings(gc *gin.Context) {
|
|||||||
app.debug.Printf(lm.DelayingRequests, requestDelayThreshold)
|
app.debug.Printf(lm.DelayingRequests, requestDelayThreshold)
|
||||||
}
|
}
|
||||||
for _, id := range req.ApplyTo {
|
for _, id := range req.ApplyTo {
|
||||||
var status int
|
|
||||||
var err error
|
var err error
|
||||||
if req.Policy {
|
if req.Policy {
|
||||||
status, err = app.jf.SetPolicy(id, policy)
|
err = app.jf.SetPolicy(id, policy)
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
if err != nil {
|
||||||
errors["policy"][id] = fmt.Sprintf("%d: %s", status, err)
|
errors["policy"][id] = err.Error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if shouldDelay {
|
if shouldDelay {
|
||||||
time.Sleep(250 * time.Millisecond)
|
time.Sleep(250 * time.Millisecond)
|
||||||
}
|
}
|
||||||
if req.Homescreen {
|
if req.Homescreen {
|
||||||
status, err = app.jf.SetConfiguration(id, configuration)
|
err = app.jf.SetConfiguration(id, configuration)
|
||||||
errorString := ""
|
errorString := ""
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
if err != nil {
|
||||||
errorString += fmt.Sprintf("Configuration %d: %v ", status, err)
|
errorString += fmt.Sprintf("Configuration: %v", err)
|
||||||
} else {
|
} else {
|
||||||
status, err = app.jf.SetDisplayPreferences(id, displayprefs)
|
err = app.jf.SetDisplayPreferences(id, displayprefs)
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
if err != nil {
|
||||||
errorString += fmt.Sprintf("Displayprefs %d: %v ", status, err)
|
errorString += fmt.Sprintf("Displayprefs;) %v ", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if errorString != "" {
|
if errorString != "" {
|
||||||
@ -1164,18 +1160,18 @@ func (app *appContext) ApplySettings(gc *gin.Context) {
|
|||||||
}
|
}
|
||||||
if ombi != nil {
|
if ombi != nil {
|
||||||
errorString := ""
|
errorString := ""
|
||||||
user, status, err := app.getOmbiUser(id)
|
user, err := app.getOmbiUser(id)
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
errorString += fmt.Sprintf("Ombi GetUser %d: %v ", status, err)
|
errorString += fmt.Sprintf("Ombi GetUser: %v ", err)
|
||||||
} else {
|
} else {
|
||||||
// newUser := ombi
|
// newUser := ombi
|
||||||
// newUser["id"] = user["id"]
|
// newUser["id"] = user["id"]
|
||||||
// newUser["userName"] = user["userName"]
|
// newUser["userName"] = user["userName"]
|
||||||
// newUser["alias"] = user["alias"]
|
// newUser["alias"] = user["alias"]
|
||||||
// newUser["emailAddress"] = user["emailAddress"]
|
// newUser["emailAddress"] = user["emailAddress"]
|
||||||
status, err = app.ombi.applyProfile(user, ombi)
|
err = app.ombi.applyProfile(user, ombi)
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
errorString += fmt.Sprintf("Apply %d: %v ", status, err)
|
errorString += fmt.Sprintf("Apply: %v ", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if errorString != "" {
|
if errorString != "" {
|
||||||
|
31
api.go
31
api.go
@ -148,18 +148,18 @@ func (app *appContext) ResetSetPassword(gc *gin.Context) {
|
|||||||
userID = reset.ID
|
userID = reset.ID
|
||||||
username = reset.Username
|
username = reset.Username
|
||||||
|
|
||||||
status, err := app.jf.ResetPasswordAdmin(userID)
|
err := app.jf.ResetPasswordAdmin(userID)
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedChangePassword, lm.Jellyfin, userID, err)
|
app.err.Printf(lm.FailedChangePassword, lm.Jellyfin, userID, err)
|
||||||
respondBool(status, false, gc)
|
respondBool(500, false, gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
delete(app.internalPWRs, req.PIN)
|
delete(app.internalPWRs, req.PIN)
|
||||||
} else {
|
} else {
|
||||||
resp, status, err := app.jf.ResetPassword(req.PIN)
|
resp, err := app.jf.ResetPassword(req.PIN)
|
||||||
if status != 200 || err != nil || !resp.Success {
|
if err != nil || !resp.Success {
|
||||||
app.err.Printf(lm.FailedChangePassword, lm.Jellyfin, userID, err)
|
app.err.Printf(lm.FailedChangePassword, lm.Jellyfin, userID, err)
|
||||||
respondBool(status, false, gc)
|
respondBool(500, false, gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if req.Password == "" || len(resp.UsersReset) == 0 {
|
if req.Password == "" || len(resp.UsersReset) == 0 {
|
||||||
@ -170,14 +170,13 @@ func (app *appContext) ResetSetPassword(gc *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var user mediabrowser.User
|
var user mediabrowser.User
|
||||||
var status int
|
|
||||||
var err error
|
var err error
|
||||||
if isInternal {
|
if isInternal {
|
||||||
user, status, err = app.jf.UserByID(userID, false)
|
user, err = app.jf.UserByID(userID, false)
|
||||||
} else {
|
} else {
|
||||||
user, status, err = app.jf.UserByName(username, false)
|
user, err = app.jf.UserByName(username, false)
|
||||||
}
|
}
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetUser, userID, lm.Jellyfin, err)
|
app.err.Printf(lm.FailedGetUser, userID, lm.Jellyfin, err)
|
||||||
respondBool(500, false, gc)
|
respondBool(500, false, gc)
|
||||||
return
|
return
|
||||||
@ -195,8 +194,8 @@ func (app *appContext) ResetSetPassword(gc *gin.Context) {
|
|||||||
if isInternal {
|
if isInternal {
|
||||||
prevPassword = ""
|
prevPassword = ""
|
||||||
}
|
}
|
||||||
status, err = app.jf.SetPassword(user.ID, prevPassword, req.Password)
|
err = app.jf.SetPassword(user.ID, prevPassword, req.Password)
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedChangePassword, lm.Jellyfin, user.ID, err)
|
app.err.Printf(lm.FailedChangePassword, lm.Jellyfin, user.ID, err)
|
||||||
respondBool(500, false, gc)
|
respondBool(500, false, gc)
|
||||||
return
|
return
|
||||||
@ -210,15 +209,15 @@ func (app *appContext) ResetSetPassword(gc *gin.Context) {
|
|||||||
respondBool(200, true, gc)
|
respondBool(200, true, gc)
|
||||||
return
|
return
|
||||||
} */
|
} */
|
||||||
ombiUser, status, err := app.getOmbiUser(user.ID)
|
ombiUser, err := app.getOmbiUser(user.ID)
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetUser, user.ID, lm.Ombi, err)
|
app.err.Printf(lm.FailedGetUser, user.ID, lm.Ombi, err)
|
||||||
respondBool(200, true, gc)
|
respondBool(200, true, gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ombiUser["password"] = req.Password
|
ombiUser["password"] = req.Password
|
||||||
status, err = app.ombi.ModifyUser(ombiUser)
|
err = app.ombi.ModifyUser(ombiUser)
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedChangePassword, lm.Ombi, user.ID, err)
|
app.err.Printf(lm.FailedChangePassword, lm.Ombi, user.ID, err)
|
||||||
respondBool(200, true, gc)
|
respondBool(200, true, gc)
|
||||||
return
|
return
|
||||||
|
11
auth.go
11
auth.go
@ -2,6 +2,7 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
@ -166,19 +167,19 @@ func (app *appContext) decodeValidateLoginHeader(gc *gin.Context, userpage bool)
|
|||||||
|
|
||||||
func (app *appContext) validateJellyfinCredentials(username, password string, gc *gin.Context, userpage bool) (user mediabrowser.User, ok bool) {
|
func (app *appContext) validateJellyfinCredentials(username, password string, gc *gin.Context, userpage bool) (user mediabrowser.User, ok bool) {
|
||||||
ok = false
|
ok = false
|
||||||
user, status, err := app.authJf.Authenticate(username, password)
|
user, err := app.authJf.Authenticate(username, password)
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
if status == 401 || status == 400 {
|
if errors.Is(err, mediabrowser.ErrUnauthorized{}) {
|
||||||
app.logIpInfo(gc, userpage, fmt.Sprintf(lm.FailedAuthRequest, lm.InvalidUserOrPass))
|
app.logIpInfo(gc, userpage, fmt.Sprintf(lm.FailedAuthRequest, lm.InvalidUserOrPass))
|
||||||
respond(401, "Unauthorized", gc)
|
respond(401, "Unauthorized", gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if status == 403 {
|
if errors.Is(err, mediabrowser.ErrForbidden{}) {
|
||||||
app.logIpInfo(gc, userpage, fmt.Sprintf(lm.FailedAuthRequest, lm.UserDisabled))
|
app.logIpInfo(gc, userpage, fmt.Sprintf(lm.FailedAuthRequest, lm.UserDisabled))
|
||||||
respond(403, "yourAccountWasDisabled", gc)
|
respond(403, "yourAccountWasDisabled", gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
app.authLog(fmt.Sprintf(lm.FailedAuthJellyfin, app.jf.Server, status, err))
|
app.authLog(fmt.Sprintf(lm.FailedAuthJellyfin, app.jf.Server, err))
|
||||||
respond(500, "Jellyfin error", gc)
|
respond(500, "Jellyfin error", gc)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package common
|
package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
|
||||||
|
lm "github.com/hrfee/jfa-go/logmessages"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TimeoutHandler recovers from an http timeout or panic.
|
// TimeoutHandler recovers from an http timeout or panic.
|
||||||
@ -12,7 +15,7 @@ type TimeoutHandler func()
|
|||||||
func NewTimeoutHandler(name, addr string, noFail bool) TimeoutHandler {
|
func NewTimeoutHandler(name, addr string, noFail bool) TimeoutHandler {
|
||||||
return func() {
|
return func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
out := fmt.Sprintf("Failed to authenticate with %s @ \"%s\": Timed out", name, addr)
|
out := fmt.Sprintf(lm.FailedAuth, name, addr, 0, lm.TimedOut)
|
||||||
if noFail {
|
if noFail {
|
||||||
log.Print(out)
|
log.Print(out)
|
||||||
} else {
|
} else {
|
||||||
@ -21,3 +24,50 @@ func NewTimeoutHandler(name, addr string, noFail bool) TimeoutHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// most 404 errors are from UserNotFound, so this generic error doesn't really need any detail.
|
||||||
|
type ErrNotFound error
|
||||||
|
|
||||||
|
type ErrUnauthorized struct{}
|
||||||
|
|
||||||
|
func (err ErrUnauthorized) Error() string {
|
||||||
|
return lm.Unauthorized
|
||||||
|
}
|
||||||
|
|
||||||
|
type ErrForbidden struct{}
|
||||||
|
|
||||||
|
func (err ErrForbidden) Error() string {
|
||||||
|
return lm.Forbidden
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
NotFound ErrNotFound = errors.New(lm.NotFound)
|
||||||
|
)
|
||||||
|
|
||||||
|
type ErrUnknown struct {
|
||||||
|
code int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err ErrUnknown) Error() string {
|
||||||
|
msg := fmt.Sprintf(lm.FailedGenericWithCode, err.code)
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
// GenericErr returns an error appropriate to the given HTTP status (or actual error, if given).
|
||||||
|
func GenericErr(status int, err error) error {
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
switch status {
|
||||||
|
case 200, 204, 201:
|
||||||
|
return nil
|
||||||
|
case 401, 400:
|
||||||
|
return ErrUnauthorized{}
|
||||||
|
case 404:
|
||||||
|
return NotFound
|
||||||
|
case 403:
|
||||||
|
return ErrForbidden{}
|
||||||
|
default:
|
||||||
|
return ErrUnknown{code: status}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
module github.com/hrfee/jfa-go/common
|
module github.com/hrfee/jfa-go/common
|
||||||
|
|
||||||
go 1.15
|
replace github.com/hrfee/jfa-go/logmessages => ../logmessages
|
||||||
|
|
||||||
|
go 1.22.4
|
||||||
|
|
||||||
|
require github.com/hrfee/jfa-go/logmessages v0.0.0-20240805130902-86c37fb4237b
|
||||||
|
21
email.go
21
email.go
@ -968,11 +968,10 @@ func (app *appContext) getAddressOrName(jfID string) string {
|
|||||||
// returns "" if none found. returns only the first match, might be an issue if there are users with the same contact method usernames.
|
// returns "" if none found. returns only the first match, might be an issue if there are users with the same contact method usernames.
|
||||||
func (app *appContext) ReverseUserSearch(address string, matchUsername, matchEmail, matchContactMethod bool) (user mediabrowser.User, ok bool) {
|
func (app *appContext) ReverseUserSearch(address string, matchUsername, matchEmail, matchContactMethod bool) (user mediabrowser.User, ok bool) {
|
||||||
ok = false
|
ok = false
|
||||||
var status int
|
|
||||||
var err error = nil
|
var err error = nil
|
||||||
if matchUsername {
|
if matchUsername {
|
||||||
user, status, err = app.jf.UserByName(address, false)
|
user, err = app.jf.UserByName(address, false)
|
||||||
if status == 200 && err == nil {
|
if err == nil {
|
||||||
ok = true
|
ok = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -983,8 +982,8 @@ func (app *appContext) ReverseUserSearch(address string, matchUsername, matchEma
|
|||||||
err = app.storage.db.Find(&emailAddresses, badgerhold.Where("Addr").Eq(address))
|
err = app.storage.db.Find(&emailAddresses, badgerhold.Where("Addr").Eq(address))
|
||||||
if err == nil && len(emailAddresses) > 0 {
|
if err == nil && len(emailAddresses) > 0 {
|
||||||
for _, emailUser := range emailAddresses {
|
for _, emailUser := range emailAddresses {
|
||||||
user, status, err = app.jf.UserByID(emailUser.JellyfinID, false)
|
user, err = app.jf.UserByID(emailUser.JellyfinID, false)
|
||||||
if status == 200 && err == nil {
|
if err == nil {
|
||||||
ok = true
|
ok = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -997,8 +996,8 @@ func (app *appContext) ReverseUserSearch(address string, matchUsername, matchEma
|
|||||||
if matchContactMethod {
|
if matchContactMethod {
|
||||||
for _, dcUser := range app.storage.GetDiscord() {
|
for _, dcUser := range app.storage.GetDiscord() {
|
||||||
if RenderDiscordUsername(dcUser) == strings.ToLower(address) {
|
if RenderDiscordUsername(dcUser) == strings.ToLower(address) {
|
||||||
user, status, err = app.jf.UserByID(dcUser.JellyfinID, false)
|
user, err = app.jf.UserByID(dcUser.JellyfinID, false)
|
||||||
if status == 200 && err == nil {
|
if err == nil {
|
||||||
ok = true
|
ok = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1009,8 +1008,8 @@ func (app *appContext) ReverseUserSearch(address string, matchUsername, matchEma
|
|||||||
err = app.storage.db.Find(&telegramUsers, badgerhold.Where("Username").Eq(tgUsername))
|
err = app.storage.db.Find(&telegramUsers, badgerhold.Where("Username").Eq(tgUsername))
|
||||||
if err == nil && len(telegramUsers) > 0 {
|
if err == nil && len(telegramUsers) > 0 {
|
||||||
for _, telegramUser := range telegramUsers {
|
for _, telegramUser := range telegramUsers {
|
||||||
user, status, err = app.jf.UserByID(telegramUser.JellyfinID, false)
|
user, err = app.jf.UserByID(telegramUser.JellyfinID, false)
|
||||||
if status == 200 && err == nil {
|
if err == nil {
|
||||||
ok = true
|
ok = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -1020,8 +1019,8 @@ func (app *appContext) ReverseUserSearch(address string, matchUsername, matchEma
|
|||||||
err = app.storage.db.Find(&matrixUsers, badgerhold.Where("UserID").Eq(address))
|
err = app.storage.db.Find(&matrixUsers, badgerhold.Where("UserID").Eq(address))
|
||||||
if err == nil && len(matrixUsers) > 0 {
|
if err == nil && len(matrixUsers) > 0 {
|
||||||
for _, matrixUser := range matrixUsers {
|
for _, matrixUser := range matrixUsers {
|
||||||
user, status, err = app.jf.UserByID(matrixUser.JellyfinID, false)
|
user, err = app.jf.UserByID(matrixUser.JellyfinID, false)
|
||||||
if status == 200 && err == nil {
|
if err == nil {
|
||||||
ok = true
|
ok = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
10
go.mod
10
go.mod
@ -33,13 +33,15 @@ require (
|
|||||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible
|
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible
|
||||||
github.com/golang-jwt/jwt v3.2.2+incompatible
|
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||||
github.com/gomarkdown/markdown v0.0.0-20230322041520-c84983bdbf2a
|
github.com/gomarkdown/markdown v0.0.0-20230322041520-c84983bdbf2a
|
||||||
github.com/hrfee/jfa-go/common v0.0.0-20240728190513-dabef831d769
|
github.com/hrfee/jfa-go/common v0.0.0-20240805130902-86c37fb4237b
|
||||||
github.com/hrfee/jfa-go/docs v0.0.0-20230626224816-f72960635dc3
|
github.com/hrfee/jfa-go/docs v0.0.0-20230626224816-f72960635dc3
|
||||||
github.com/hrfee/jfa-go/easyproxy v0.0.0-00010101000000-000000000000
|
github.com/hrfee/jfa-go/easyproxy v0.0.0-00010101000000-000000000000
|
||||||
|
github.com/hrfee/jfa-go/jellyseerr v0.0.0-20240805130902-86c37fb4237b
|
||||||
github.com/hrfee/jfa-go/linecache v0.0.0-20230626224816-f72960635dc3
|
github.com/hrfee/jfa-go/linecache v0.0.0-20230626224816-f72960635dc3
|
||||||
github.com/hrfee/jfa-go/logger v0.0.0-20240731152135-2d066ea7cd32
|
github.com/hrfee/jfa-go/logger v0.0.0-20240731152135-2d066ea7cd32
|
||||||
github.com/hrfee/jfa-go/ombi v0.0.0-20230626224816-f72960635dc3
|
github.com/hrfee/jfa-go/logmessages v0.0.0-20240805130902-86c37fb4237b
|
||||||
github.com/hrfee/mediabrowser v0.3.14
|
github.com/hrfee/jfa-go/ombi v0.0.0-20240805130902-86c37fb4237b
|
||||||
|
github.com/hrfee/mediabrowser v0.3.18
|
||||||
github.com/itchyny/timefmt-go v0.1.5
|
github.com/itchyny/timefmt-go v0.1.5
|
||||||
github.com/lithammer/shortuuid/v3 v3.0.7
|
github.com/lithammer/shortuuid/v3 v3.0.7
|
||||||
github.com/mailgun/mailgun-go/v4 v4.9.1
|
github.com/mailgun/mailgun-go/v4 v4.9.1
|
||||||
@ -92,8 +94,6 @@ require (
|
|||||||
github.com/google/uuid v1.3.0 // indirect
|
github.com/google/uuid v1.3.0 // indirect
|
||||||
github.com/gorilla/mux v1.8.0 // indirect
|
github.com/gorilla/mux v1.8.0 // indirect
|
||||||
github.com/gorilla/websocket v1.5.0 // indirect
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
github.com/hrfee/jfa-go/jellyseerr v0.0.0-00010101000000-000000000000 // indirect
|
|
||||||
github.com/hrfee/jfa-go/logmessages v0.0.0-00010101000000-000000000000 // indirect
|
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
github.com/klauspost/compress v1.16.6 // indirect
|
github.com/klauspost/compress v1.16.6 // indirect
|
||||||
|
16
go.sum
16
go.sum
@ -1,6 +1,7 @@
|
|||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||||
|
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||||
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
|
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
|
||||||
@ -94,6 +95,7 @@ github.com/getlantern/systray v1.2.2/go.mod h1:pXFOI1wwqwYXEhLPm9ZGjS2u/vVELeIgN
|
|||||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||||
github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w=
|
github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w=
|
||||||
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
||||||
|
github.com/gin-contrib/gzip v0.0.6/go.mod h1:QOJlmV2xmayAjkNS2Y8NQsMneuRShOU/kjovCXNuzzk=
|
||||||
github.com/gin-contrib/pprof v1.4.0 h1:XxiBSf5jWZ5i16lNOPbMTVdgHBdhfGRD5PZ1LWazzvg=
|
github.com/gin-contrib/pprof v1.4.0 h1:XxiBSf5jWZ5i16lNOPbMTVdgHBdhfGRD5PZ1LWazzvg=
|
||||||
github.com/gin-contrib/pprof v1.4.0/go.mod h1:RrehPJasUVBPK6yTUwOl8/NP6i0vbUgmxtis+Z5KE90=
|
github.com/gin-contrib/pprof v1.4.0/go.mod h1:RrehPJasUVBPK6yTUwOl8/NP6i0vbUgmxtis+Z5KE90=
|
||||||
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||||
@ -140,6 +142,7 @@ github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogB
|
|||||||
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||||
|
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||||
@ -213,6 +216,7 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||||
|
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||||
@ -224,10 +228,10 @@ github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/ad
|
|||||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||||
github.com/hrfee/mediabrowser v0.3.13 h1:NgQNbq+JWwsP68BdWXL/rwbpfE/oO5LJ5KVkE+aNbX8=
|
github.com/hrfee/mediabrowser v0.3.17 h1:gerX/sxQ8V64mZ13I0zuK9hpCJnScdTpAzD2j0a7bvE=
|
||||||
github.com/hrfee/mediabrowser v0.3.13/go.mod h1:PnHZbdxmbv1wCVdAQyM7nwPwpVj9fdKx2EcET7sAk+U=
|
github.com/hrfee/mediabrowser v0.3.17/go.mod h1:PnHZbdxmbv1wCVdAQyM7nwPwpVj9fdKx2EcET7sAk+U=
|
||||||
github.com/hrfee/mediabrowser v0.3.14 h1:/hxtwefV4pA63fyHussk00JBFry6p+uDDOumA49M1eY=
|
github.com/hrfee/mediabrowser v0.3.18 h1:6UDyae0srEVjiMG+utPQfJJp4UId6/T3WN9EDCQKRTk=
|
||||||
github.com/hrfee/mediabrowser v0.3.14/go.mod h1:PnHZbdxmbv1wCVdAQyM7nwPwpVj9fdKx2EcET7sAk+U=
|
github.com/hrfee/mediabrowser v0.3.18/go.mod h1:PnHZbdxmbv1wCVdAQyM7nwPwpVj9fdKx2EcET7sAk+U=
|
||||||
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
|
||||||
github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE=
|
github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE=
|
||||||
github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8=
|
github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8=
|
||||||
@ -289,6 +293,7 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/
|
|||||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||||
github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
|
github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
|
||||||
|
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||||
@ -351,6 +356,7 @@ github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o
|
|||||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||||
|
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||||
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
|
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
|
||||||
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
|
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
|
||||||
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
|
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
|
||||||
@ -420,6 +426,7 @@ go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
|||||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||||
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||||
|
go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||||
@ -455,6 +462,7 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
|||||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
|
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
|
||||||
|
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
|
@ -16,7 +16,7 @@ func (app *appContext) clearEmails() {
|
|||||||
app.debug.Println(lm.HousekeepingEmail)
|
app.debug.Println(lm.HousekeepingEmail)
|
||||||
emails := app.storage.GetEmails()
|
emails := app.storage.GetEmails()
|
||||||
for _, email := range emails {
|
for _, email := range emails {
|
||||||
_, _, err := app.jf.UserByID(email.JellyfinID, false)
|
_, err := app.jf.UserByID(email.JellyfinID, false)
|
||||||
// Make sure the user doesn't exist, and no other error has occured
|
// Make sure the user doesn't exist, and no other error has occured
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
case mediabrowser.ErrUserNotFound:
|
case mediabrowser.ErrUserNotFound:
|
||||||
@ -32,7 +32,7 @@ func (app *appContext) clearDiscord() {
|
|||||||
app.debug.Println(lm.HousekeepingDiscord)
|
app.debug.Println(lm.HousekeepingDiscord)
|
||||||
discordUsers := app.storage.GetDiscord()
|
discordUsers := app.storage.GetDiscord()
|
||||||
for _, discordUser := range discordUsers {
|
for _, discordUser := range discordUsers {
|
||||||
user, _, err := app.jf.UserByID(discordUser.JellyfinID, false)
|
user, err := app.jf.UserByID(discordUser.JellyfinID, false)
|
||||||
// Make sure the user doesn't exist, and no other error has occured
|
// Make sure the user doesn't exist, and no other error has occured
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
case mediabrowser.ErrUserNotFound:
|
case mediabrowser.ErrUserNotFound:
|
||||||
@ -53,7 +53,7 @@ func (app *appContext) clearMatrix() {
|
|||||||
app.debug.Println(lm.HousekeepingMatrix)
|
app.debug.Println(lm.HousekeepingMatrix)
|
||||||
matrixUsers := app.storage.GetMatrix()
|
matrixUsers := app.storage.GetMatrix()
|
||||||
for _, matrixUser := range matrixUsers {
|
for _, matrixUser := range matrixUsers {
|
||||||
_, _, err := app.jf.UserByID(matrixUser.JellyfinID, false)
|
_, err := app.jf.UserByID(matrixUser.JellyfinID, false)
|
||||||
// Make sure the user doesn't exist, and no other error has occured
|
// Make sure the user doesn't exist, and no other error has occured
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
case mediabrowser.ErrUserNotFound:
|
case mediabrowser.ErrUserNotFound:
|
||||||
@ -69,7 +69,7 @@ func (app *appContext) clearTelegram() {
|
|||||||
app.debug.Println(lm.HousekeepingTelegram)
|
app.debug.Println(lm.HousekeepingTelegram)
|
||||||
telegramUsers := app.storage.GetTelegram()
|
telegramUsers := app.storage.GetTelegram()
|
||||||
for _, telegramUser := range telegramUsers {
|
for _, telegramUser := range telegramUsers {
|
||||||
_, _, err := app.jf.UserByID(telegramUser.JellyfinID, false)
|
_, err := app.jf.UserByID(telegramUser.JellyfinID, false)
|
||||||
// Make sure the user doesn't exist, and no other error has occured
|
// Make sure the user doesn't exist, and no other error has occured
|
||||||
switch err.(type) {
|
switch err.(type) {
|
||||||
case mediabrowser.ErrUserNotFound:
|
case mediabrowser.ErrUserNotFound:
|
||||||
|
@ -44,7 +44,7 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div id="modal-about" class="modal">
|
<div id="modal-about" class="modal">
|
||||||
<div class="relative mx-auto my-[10%] w-11/12 sm:w-4/5 lg:w-1/3 content card">
|
<div class="relative mx-auto my-[10%] w-11/12 sm:w-4/5 lg:w-1/2 content card">
|
||||||
<img src="{{ .urlBase }}/banner.svg" class="banner header" alt="jfa-go banner">
|
<img src="{{ .urlBase }}/banner.svg" class="banner header" alt="jfa-go banner">
|
||||||
<span class="heading"><span class="modal-close">×</span></span>
|
<span class="heading"><span class="modal-close">×</span></span>
|
||||||
<p>{{ .strings.version }} <span class="text-black dark:text-white font-mono bg-inherit">{{ .version }}</span></p>
|
<p>{{ .strings.version }} <span class="text-black dark:text-white font-mono bg-inherit">{{ .version }}</span></p>
|
||||||
|
@ -58,8 +58,8 @@ func (app *appContext) SynchronizeJellyseerrUser(jfID string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (app *appContext) SynchronizeJellyseerrUsers() {
|
func (app *appContext) SynchronizeJellyseerrUsers() {
|
||||||
users, status, err := app.jf.GetUsers(false)
|
users, err := app.jf.GetUsers(false)
|
||||||
if err != nil || status != 200 {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetUsers, lm.Jellyfin, err)
|
app.err.Printf(lm.FailedGetUsers, lm.Jellyfin, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hrfee/jfa-go/common"
|
co "github.com/hrfee/jfa-go/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -28,13 +28,13 @@ type Jellyseerr struct {
|
|||||||
userCache map[string]User // Map of jellyfin IDs to users
|
userCache map[string]User // Map of jellyfin IDs to users
|
||||||
cacheExpiry time.Time
|
cacheExpiry time.Time
|
||||||
cacheLength time.Duration
|
cacheLength time.Duration
|
||||||
timeoutHandler common.TimeoutHandler
|
timeoutHandler co.TimeoutHandler
|
||||||
LogRequestBodies bool
|
LogRequestBodies bool
|
||||||
AutoImportUsers bool
|
AutoImportUsers bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewJellyseerr returns an Ombi object.
|
// NewJellyseerr returns an Ombi object.
|
||||||
func NewJellyseerr(server, key string, timeoutHandler common.TimeoutHandler) *Jellyseerr {
|
func NewJellyseerr(server, key string, timeoutHandler co.TimeoutHandler) *Jellyseerr {
|
||||||
if !strings.HasSuffix(server, API_SUFFIX) {
|
if !strings.HasSuffix(server, API_SUFFIX) {
|
||||||
server = server + API_SUFFIX
|
server = server + API_SUFFIX
|
||||||
}
|
}
|
||||||
@ -82,25 +82,23 @@ func (js *Jellyseerr) req(mode string, uri string, data any, queryParams url.Val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
resp, err := js.httpClient.Do(req)
|
resp, err := js.httpClient.Do(req)
|
||||||
reqFailed := err != nil || !(resp.StatusCode == 200 || resp.StatusCode == 201)
|
err = co.GenericErr(resp.StatusCode, err)
|
||||||
defer js.timeoutHandler()
|
defer js.timeoutHandler()
|
||||||
var responseText string
|
var responseText string
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
if response || reqFailed {
|
if response || err != nil {
|
||||||
responseText, err = js.decodeResp(resp)
|
responseText, err = js.decodeResp(resp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return responseText, resp.StatusCode, err
|
return responseText, resp.StatusCode, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if reqFailed {
|
if err != nil {
|
||||||
var msg ErrorDTO
|
var msg ErrorDTO
|
||||||
err = json.Unmarshal([]byte(responseText), &msg)
|
err = json.Unmarshal([]byte(responseText), &msg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return responseText, resp.StatusCode, err
|
return responseText, resp.StatusCode, err
|
||||||
}
|
}
|
||||||
if msg.Message == "" {
|
if msg.Message != "" {
|
||||||
err = fmt.Errorf("failed (error %d)", resp.StatusCode)
|
|
||||||
} else {
|
|
||||||
err = fmt.Errorf("got %d: %s", resp.StatusCode, msg.Message)
|
err = fmt.Errorf("got %d: %s", resp.StatusCode, msg.Message)
|
||||||
}
|
}
|
||||||
return responseText, resp.StatusCode, err
|
return responseText, resp.StatusCode, err
|
||||||
@ -145,14 +143,11 @@ func (js *Jellyseerr) ImportFromJellyfin(jfIDs ...string) ([]User, error) {
|
|||||||
params := map[string]interface{}{
|
params := map[string]interface{}{
|
||||||
"jellyfinUserIds": jfIDs,
|
"jellyfinUserIds": jfIDs,
|
||||||
}
|
}
|
||||||
resp, status, err := js.post(js.server+"/user/import-from-jellyfin", params, true)
|
resp, _, err := js.post(js.server+"/user/import-from-jellyfin", params, true)
|
||||||
var data []User
|
var data []User
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return data, err
|
return data, err
|
||||||
}
|
}
|
||||||
if status != 200 && status != 201 {
|
|
||||||
return data, fmt.Errorf("failed (error %d)", status)
|
|
||||||
}
|
|
||||||
err = json.Unmarshal([]byte(resp), &data)
|
err = json.Unmarshal([]byte(resp), &data)
|
||||||
for _, u := range data {
|
for _, u := range data {
|
||||||
if u.JellyfinUserID != "" {
|
if u.JellyfinUserID != "" {
|
||||||
@ -197,15 +192,11 @@ func (js *Jellyseerr) getUserPage(page int) (GetUsersDTO, error) {
|
|||||||
if js.LogRequestBodies {
|
if js.LogRequestBodies {
|
||||||
fmt.Printf("Jellyseerr API Client: Sending with URL params \"%+v\"\n", params)
|
fmt.Printf("Jellyseerr API Client: Sending with URL params \"%+v\"\n", params)
|
||||||
}
|
}
|
||||||
resp, status, err := js.get(js.server+"/user", nil, params)
|
resp, _, err := js.get(js.server+"/user", nil, params)
|
||||||
var data GetUsersDTO
|
var data GetUsersDTO
|
||||||
if status != 200 {
|
if err == nil {
|
||||||
return data, fmt.Errorf("failed (error %d)", status)
|
err = json.Unmarshal([]byte(resp), &data)
|
||||||
}
|
}
|
||||||
if err != nil {
|
|
||||||
return data, err
|
|
||||||
}
|
|
||||||
err = json.Unmarshal([]byte(resp), &data)
|
|
||||||
return data, err
|
return data, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,12 +252,9 @@ func (js *Jellyseerr) getUser(jfID string) (User, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (js *Jellyseerr) Me() (User, error) {
|
func (js *Jellyseerr) Me() (User, error) {
|
||||||
resp, status, err := js.get(js.server+"/auth/me", nil, url.Values{})
|
resp, _, err := js.get(js.server+"/auth/me", nil, url.Values{})
|
||||||
var data User
|
var data User
|
||||||
data.ID = -1
|
data.ID = -1
|
||||||
if status != 200 {
|
|
||||||
return data, fmt.Errorf("failed (error %d)", status)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return data, err
|
return data, err
|
||||||
}
|
}
|
||||||
@ -281,13 +269,10 @@ func (js *Jellyseerr) GetPermissions(jfID string) (Permissions, error) {
|
|||||||
return data.Permissions, err
|
return data.Permissions, err
|
||||||
}
|
}
|
||||||
|
|
||||||
resp, status, err := js.get(fmt.Sprintf(js.server+"/user/%d/settings/permissions", u.ID), nil, url.Values{})
|
resp, _, err := js.get(fmt.Sprintf(js.server+"/user/%d/settings/permissions", u.ID), nil, url.Values{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return data.Permissions, err
|
return data.Permissions, err
|
||||||
}
|
}
|
||||||
if status != 200 {
|
|
||||||
return data.Permissions, fmt.Errorf("failed (error %d)", status)
|
|
||||||
}
|
|
||||||
err = json.Unmarshal([]byte(resp), &data)
|
err = json.Unmarshal([]byte(resp), &data)
|
||||||
return data.Permissions, err
|
return data.Permissions, err
|
||||||
}
|
}
|
||||||
@ -298,13 +283,10 @@ func (js *Jellyseerr) SetPermissions(jfID string, perm Permissions) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, status, err := js.post(fmt.Sprintf(js.server+"/user/%d/settings/permissions", u.ID), permissionsDTO{Permissions: perm}, false)
|
_, _, err = js.post(fmt.Sprintf(js.server+"/user/%d/settings/permissions", u.ID), permissionsDTO{Permissions: perm}, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if status != 200 && status != 201 {
|
|
||||||
return fmt.Errorf("failed (error %d)", status)
|
|
||||||
}
|
|
||||||
u.Permissions = perm
|
u.Permissions = perm
|
||||||
js.userCache[jfID] = u
|
js.userCache[jfID] = u
|
||||||
return nil
|
return nil
|
||||||
@ -316,13 +298,10 @@ func (js *Jellyseerr) ApplyTemplateToUser(jfID string, tmpl UserTemplate) error
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, status, err := js.put(fmt.Sprintf(js.server+"/user/%d", u.ID), tmpl, false)
|
_, _, err = js.put(fmt.Sprintf(js.server+"/user/%d", u.ID), tmpl, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if status != 200 && status != 201 {
|
|
||||||
return fmt.Errorf("failed (error %d)", status)
|
|
||||||
}
|
|
||||||
u.UserTemplate = tmpl
|
u.UserTemplate = tmpl
|
||||||
js.userCache[jfID] = u
|
js.userCache[jfID] = u
|
||||||
return nil
|
return nil
|
||||||
@ -337,13 +316,10 @@ func (js *Jellyseerr) ModifyUser(jfID string, conf map[UserField]any) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, status, err := js.put(fmt.Sprintf(js.server+"/user/%d", u.ID), conf, false)
|
_, _, err = js.put(fmt.Sprintf(js.server+"/user/%d", u.ID), conf, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if status != 200 && status != 201 {
|
|
||||||
return fmt.Errorf("failed (error %d)", status)
|
|
||||||
}
|
|
||||||
// Lazily just invalidate the cache.
|
// Lazily just invalidate the cache.
|
||||||
js.cacheExpiry = time.Now()
|
js.cacheExpiry = time.Now()
|
||||||
return nil
|
return nil
|
||||||
@ -355,10 +331,7 @@ func (js *Jellyseerr) DeleteUser(jfID string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
status, err := js.delete(fmt.Sprintf(js.server+"/user/%d", u.ID), nil)
|
_, err = js.delete(fmt.Sprintf(js.server+"/user/%d", u.ID), nil)
|
||||||
if status != 200 && status != 201 {
|
|
||||||
return fmt.Errorf("failed (error %d)", status)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -376,13 +349,10 @@ func (js *Jellyseerr) GetNotificationPreferences(jfID string) (Notifications, er
|
|||||||
|
|
||||||
func (js *Jellyseerr) GetNotificationPreferencesByID(jellyseerrID int64) (Notifications, error) {
|
func (js *Jellyseerr) GetNotificationPreferencesByID(jellyseerrID int64) (Notifications, error) {
|
||||||
var data Notifications
|
var data Notifications
|
||||||
resp, status, err := js.get(fmt.Sprintf(js.server+"/user/%d/settings/notifications", jellyseerrID), nil, url.Values{})
|
resp, _, err := js.get(fmt.Sprintf(js.server+"/user/%d/settings/notifications", jellyseerrID), nil, url.Values{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return data, err
|
return data, err
|
||||||
}
|
}
|
||||||
if status != 200 {
|
|
||||||
return data, fmt.Errorf("failed (error %d)", status)
|
|
||||||
}
|
|
||||||
err = json.Unmarshal([]byte(resp), &data)
|
err = json.Unmarshal([]byte(resp), &data)
|
||||||
return data, err
|
return data, err
|
||||||
}
|
}
|
||||||
@ -397,13 +367,10 @@ func (js *Jellyseerr) ApplyNotificationsTemplateToUser(jfID string, tmpl Notific
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, status, err := js.post(fmt.Sprintf(js.server+"/user/%d/settings/notifications", u.ID), tmpl, false)
|
_, _, err = js.post(fmt.Sprintf(js.server+"/user/%d/settings/notifications", u.ID), tmpl, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if status != 200 && status != 201 {
|
|
||||||
return fmt.Errorf("failed (error %d)", status)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -413,13 +380,10 @@ func (js *Jellyseerr) ModifyNotifications(jfID string, conf map[NotificationsFie
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, status, err := js.post(fmt.Sprintf(js.server+"/user/%d/settings/notifications", u.ID), conf, false)
|
_, _, err = js.post(fmt.Sprintf(js.server+"/user/%d/settings/notifications", u.ID), conf, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if status != 200 && status != 201 {
|
|
||||||
return fmt.Errorf("failed (error %d)", status)
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -429,11 +393,8 @@ func (js *Jellyseerr) GetUsers() (map[string]User, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (js *Jellyseerr) UserByID(jellyseerrID int64) (User, error) {
|
func (js *Jellyseerr) UserByID(jellyseerrID int64) (User, error) {
|
||||||
resp, status, err := js.get(js.server+fmt.Sprintf("/user/%d", jellyseerrID), nil, url.Values{})
|
resp, _, err := js.get(js.server+fmt.Sprintf("/user/%d", jellyseerrID), nil, url.Values{})
|
||||||
var data User
|
var data User
|
||||||
if status != 200 {
|
|
||||||
return data, fmt.Errorf("failed (error %d)", status)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return data, err
|
return data, err
|
||||||
}
|
}
|
||||||
@ -447,13 +408,10 @@ func (js *Jellyseerr) ModifyMainUserSettings(jfID string, conf MainUserSettings)
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
_, status, err := js.post(fmt.Sprintf(js.server+"/user/%d/settings/main", u.ID), conf, false)
|
_, _, err = js.post(fmt.Sprintf(js.server+"/user/%d/settings/main", u.ID), conf, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if status != 200 && status != 201 {
|
|
||||||
return fmt.Errorf("failed (error %d)", status)
|
|
||||||
}
|
|
||||||
// Lazily just invalidate the cache.
|
// Lazily just invalidate the cache.
|
||||||
js.cacheExpiry = time.Now()
|
js.cacheExpiry = time.Now()
|
||||||
return nil
|
return nil
|
||||||
|
@ -1,3 +1,3 @@
|
|||||||
module github.com/hrfee/logmessages
|
module github.com/hrfee/jfa-go/logmessages
|
||||||
|
|
||||||
go 1.22.4
|
go 1.22.4
|
||||||
|
@ -45,7 +45,7 @@ const (
|
|||||||
|
|
||||||
UsingTLS = "Using TLS/HTTP2"
|
UsingTLS = "Using TLS/HTTP2"
|
||||||
|
|
||||||
UsingOmbi = "Starting " + " + Ombi + " + " client"
|
UsingOmbi = "Starting " + Ombi + " client"
|
||||||
UsingJellyseerr = "Starting " + Jellyseerr + " client"
|
UsingJellyseerr = "Starting " + Jellyseerr + " client"
|
||||||
UsingEmby = "Using Emby server type (EXPERIMENTAL: PWRs are not available, and support is limited.)"
|
UsingEmby = "Using Emby server type (EXPERIMENTAL: PWRs are not available, and support is limited.)"
|
||||||
UsingJellyfin = "Using " + Jellyfin + " server type"
|
UsingJellyfin = "Using " + Jellyfin + " server type"
|
||||||
@ -54,6 +54,13 @@ const (
|
|||||||
|
|
||||||
AuthJellyfin = "Authenticated with " + Jellyfin + " @ \"%s\""
|
AuthJellyfin = "Authenticated with " + Jellyfin + " @ \"%s\""
|
||||||
FailedAuthJellyfin = "Failed to authenticate with " + Jellyfin + " @ \"%s\" (code %d): %v"
|
FailedAuthJellyfin = "Failed to authenticate with " + Jellyfin + " @ \"%s\" (code %d): %v"
|
||||||
|
FailedAuth = "Failed to authenticate with %s @ \"%s\" (code %d): %v"
|
||||||
|
|
||||||
|
Unauthorized = "unauthorized, check credentials"
|
||||||
|
Forbidden = "forbidden, the user may not have correct permissions"
|
||||||
|
NotFound = "not found"
|
||||||
|
TimedOut = "timed out"
|
||||||
|
FailedGenericWithCode = "failed (code %d)"
|
||||||
|
|
||||||
InitDiscord = "Initialized Discord daemon"
|
InitDiscord = "Initialized Discord daemon"
|
||||||
FailedInitDiscord = "Failed to initialize Discord daemon: %v"
|
FailedInitDiscord = "Failed to initialize Discord daemon: %v"
|
||||||
@ -213,7 +220,6 @@ const (
|
|||||||
FailedGetDiscordChannel = "Failed to get " + Discord + " channel \"%s\": %v"
|
FailedGetDiscordChannel = "Failed to get " + Discord + " channel \"%s\": %v"
|
||||||
MonitorAllDiscordChannels = "Will monitor all " + Discord + " channels"
|
MonitorAllDiscordChannels = "Will monitor all " + Discord + " channels"
|
||||||
FailedCreateDiscordDMChannel = "Failed to create " + Discord + " private DM channel with \"%s\": %v"
|
FailedCreateDiscordDMChannel = "Failed to create " + Discord + " private DM channel with \"%s\": %v"
|
||||||
NotFound = "not found"
|
|
||||||
RegisterDiscordChoice = "Registered " + Discord + " %s choice \"%s\""
|
RegisterDiscordChoice = "Registered " + Discord + " %s choice \"%s\""
|
||||||
FailedRegisterDiscordChoices = "Failed to register " + Discord + " %s choices: %v"
|
FailedRegisterDiscordChoices = "Failed to register " + Discord + " %s choices: %v"
|
||||||
FailedDeregDiscordChoice = "Failed to deregister " + Discord + " %s choice \"%s\": %v"
|
FailedDeregDiscordChoice = "Failed to deregister " + Discord + " %s choice \"%s\": %v"
|
||||||
|
12
main.go
12
main.go
@ -154,8 +154,8 @@ func test(app *appContext) {
|
|||||||
for n, v := range settings {
|
for n, v := range settings {
|
||||||
fmt.Println(n, ":", v)
|
fmt.Println(n, ":", v)
|
||||||
}
|
}
|
||||||
users, status, err := app.jf.GetUsers(false)
|
users, err := app.jf.GetUsers(false)
|
||||||
fmt.Printf("GetUsers: code %d err %s maplength %d\n", status, err, len(users))
|
fmt.Printf("GetUsers: err %s maplength %d\n", err, len(users))
|
||||||
fmt.Printf("View output? [y/n]: ")
|
fmt.Printf("View output? [y/n]: ")
|
||||||
var choice string
|
var choice string
|
||||||
fmt.Scanln(&choice)
|
fmt.Scanln(&choice)
|
||||||
@ -166,8 +166,8 @@ func test(app *appContext) {
|
|||||||
fmt.Printf("Enter a user to grab: ")
|
fmt.Printf("Enter a user to grab: ")
|
||||||
var username string
|
var username string
|
||||||
fmt.Scanln(&username)
|
fmt.Scanln(&username)
|
||||||
user, status, err := app.jf.UserByName(username, false)
|
user, err := app.jf.UserByName(username, false)
|
||||||
fmt.Printf("UserByName (%s): code %d err %s", username, status, err)
|
fmt.Printf("UserByName (%s): code %d err %s", username, err)
|
||||||
out, _ := json.MarshalIndent(user, "", " ")
|
out, _ := json.MarshalIndent(user, "", " ")
|
||||||
fmt.Print(string(out))
|
fmt.Print(string(out))
|
||||||
}
|
}
|
||||||
@ -436,8 +436,8 @@ func start(asDaemon, firstCall bool) {
|
|||||||
RetryGap: time.Duration(app.config.Section("advanced").Key("auth_retry_gap").MustInt(10)) * time.Second,
|
RetryGap: time.Duration(app.config.Section("advanced").Key("auth_retry_gap").MustInt(10)) * time.Second,
|
||||||
LogFailures: true,
|
LogFailures: true,
|
||||||
}
|
}
|
||||||
_, status, err = app.jf.MustAuthenticate(app.config.Section("jellyfin").Key("username").String(), app.config.Section("jellyfin").Key("password").String(), retryOpts)
|
_, err = app.jf.MustAuthenticate(app.config.Section("jellyfin").Key("username").String(), app.config.Section("jellyfin").Key("password").String(), retryOpts)
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
app.err.Fatalf(lm.FailedAuthJellyfin, server, status, err)
|
app.err.Fatalf(lm.FailedAuthJellyfin, server, status, err)
|
||||||
}
|
}
|
||||||
app.info.Printf(lm.AuthJellyfin, server)
|
app.info.Printf(lm.AuthJellyfin, server)
|
||||||
|
@ -185,14 +185,14 @@ func linkExistingOmbiDiscordTelegram(app *appContext) error {
|
|||||||
idList[user.JellyfinID] = vals
|
idList[user.JellyfinID] = vals
|
||||||
}
|
}
|
||||||
for jfID, ids := range idList {
|
for jfID, ids := range idList {
|
||||||
ombiUser, status, err := app.getOmbiUser(jfID)
|
ombiUser, err := app.getOmbiUser(jfID)
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
app.debug.Printf("Failed to get Ombi user with Discord/Telegram \"%s\"/\"%s\" (%d): %v", ids[0], ids[1], status, err)
|
app.debug.Printf("Failed to get Ombi user with Discord/Telegram \"%s\"/\"%s\": %v", ids[0], ids[1], err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
_, status, err = app.ombi.SetNotificationPrefs(ombiUser, ids[0], ids[1])
|
_, err = app.ombi.SetNotificationPrefs(ombiUser, ids[0], ids[1])
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
app.debug.Printf("Failed to set prefs for Ombi user \"%s\" (%d): %v", ombiUser["userName"].(string), status, err)
|
app.debug.Printf("Failed to set prefs for Ombi user \"%s\": %v", ombiUser["userName"].(string), err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,3 +3,5 @@ module github.com/hrfee/jfa-go/ombi
|
|||||||
replace github.com/hrfee/jfa-go/common => ../common
|
replace github.com/hrfee/jfa-go/common => ../common
|
||||||
|
|
||||||
go 1.15
|
go 1.15
|
||||||
|
|
||||||
|
require github.com/hrfee/jfa-go/common v0.0.0-20240805130902-86c37fb4237b // indirect
|
||||||
|
43
ombi/ombi.go
43
ombi/ombi.go
@ -10,7 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/hrfee/jfa-go/common"
|
co "github.com/hrfee/jfa-go/common"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -26,11 +26,11 @@ type Ombi struct {
|
|||||||
userCache []map[string]interface{}
|
userCache []map[string]interface{}
|
||||||
cacheExpiry time.Time
|
cacheExpiry time.Time
|
||||||
cacheLength int
|
cacheLength int
|
||||||
timeoutHandler common.TimeoutHandler
|
timeoutHandler co.TimeoutHandler
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewOmbi returns an Ombi object.
|
// NewOmbi returns an Ombi object.
|
||||||
func NewOmbi(server, key string, timeoutHandler common.TimeoutHandler) *Ombi {
|
func NewOmbi(server, key string, timeoutHandler co.TimeoutHandler) *Ombi {
|
||||||
return &Ombi{
|
return &Ombi{
|
||||||
server: server,
|
server: server,
|
||||||
key: key,
|
key: key,
|
||||||
@ -133,17 +133,19 @@ func (ombi *Ombi) put(url string, data map[string]interface{}, response bool) (s
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ModifyUser applies the given modified user object to the corresponding user.
|
// ModifyUser applies the given modified user object to the corresponding user.
|
||||||
func (ombi *Ombi) ModifyUser(user map[string]interface{}) (status int, err error) {
|
func (ombi *Ombi) ModifyUser(user map[string]interface{}) (err error) {
|
||||||
if _, ok := user["id"]; !ok {
|
if _, ok := user["id"]; !ok {
|
||||||
err = fmt.Errorf("No ID provided")
|
err = fmt.Errorf("No ID provided")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
var status int
|
||||||
_, status, err = ombi.put(ombi.server+"/api/v1/Identity/", user, false)
|
_, status, err = ombi.put(ombi.server+"/api/v1/Identity/", user, false)
|
||||||
|
err = co.GenericErr(status, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteUser deletes the user corresponding to the given ID.
|
// DeleteUser deletes the user corresponding to the given ID.
|
||||||
func (ombi *Ombi) DeleteUser(id string) (code int, err error) {
|
func (ombi *Ombi) DeleteUser(id string) (err error) {
|
||||||
url := fmt.Sprintf("%s/api/v1/Identity/%s", ombi.server, id)
|
url := fmt.Sprintf("%s/api/v1/Identity/%s", ombi.server, id)
|
||||||
req, _ := http.NewRequest("DELETE", url, nil)
|
req, _ := http.NewRequest("DELETE", url, nil)
|
||||||
req.Header.Add("Content-Type", "application/json")
|
req.Header.Add("Content-Type", "application/json")
|
||||||
@ -152,18 +154,19 @@ func (ombi *Ombi) DeleteUser(id string) (code int, err error) {
|
|||||||
}
|
}
|
||||||
resp, err := ombi.httpClient.Do(req)
|
resp, err := ombi.httpClient.Do(req)
|
||||||
defer ombi.timeoutHandler()
|
defer ombi.timeoutHandler()
|
||||||
return resp.StatusCode, err
|
return co.GenericErr(resp.StatusCode, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UserByID returns the user corresponding to the provided ID.
|
// UserByID returns the user corresponding to the provided ID.
|
||||||
func (ombi *Ombi) UserByID(id string) (result map[string]interface{}, code int, err error) {
|
func (ombi *Ombi) UserByID(id string) (result map[string]interface{}, err error) {
|
||||||
resp, code, err := ombi.getJSON(fmt.Sprintf("%s/api/v1/Identity/User/%s", ombi.server, id), nil)
|
resp, code, err := ombi.getJSON(fmt.Sprintf("%s/api/v1/Identity/User/%s", ombi.server, id), nil)
|
||||||
|
err = co.GenericErr(code, err)
|
||||||
json.Unmarshal([]byte(resp), &result)
|
json.Unmarshal([]byte(resp), &result)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUsers returns all users on the Ombi instance.
|
// GetUsers returns all users on the Ombi instance.
|
||||||
func (ombi *Ombi) GetUsers() ([]map[string]interface{}, int, error) {
|
func (ombi *Ombi) GetUsers() ([]map[string]interface{}, error) {
|
||||||
if time.Now().After(ombi.cacheExpiry) {
|
if time.Now().After(ombi.cacheExpiry) {
|
||||||
resp, code, err := ombi.getJSON(fmt.Sprintf("%s/api/v1/Identity/Users", ombi.server), nil)
|
resp, code, err := ombi.getJSON(fmt.Sprintf("%s/api/v1/Identity/Users", ombi.server), nil)
|
||||||
var result []map[string]interface{}
|
var result []map[string]interface{}
|
||||||
@ -172,9 +175,10 @@ func (ombi *Ombi) GetUsers() ([]map[string]interface{}, int, error) {
|
|||||||
if (code == 200 || code == 204) && err == nil {
|
if (code == 200 || code == 204) && err == nil {
|
||||||
ombi.cacheExpiry = time.Now().Add(time.Minute * time.Duration(ombi.cacheLength))
|
ombi.cacheExpiry = time.Now().Add(time.Minute * time.Duration(ombi.cacheLength))
|
||||||
}
|
}
|
||||||
return result, code, err
|
err = co.GenericErr(code, err)
|
||||||
|
return result, err
|
||||||
}
|
}
|
||||||
return ombi.userCache, 200, nil
|
return ombi.userCache, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Strip these from a user when saving as a template.
|
// Strip these from a user when saving as a template.
|
||||||
@ -190,9 +194,9 @@ var stripFromOmbi = []string{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TemplateByID returns a template based on the user corresponding to the provided ID's settings.
|
// TemplateByID returns a template based on the user corresponding to the provided ID's settings.
|
||||||
func (ombi *Ombi) TemplateByID(id string) (result map[string]interface{}, code int, err error) {
|
func (ombi *Ombi) TemplateByID(id string) (result map[string]interface{}, err error) {
|
||||||
result, code, err = ombi.UserByID(id)
|
result, err = ombi.UserByID(id)
|
||||||
if err != nil || code != 200 {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
for _, key := range stripFromOmbi {
|
for _, key := range stripFromOmbi {
|
||||||
@ -209,24 +213,25 @@ func (ombi *Ombi) TemplateByID(id string) (result map[string]interface{}, code i
|
|||||||
}
|
}
|
||||||
|
|
||||||
// NewUser creates a new user with the given username, password and email address.
|
// NewUser creates a new user with the given username, password and email address.
|
||||||
func (ombi *Ombi) NewUser(username, password, email string, template map[string]interface{}) ([]string, int, error) {
|
func (ombi *Ombi) NewUser(username, password, email string, template map[string]interface{}) ([]string, error) {
|
||||||
url := fmt.Sprintf("%s/api/v1/Identity", ombi.server)
|
url := fmt.Sprintf("%s/api/v1/Identity", ombi.server)
|
||||||
user := template
|
user := template
|
||||||
user["userName"] = username
|
user["userName"] = username
|
||||||
user["password"] = password
|
user["password"] = password
|
||||||
user["emailAddress"] = email
|
user["emailAddress"] = email
|
||||||
resp, code, err := ombi.post(url, user, true)
|
resp, code, err := ombi.post(url, user, true)
|
||||||
|
err = co.GenericErr(code, err)
|
||||||
var data map[string]interface{}
|
var data map[string]interface{}
|
||||||
json.Unmarshal([]byte(resp), &data)
|
json.Unmarshal([]byte(resp), &data)
|
||||||
if err != nil || code != 200 {
|
if err != nil {
|
||||||
var lst []string
|
var lst []string
|
||||||
if data["errors"] != nil {
|
if data["errors"] != nil {
|
||||||
lst = data["errors"].([]string)
|
lst = data["errors"].([]string)
|
||||||
}
|
}
|
||||||
return lst, code, err
|
return lst, err
|
||||||
}
|
}
|
||||||
ombi.cacheExpiry = time.Now()
|
ombi.cacheExpiry = time.Now()
|
||||||
return nil, code, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
type NotificationPref struct {
|
type NotificationPref struct {
|
||||||
@ -236,7 +241,7 @@ type NotificationPref struct {
|
|||||||
Enabled bool `json:"enabled"`
|
Enabled bool `json:"enabled"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ombi *Ombi) SetNotificationPrefs(user map[string]interface{}, discordID, telegramUser string) (result string, code int, err error) {
|
func (ombi *Ombi) SetNotificationPrefs(user map[string]interface{}, discordID, telegramUser string) (result string, err error) {
|
||||||
id := user["id"].(string)
|
id := user["id"].(string)
|
||||||
url := fmt.Sprintf("%s/api/v1/Identity/NotificationPreferences", ombi.server)
|
url := fmt.Sprintf("%s/api/v1/Identity/NotificationPreferences", ombi.server)
|
||||||
data := []NotificationPref{}
|
data := []NotificationPref{}
|
||||||
@ -246,6 +251,8 @@ func (ombi *Ombi) SetNotificationPrefs(user map[string]interface{}, discordID, t
|
|||||||
if telegramUser != "" {
|
if telegramUser != "" {
|
||||||
data = append(data, NotificationPref{NotifAgentTelegram, id, telegramUser, true})
|
data = append(data, NotificationPref{NotifAgentTelegram, id, telegramUser, true})
|
||||||
}
|
}
|
||||||
|
var code int
|
||||||
result, code, err = ombi.send("POST", url, data, true, map[string]string{"UserName": user["userName"].(string)})
|
result, code, err = ombi.send("POST", url, data, true, map[string]string{"UserName": user["userName"].(string)})
|
||||||
|
err = co.GenericErr(code, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -14,8 +14,8 @@ import (
|
|||||||
// GenInternalReset generates a local password reset PIN, for use with the PWR option on the Admin page.
|
// GenInternalReset generates a local password reset PIN, for use with the PWR option on the Admin page.
|
||||||
func (app *appContext) GenInternalReset(userID string) (InternalPWR, error) {
|
func (app *appContext) GenInternalReset(userID string) (InternalPWR, error) {
|
||||||
pin := genAuthToken()
|
pin := genAuthToken()
|
||||||
user, status, err := app.jf.UserByID(userID, false)
|
user, err := app.jf.UserByID(userID, false)
|
||||||
if err != nil || status != 200 {
|
if err != nil {
|
||||||
return InternalPWR{}, err
|
return InternalPWR{}, err
|
||||||
}
|
}
|
||||||
pwr := InternalPWR{
|
pwr := InternalPWR{
|
||||||
@ -95,8 +95,8 @@ func pwrMonitor(app *appContext, watcher *fsnotify.Watcher) {
|
|||||||
}
|
}
|
||||||
app.info.Printf("New password reset for user \"%s\"", pwr.Username)
|
app.info.Printf("New password reset for user \"%s\"", pwr.Username)
|
||||||
if currentTime := time.Now(); pwr.Expiry.After(currentTime) {
|
if currentTime := time.Now(); pwr.Expiry.After(currentTime) {
|
||||||
user, status, err := app.jf.UserByName(pwr.Username, false)
|
user, err := app.jf.UserByName(pwr.Username, false)
|
||||||
if !(status == 200 || status == 204) || err != nil || user.ID == "" {
|
if err != nil || user.ID == "" {
|
||||||
app.err.Printf(lm.FailedGetUser, pwr.Username, lm.Jellyfin, err)
|
app.err.Printf(lm.FailedGetUser, pwr.Username, lm.Jellyfin, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
21
setup.go
21
setup.go
@ -91,19 +91,22 @@ func (app *appContext) TestJF(gc *gin.Context) {
|
|||||||
tempjf.SetTransport(transport)
|
tempjf.SetTransport(transport)
|
||||||
}
|
}
|
||||||
|
|
||||||
user, status, err := tempjf.Authenticate(req.Username, req.Password)
|
user, err := tempjf.Authenticate(req.Username, req.Password)
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
if err != nil {
|
||||||
msg := ""
|
msg := ""
|
||||||
switch status {
|
status := 500
|
||||||
case 0:
|
switch err.(type) {
|
||||||
msg = "errorConnectionRefused"
|
case mediabrowser.ErrUnauthorized:
|
||||||
status = 500
|
|
||||||
case 401:
|
|
||||||
msg = "errorInvalidUserPass"
|
msg = "errorInvalidUserPass"
|
||||||
case 403:
|
status = 401
|
||||||
|
case mediabrowser.ErrForbidden:
|
||||||
msg = "errorUserDisabled"
|
msg = "errorUserDisabled"
|
||||||
case 404:
|
status = 403
|
||||||
|
case mediabrowser.ErrNotFound:
|
||||||
msg = "error404"
|
msg = "error404"
|
||||||
|
status = 404
|
||||||
|
default:
|
||||||
|
msg = "errorConnectionRefused"
|
||||||
}
|
}
|
||||||
app.err.Printf(lm.FailedAuthJellyfin, req.Server, status, err)
|
app.err.Printf(lm.FailedAuthJellyfin, req.Server, status, err)
|
||||||
if msg != "" {
|
if msg != "" {
|
||||||
|
@ -24,8 +24,8 @@ func (app *appContext) checkUsers() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
app.info.Println(lm.CheckUserExpiries)
|
app.info.Println(lm.CheckUserExpiries)
|
||||||
users, status, err := app.jf.GetUsers(false)
|
users, err := app.jf.GetUsers(false)
|
||||||
if err != nil || status != 200 {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetUsers, lm.Jellyfin, err)
|
app.err.Printf(lm.FailedGetUsers, lm.Jellyfin, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ func (app *appContext) checkUsers() {
|
|||||||
err, _, _ = app.SetUserDisabled(user, true)
|
err, _, _ = app.SetUserDisabled(user, true)
|
||||||
activity.Type = ActivityDisabled
|
activity.Type = ActivityDisabled
|
||||||
}
|
}
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedDeleteOrDisableExpiredUser, user.ID, err)
|
app.err.Printf(lm.FailedDeleteOrDisableExpiredUser, user.ID, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
41
users.go
41
users.go
@ -1,7 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
@ -68,7 +67,7 @@ func (app *appContext) NewUserPostVerification(p NewUserParams) (out NewUserData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
existingUser, _, _ := app.jf.UserByName(p.Req.Username, false)
|
existingUser, _ := app.jf.UserByName(p.Req.Username, false)
|
||||||
if existingUser.Name != "" {
|
if existingUser.Name != "" {
|
||||||
out.Message = lm.UserExists
|
out.Message = lm.UserExists
|
||||||
deferLogInfo(lm.FailedCreateUser, lm.Jellyfin, p.Req.Username, out.Message)
|
deferLogInfo(lm.FailedCreateUser, lm.Jellyfin, p.Req.Username, out.Message)
|
||||||
@ -76,10 +75,9 @@ func (app *appContext) NewUserPostVerification(p NewUserParams) (out NewUserData
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var status int
|
|
||||||
var err error
|
var err error
|
||||||
out.User, status, err = app.jf.NewUser(p.Req.Username, p.Req.Password)
|
out.User, err = app.jf.NewUser(p.Req.Username, p.Req.Password)
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
if err != nil {
|
||||||
out.Message = err.Error()
|
out.Message = err.Error()
|
||||||
deferLogError(lm.FailedCreateUser, lm.Jellyfin, p.Req.Username, out.Message)
|
deferLogError(lm.FailedCreateUser, lm.Jellyfin, p.Req.Username, out.Message)
|
||||||
out.Status = 401
|
out.Status = 401
|
||||||
@ -100,15 +98,15 @@ func (app *appContext) NewUserPostVerification(p NewUserParams) (out NewUserData
|
|||||||
}, p.ContextForIPLogging, (p.SourceType != ActivityAdmin))
|
}, p.ContextForIPLogging, (p.SourceType != ActivityAdmin))
|
||||||
|
|
||||||
if p.Profile != nil {
|
if p.Profile != nil {
|
||||||
status, err = app.jf.SetPolicy(out.User.ID, p.Profile.Policy)
|
err = app.jf.SetPolicy(out.User.ID, p.Profile.Policy)
|
||||||
if !((status == 200 || status == 204) && err == nil) {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedApplyTemplate, "policy", lm.Jellyfin, out.User.ID, err)
|
app.err.Printf(lm.FailedApplyTemplate, "policy", lm.Jellyfin, out.User.ID, err)
|
||||||
}
|
}
|
||||||
status, err = app.jf.SetConfiguration(out.User.ID, p.Profile.Configuration)
|
err = app.jf.SetConfiguration(out.User.ID, p.Profile.Configuration)
|
||||||
if (status == 200 || status == 204) && err == nil {
|
if err == nil {
|
||||||
status, err = app.jf.SetDisplayPreferences(out.User.ID, p.Profile.Displayprefs)
|
err = app.jf.SetDisplayPreferences(out.User.ID, p.Profile.Displayprefs)
|
||||||
}
|
}
|
||||||
if !((status == 200 || status == 204) && err == nil) {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedApplyTemplate, "configuration", lm.Jellyfin, out.User.ID, err)
|
app.err.Printf(lm.FailedApplyTemplate, "configuration", lm.Jellyfin, out.User.ID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,11 +162,7 @@ func (app *appContext) SetUserDisabled(user mediabrowser.User, disabled bool) (e
|
|||||||
change = user.Policy.IsDisabled != disabled
|
change = user.Policy.IsDisabled != disabled
|
||||||
user.Policy.IsDisabled = disabled
|
user.Policy.IsDisabled = disabled
|
||||||
|
|
||||||
var status int
|
err = app.jf.SetPolicy(user.ID, user.Policy)
|
||||||
status, err = app.jf.SetPolicy(user.ID, user.Policy)
|
|
||||||
if !(status == 200 || status == 204) && err == nil {
|
|
||||||
err = fmt.Errorf("failed (code %d)", status)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -185,16 +179,12 @@ func (app *appContext) SetUserDisabled(user mediabrowser.User, disabled bool) (e
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (app *appContext) DeleteUser(user mediabrowser.User) (err error, deleted bool) {
|
func (app *appContext) DeleteUser(user mediabrowser.User) (err error, deleted bool) {
|
||||||
var status int
|
|
||||||
if app.ombi != nil {
|
if app.ombi != nil {
|
||||||
var tpUser map[string]any
|
var tpUser map[string]any
|
||||||
tpUser, status, err = app.getOmbiUser(user.ID)
|
tpUser, err = app.getOmbiUser(user.ID)
|
||||||
if status == 200 && err == nil {
|
if err == nil {
|
||||||
if id, ok := tpUser["id"]; ok {
|
if id, ok := tpUser["id"]; ok {
|
||||||
status, err = app.ombi.DeleteUser(id.(string))
|
err = app.ombi.DeleteUser(id.(string))
|
||||||
if status != 200 && err == nil {
|
|
||||||
err = fmt.Errorf("failed (code %d)", status)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedDeleteUser, lm.Ombi, user.ID, err)
|
app.err.Printf(lm.FailedDeleteUser, lm.Ombi, user.ID, err)
|
||||||
}
|
}
|
||||||
@ -211,10 +201,7 @@ func (app *appContext) DeleteUser(user mediabrowser.User) (err error, deleted bo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status, err = app.jf.DeleteUser(user.ID)
|
err = app.jf.DeleteUser(user.ID)
|
||||||
if status != 200 && status != 204 && err == nil {
|
|
||||||
err = fmt.Errorf("failed (code %d)", status)
|
|
||||||
}
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
31
views.go
31
views.go
@ -333,26 +333,25 @@ func (app *appContext) ResetPassword(gc *gin.Context) {
|
|||||||
// data["pin"] = pin
|
// data["pin"] = pin
|
||||||
// }
|
// }
|
||||||
var resp mediabrowser.PasswordResetResponse
|
var resp mediabrowser.PasswordResetResponse
|
||||||
var status int
|
|
||||||
var err error
|
var err error
|
||||||
var username string
|
var username string
|
||||||
if !isInternal && !setPassword {
|
if !isInternal && !setPassword {
|
||||||
resp, status, err = app.jf.ResetPassword(pin)
|
resp, err = app.jf.ResetPassword(pin)
|
||||||
} else if time.Now().After(pwr.Expiry) {
|
} else if time.Now().After(pwr.Expiry) {
|
||||||
app.debug.Printf(lm.FailedChangePassword, lm.Jellyfin, "?", fmt.Sprintf(lm.ExpiredPIN, pin))
|
app.debug.Printf(lm.FailedChangePassword, lm.Jellyfin, "?", fmt.Sprintf(lm.ExpiredPIN, pin))
|
||||||
app.NoRouteHandler(gc)
|
app.NoRouteHandler(gc)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
status, err = app.jf.ResetPasswordAdmin(pwr.ID)
|
err = app.jf.ResetPasswordAdmin(pwr.ID)
|
||||||
if !(status == 200 || status == 204) || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedChangePassword, lm.Jellyfin, "?", err)
|
app.err.Printf(lm.FailedChangePassword, lm.Jellyfin, "?", err)
|
||||||
} else {
|
} else {
|
||||||
status, err = app.jf.SetPassword(pwr.ID, "", pin)
|
err = app.jf.SetPassword(pwr.ID, "", pin)
|
||||||
}
|
}
|
||||||
username = pwr.Username
|
username = pwr.Username
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == 200 || status == 204) && err == nil && (isInternal || resp.Success) {
|
if err == nil && (isInternal || resp.Success) {
|
||||||
data["success"] = true
|
data["success"] = true
|
||||||
data["pin"] = pin
|
data["pin"] = pin
|
||||||
if !isInternal {
|
if !isInternal {
|
||||||
@ -364,8 +363,8 @@ func (app *appContext) ResetPassword(gc *gin.Context) {
|
|||||||
|
|
||||||
// Only log PWRs we know the user for.
|
// Only log PWRs we know the user for.
|
||||||
if username != "" {
|
if username != "" {
|
||||||
jfUser, status, err := app.jf.UserByName(username, false)
|
jfUser, err := app.jf.UserByName(username, false)
|
||||||
if err == nil && status == 200 {
|
if err == nil {
|
||||||
app.storage.SetActivityKey(shortuuid.New(), Activity{
|
app.storage.SetActivityKey(shortuuid.New(), Activity{
|
||||||
Type: ActivityResetPassword,
|
Type: ActivityResetPassword,
|
||||||
UserID: jfUser.ID,
|
UserID: jfUser.ID,
|
||||||
@ -377,19 +376,19 @@ func (app *appContext) ResetPassword(gc *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if app.config.Section("ombi").Key("enabled").MustBool(false) {
|
if app.config.Section("ombi").Key("enabled").MustBool(false) {
|
||||||
jfUser, status, err := app.jf.UserByName(username, false)
|
jfUser, err := app.jf.UserByName(username, false)
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetUser, username, lm.Jellyfin, err)
|
app.err.Printf(lm.FailedGetUser, username, lm.Jellyfin, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ombiUser, status, err := app.getOmbiUser(jfUser.ID)
|
ombiUser, err := app.getOmbiUser(jfUser.ID)
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedGetUser, username, lm.Ombi, err)
|
app.err.Printf(lm.FailedGetUser, username, lm.Ombi, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ombiUser["password"] = pin
|
ombiUser["password"] = pin
|
||||||
status, err = app.ombi.ModifyUser(ombiUser)
|
err = app.ombi.ModifyUser(ombiUser)
|
||||||
if status != 200 || err != nil {
|
if err != nil {
|
||||||
app.err.Printf(lm.FailedChangePassword, lm.Ombi, ombiUser["userName"], err)
|
app.err.Printf(lm.FailedChangePassword, lm.Ombi, ombiUser["userName"], err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -749,8 +748,8 @@ func (app *appContext) InviteProxy(gc *gin.Context) {
|
|||||||
|
|
||||||
fromUser := ""
|
fromUser := ""
|
||||||
if invite.ReferrerJellyfinID != "" {
|
if invite.ReferrerJellyfinID != "" {
|
||||||
sender, status, err := app.jf.UserByID(invite.ReferrerJellyfinID, false)
|
sender, err := app.jf.UserByID(invite.ReferrerJellyfinID, false)
|
||||||
if status == 200 && err == nil {
|
if err == nil {
|
||||||
fromUser = sender.Name
|
fromUser = sender.Name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user