From 95c9f4f42d79e2685b8fe8cbf90807af4d44579f Mon Sep 17 00:00:00 2001 From: Harvey Tindall Date: Fri, 30 Oct 2020 21:13:13 +0000 Subject: [PATCH] Apply email addres changes to ombi for #11. --- api.go | 68 ++++++++++++++++++++++++++++++++++----------------------- ombi.go | 42 ++++++++++++++++++++++++++++++----- 2 files changed, 77 insertions(+), 33 deletions(-) diff --git a/api.go b/api.go index ef6dd8b..2e20b2e 100644 --- a/api.go +++ b/api.go @@ -194,6 +194,29 @@ func (app *appContext) checkInvite(code string, used bool, username string) bool return false } +func (app *appContext) getOmbiUser(jfID string) (map[string]interface{}, int, error) { + ombiUsers, code, err := app.ombi.getUsers() + if err != nil || code != 200 { + return nil, code, err + } + jfUser, code, err := app.jf.userById(jfID, false) + if err != nil || code != 200 { + return nil, code, err + } + username := jfUser["Name"].(string) + email := app.storage.emails[jfID].(string) + for _, ombiUser := range ombiUsers { + ombiAddr := "" + if a, ok := ombiUser["emailAddress"]; ok && a != nil { + ombiAddr = a.(string) + } + if ombiUser["userName"].(string) == username || (ombiAddr == email && email != "") { + return ombiUser, code, err + } + } + return nil, 400, fmt.Errorf("Couldn't find user") +} + // Routes from now on! // @Summary Creates a new Jellyfin user without an invite. @@ -386,31 +409,12 @@ func (app *appContext) DeleteUser(gc *gin.Context) { gc.BindJSON(&req) errors := map[string]string{} ombiEnabled := app.config.Section("ombi").Key("enabled").MustBool(false) - ombiUsers := []map[string]interface{}{} - var code int - var err error - if ombiEnabled { - ombiUsers, code, err = app.ombi.getUsers() - if code != 200 || err != nil { - respond(500, fmt.Sprintf("Couldn't get users: %s (%s)", code, err), gc) - return - } - } for _, userID := range req.Users { if ombiEnabled { - ombiID := "" - user, status, err := app.jf.userById(userID, false) - if err == nil && status == 200 { - username := user["Name"].(string) - email := app.storage.emails[userID].(string) - for _, ombiUser := range ombiUsers { - if ombiUser["userName"].(string) == username || (ombiUser["emailAddress"].(string) == email && email != "") { - ombiID = ombiUser["id"].(string) - break - } - } - if ombiID != "" { - status, err := app.ombi.deleteUser(ombiID) + ombiUser, code, err := app.getOmbiUser(userID) + if code == 200 && err == nil { + if id, ok := ombiUser["id"]; ok { + status, err := app.ombi.deleteUser(id.(string)) if err != nil || status != 200 { app.err.Printf("Failed to delete ombi user: %d %s", status, err) errors[userID] = fmt.Sprintf("Ombi: %d %s, ", status, err) @@ -605,7 +609,7 @@ func (app *appContext) SetDefaultProfile(gc *gin.Context) { // @Security ApiKeyBlankPassword // @tags Profiles & Settings func (app *appContext) CreateProfile(gc *gin.Context) { - fmt.Println("Profile creation requested") + app.info.Println("Profile creation requested") var req newProfileDTO gc.BindJSON(&req) user, status, err := app.jf.userById(req.ID, false) @@ -910,7 +914,6 @@ func (app *appContext) SetOmbiDefaults(gc *gin.Context) { return } app.storage.ombi_template = template - fmt.Println(app.storage.ombi_path) app.storage.storeOmbiTemplate() respondBool(200, true, gc) } @@ -926,7 +929,6 @@ func (app *appContext) SetOmbiDefaults(gc *gin.Context) { func (app *appContext) ModifyEmails(gc *gin.Context) { var req modifyEmailsDTO gc.BindJSON(&req) - fmt.Println(req) app.debug.Println("Email modification requested") users, status, err := app.jf.getUsers(false) if !(status == 200 || status == 204) || err != nil { @@ -935,9 +937,21 @@ func (app *appContext) ModifyEmails(gc *gin.Context) { respond(500, "Couldn't get users", gc) return } + ombiEnabled := app.config.Section("ombi").Key("enabled").MustBool(false) for _, jfUser := range users { - if address, ok := req[jfUser["Id"].(string)]; ok { + id := jfUser["Id"].(string) + if address, ok := req[id]; ok { app.storage.emails[jfUser["Id"].(string)] = address + if ombiEnabled { + ombiUser, code, err := app.getOmbiUser(id) + if code == 200 && err == nil { + ombiUser["emailAddress"] = address + code, err = app.ombi.modifyUser(ombiUser) + if code != 200 || err != nil { + app.err.Printf("%s: Failed to change ombi email address: %d %s", ombiUser["userName"].(string), code, err) + } + } + } } } app.storage.storeEmails() diff --git a/ombi.go b/ombi.go index 2bd9969..c5b80b3 100644 --- a/ombi.go +++ b/ombi.go @@ -16,6 +16,9 @@ type Ombi struct { header map[string]string httpClient *http.Client noFail bool + userCache []map[string]interface{} + cacheExpiry time.Time + cacheLength int } func newOmbi(server, key string, noFail bool) *Ombi { @@ -29,6 +32,8 @@ func newOmbi(server, key string, noFail bool) *Ombi { header: map[string]string{ "ApiKey": key, }, + cacheLength: 30, + cacheExpiry: time.Now(), } } @@ -72,10 +77,10 @@ func (ombi *Ombi) _getJSON(url string, params map[string]string) (string, int, e } // does a POST and optionally returns response as string. Returns a string instead of an io.reader bcs i couldn't get it working otherwise. -func (ombi *Ombi) _post(url string, data map[string]interface{}, response bool) (string, int, error) { +func (ombi *Ombi) _send(mode string, url string, data map[string]interface{}, response bool) (string, int, error) { responseText := "" params, _ := json.Marshal(data) - req, _ := http.NewRequest("POST", url, bytes.NewBuffer(params)) + req, _ := http.NewRequest(mode, url, bytes.NewBuffer(params)) req.Header.Add("Content-Type", "application/json") for name, value := range ombi.header { req.Header.Add(name, value) @@ -107,6 +112,23 @@ func (ombi *Ombi) _post(url string, data map[string]interface{}, response bool) return responseText, resp.StatusCode, nil } +func (ombi *Ombi) _post(url string, data map[string]interface{}, response bool) (string, int, error) { + return ombi._send("POST", url, data, response) +} + +func (ombi *Ombi) _put(url string, data map[string]interface{}, response bool) (string, int, error) { + return ombi._send("PUT", url, data, response) +} + +func (ombi *Ombi) modifyUser(user map[string]interface{}) (status int, err error) { + if _, ok := user["id"]; !ok { + err = fmt.Errorf("No ID provided") + return + } + _, status, err = ombi._put(ombi.server+"/api/v1/Identity", user, false) + return +} + func (ombi *Ombi) deleteUser(id string) (code int, err error) { url := fmt.Sprintf("%s/api/v1/Identity/%s", ombi.server, id) req, _ := http.NewRequest("DELETE", url, nil) @@ -127,10 +149,18 @@ func (ombi *Ombi) userByID(id string) (result map[string]interface{}, code int, } // gets a list of all users. -func (ombi *Ombi) getUsers() (result []map[string]interface{}, code int, err error) { - resp, code, err := ombi._getJSON(fmt.Sprintf("%s/api/v1/Identity/Users", ombi.server), nil) - json.Unmarshal([]byte(resp), &result) - return +func (ombi *Ombi) getUsers() ([]map[string]interface{}, int, error) { + if time.Now().After(ombi.cacheExpiry) { + resp, code, err := ombi._getJSON(fmt.Sprintf("%s/api/v1/Identity/Users", ombi.server), nil) + var result []map[string]interface{} + json.Unmarshal([]byte(resp), &result) + ombi.userCache = result + if (code == 200 || code == 204) && err == nil { + ombi.cacheExpiry = time.Now().Add(time.Minute * time.Duration(ombi.cacheLength)) + } + return result, code, err + } + return ombi.userCache, 200, nil } // Strip these from a user when saving as a template.