2022-03-22 14:58:39 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2024-07-30 15:36:59 +00:00
|
|
|
"net/url"
|
2024-08-03 20:23:59 +00:00
|
|
|
"strings"
|
2022-03-22 14:58:39 +00:00
|
|
|
|
|
|
|
"github.com/gin-gonic/gin"
|
2024-08-06 13:48:31 +00:00
|
|
|
"github.com/hrfee/jfa-go/common"
|
2024-07-31 17:49:52 +00:00
|
|
|
lm "github.com/hrfee/jfa-go/logmessages"
|
2024-08-03 20:23:59 +00:00
|
|
|
"github.com/hrfee/jfa-go/ombi"
|
2023-10-06 13:41:33 +00:00
|
|
|
"github.com/hrfee/mediabrowser"
|
2022-03-22 14:58:39 +00:00
|
|
|
)
|
|
|
|
|
2024-08-06 13:48:31 +00:00
|
|
|
func (app *appContext) getOmbiUser(jfID string) (map[string]interface{}, error) {
|
|
|
|
jfUser, err := app.jf.UserByID(jfID, false)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2022-03-22 14:58:39 +00:00
|
|
|
}
|
|
|
|
username := jfUser.Name
|
|
|
|
email := ""
|
2023-06-20 11:19:24 +00:00
|
|
|
if e, ok := app.storage.GetEmailsKey(jfID); ok {
|
2022-03-22 14:58:39 +00:00
|
|
|
email = e.Addr
|
|
|
|
}
|
2024-08-06 13:48:31 +00:00
|
|
|
user, err := app.ombi.getUser(username, email)
|
|
|
|
return user, err
|
2024-08-03 20:23:59 +00:00
|
|
|
}
|
|
|
|
|
2024-08-06 13:48:31 +00:00
|
|
|
func (ombi *OmbiWrapper) getUser(username string, email string) (map[string]interface{}, error) {
|
|
|
|
ombiUsers, err := ombi.GetUsers()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2024-08-03 20:23:59 +00:00
|
|
|
}
|
2022-03-22 14:58:39 +00:00
|
|
|
for _, ombiUser := range ombiUsers {
|
|
|
|
ombiAddr := ""
|
|
|
|
if a, ok := ombiUser["emailAddress"]; ok && a != nil {
|
|
|
|
ombiAddr = a.(string)
|
|
|
|
}
|
|
|
|
if ombiUser["userName"].(string) == username || (ombiAddr == email && email != "") {
|
2024-08-06 13:48:31 +00:00
|
|
|
return ombiUser, err
|
2022-03-22 14:58:39 +00:00
|
|
|
}
|
|
|
|
}
|
2024-08-06 13:48:31 +00:00
|
|
|
// Gets a generic "not found" type error
|
|
|
|
return nil, common.GenericErr(404, err)
|
2023-10-06 13:41:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Returns a user with the given name who has been imported from Jellyfin/Emby by Ombi
|
2024-08-06 13:48:31 +00:00
|
|
|
func (ombi *OmbiWrapper) getImportedUser(name string) (map[string]interface{}, error) {
|
2023-10-06 13:41:33 +00:00
|
|
|
// Ombi User Types: 3/4 = Emby, 5 = Jellyfin
|
2024-08-06 13:48:31 +00:00
|
|
|
ombiUsers, err := ombi.GetUsers()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
2023-10-06 13:41:33 +00:00
|
|
|
}
|
|
|
|
for _, ombiUser := range ombiUsers {
|
|
|
|
if ombiUser["userName"].(string) == name {
|
|
|
|
uType, ok := ombiUser["userType"].(int)
|
|
|
|
if !ok { // Don't know if Ombi somehow allows duplicate usernames
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
if serverType == mediabrowser.JellyfinServer && uType != 5 { // Jellyfin
|
|
|
|
continue
|
|
|
|
} else if uType != 3 && uType != 4 { // Emby
|
|
|
|
continue
|
|
|
|
}
|
2024-08-06 13:48:31 +00:00
|
|
|
return ombiUser, err
|
2023-10-06 13:41:33 +00:00
|
|
|
}
|
|
|
|
}
|
2024-08-06 13:48:31 +00:00
|
|
|
// Gets a generic "not found" type error
|
|
|
|
return nil, common.GenericErr(404, err)
|
2022-03-22 14:58:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// @Summary Get a list of Ombi users.
|
|
|
|
// @Produce json
|
|
|
|
// @Success 200 {object} ombiUsersDTO
|
|
|
|
// @Failure 500 {object} stringResponse
|
|
|
|
// @Router /ombi/users [get]
|
|
|
|
// @Security Bearer
|
|
|
|
// @tags Ombi
|
|
|
|
func (app *appContext) OmbiUsers(gc *gin.Context) {
|
2024-08-06 13:48:31 +00:00
|
|
|
users, err := app.ombi.GetUsers()
|
|
|
|
if err != nil {
|
2024-07-31 17:49:52 +00:00
|
|
|
app.err.Printf(lm.FailedGetUsers, lm.Ombi, err)
|
2022-03-22 14:58:39 +00:00
|
|
|
respond(500, "Couldn't get users", gc)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
userlist := make([]ombiUser, len(users))
|
|
|
|
for i, data := range users {
|
|
|
|
userlist[i] = ombiUser{
|
|
|
|
Name: data["userName"].(string),
|
|
|
|
ID: data["id"].(string),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
gc.JSON(200, ombiUsersDTO{Users: userlist})
|
|
|
|
}
|
|
|
|
|
|
|
|
// @Summary Store Ombi user template in an existing profile.
|
|
|
|
// @Produce json
|
|
|
|
// @Param ombiUser body ombiUser true "User to source settings from"
|
|
|
|
// @Param profile path string true "Name of profile to store in"
|
|
|
|
// @Success 200 {object} boolResponse
|
|
|
|
// @Failure 400 {object} boolResponse
|
|
|
|
// @Failure 500 {object} stringResponse
|
|
|
|
// @Router /profiles/ombi/{profile} [post]
|
|
|
|
// @Security Bearer
|
|
|
|
// @tags Ombi
|
|
|
|
func (app *appContext) SetOmbiProfile(gc *gin.Context) {
|
|
|
|
var req ombiUser
|
|
|
|
gc.BindJSON(&req)
|
2024-07-30 15:36:59 +00:00
|
|
|
escapedProfileName := gc.Param("profile")
|
|
|
|
profileName, _ := url.QueryUnescape(escapedProfileName)
|
2023-06-24 20:29:16 +00:00
|
|
|
profile, ok := app.storage.GetProfileKey(profileName)
|
2022-03-22 14:58:39 +00:00
|
|
|
if !ok {
|
|
|
|
respondBool(400, false, gc)
|
|
|
|
return
|
|
|
|
}
|
2024-08-06 13:48:31 +00:00
|
|
|
template, err := app.ombi.TemplateByID(req.ID)
|
|
|
|
if err != nil || len(template) == 0 {
|
2024-07-31 17:49:52 +00:00
|
|
|
app.err.Printf(lm.FailedGetUsers, lm.Ombi, err)
|
2022-03-22 14:58:39 +00:00
|
|
|
respond(500, "Couldn't get user", gc)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
profile.Ombi = template
|
2023-06-24 20:29:16 +00:00
|
|
|
app.storage.SetProfileKey(profileName, profile)
|
2022-03-22 14:58:39 +00:00
|
|
|
respondBool(204, true, gc)
|
|
|
|
}
|
|
|
|
|
|
|
|
// @Summary Remove ombi user template from a profile.
|
|
|
|
// @Produce json
|
|
|
|
// @Param profile path string true "Name of profile to store in"
|
|
|
|
// @Success 200 {object} boolResponse
|
|
|
|
// @Failure 400 {object} boolResponse
|
|
|
|
// @Failure 500 {object} stringResponse
|
|
|
|
// @Router /profiles/ombi/{profile} [delete]
|
|
|
|
// @Security Bearer
|
|
|
|
// @tags Ombi
|
|
|
|
func (app *appContext) DeleteOmbiProfile(gc *gin.Context) {
|
2024-07-30 15:36:59 +00:00
|
|
|
escapedProfileName := gc.Param("profile")
|
|
|
|
profileName, _ := url.QueryUnescape(escapedProfileName)
|
2023-06-24 20:29:16 +00:00
|
|
|
profile, ok := app.storage.GetProfileKey(profileName)
|
2022-03-22 14:58:39 +00:00
|
|
|
if !ok {
|
|
|
|
respondBool(400, false, gc)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
profile.Ombi = nil
|
2023-06-24 20:29:16 +00:00
|
|
|
app.storage.SetProfileKey(profileName, profile)
|
2022-03-22 14:58:39 +00:00
|
|
|
respondBool(204, true, gc)
|
|
|
|
}
|
2023-10-09 09:39:22 +00:00
|
|
|
|
2024-08-03 20:23:59 +00:00
|
|
|
type OmbiWrapper struct {
|
|
|
|
*ombi.Ombi
|
|
|
|
}
|
|
|
|
|
2024-08-06 13:48:31 +00:00
|
|
|
func (ombi *OmbiWrapper) applyProfile(user map[string]interface{}, profile map[string]interface{}) (err error) {
|
2023-10-09 09:39:22 +00:00
|
|
|
for k, v := range profile {
|
|
|
|
switch v.(type) {
|
|
|
|
case map[string]interface{}, []interface{}:
|
|
|
|
user[k] = v
|
|
|
|
default:
|
|
|
|
if v != user[k] {
|
|
|
|
user[k] = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-08-06 13:48:31 +00:00
|
|
|
err = ombi.ModifyUser(user)
|
2024-08-03 20:23:59 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ombi *OmbiWrapper) ImportUser(jellyfinID string, req newUserDTO, profile Profile) (err error, ok bool) {
|
2024-08-06 13:48:31 +00:00
|
|
|
errors, err := ombi.NewUser(req.Username, req.Password, req.Email, profile.Ombi)
|
2024-08-03 20:23:59 +00:00
|
|
|
var ombiUser map[string]interface{}
|
2024-08-06 13:48:31 +00:00
|
|
|
if err != nil {
|
2024-08-03 20:23:59 +00:00
|
|
|
// Check if on the off chance, Ombi's user importer has already added the account.
|
2024-08-06 13:48:31 +00:00
|
|
|
ombiUser, err = ombi.getImportedUser(req.Username)
|
|
|
|
if err == nil {
|
2024-08-03 20:23:59 +00:00
|
|
|
// app.info.Println(lm.Ombi + " " + lm.UserExists)
|
|
|
|
profile.Ombi["password"] = req.Password
|
2024-08-06 13:48:31 +00:00
|
|
|
err = ombi.applyProfile(ombiUser, profile.Ombi)
|
|
|
|
if err != nil {
|
2024-08-03 20:23:59 +00:00
|
|
|
err = fmt.Errorf(lm.FailedApplyProfile, lm.Ombi, req.Username, err)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if len(errors) != 0 {
|
|
|
|
err = fmt.Errorf("%v, %s", err, strings.Join(errors, ", "))
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ok = true
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ombi *OmbiWrapper) AddContactMethods(jellyfinID string, req newUserDTO, discord *DiscordUser, telegram *TelegramUser) (err error) {
|
|
|
|
var ombiUser map[string]interface{}
|
2024-08-06 13:48:31 +00:00
|
|
|
ombiUser, err = ombi.getUser(req.Username, req.Email)
|
|
|
|
if err != nil {
|
2024-08-03 20:23:59 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
if discordEnabled || telegramEnabled {
|
|
|
|
dID := ""
|
|
|
|
tUser := ""
|
|
|
|
if discord != nil {
|
|
|
|
dID = discord.ID
|
|
|
|
}
|
|
|
|
if telegram != nil {
|
|
|
|
tUser = telegram.Username
|
|
|
|
}
|
|
|
|
var resp string
|
2024-08-06 13:48:31 +00:00
|
|
|
resp, err = ombi.SetNotificationPrefs(ombiUser, dID, tUser)
|
|
|
|
if err != nil {
|
2024-08-03 20:23:59 +00:00
|
|
|
if resp != "" {
|
|
|
|
err = fmt.Errorf("%v, %s", err, resp)
|
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
2023-10-09 09:39:22 +00:00
|
|
|
return
|
|
|
|
}
|
2024-08-03 20:23:59 +00:00
|
|
|
|
|
|
|
func (ombi *OmbiWrapper) Name() string { return lm.Ombi }
|
|
|
|
|
|
|
|
func (ombi *OmbiWrapper) Enabled(app *appContext, profile *Profile) bool {
|
|
|
|
return profile != nil && profile.Ombi != nil && len(profile.Ombi) != 0 && app.config.Section("ombi").Key("enabled").MustBool(false)
|
|
|
|
}
|