func swap(w http.ResponseWriter, r *http.Request, t auth.Token) error { u, err := t.User() if err != nil { return err } app1Name := r.URL.Query().Get("app1") app2Name := r.URL.Query().Get("app2") locked1, err := app.AcquireApplicationLock(app1Name, t.GetUserName(), "/swap") if err != nil { return err } defer app.ReleaseApplicationLock(app1Name) locked2, err := app.AcquireApplicationLock(app2Name, t.GetUserName(), "/swap") if err != nil { return err } defer app.ReleaseApplicationLock(app2Name) app1, err := getApp(app1Name, u) if err != nil { return err } if !locked1 { return &errors.HTTP{Code: http.StatusConflict, Message: fmt.Sprintf("%s: %s", app1.Name, &app1.Lock)} } app2, err := getApp(app2Name, u) if err != nil { return err } if !locked2 { return &errors.HTTP{Code: http.StatusConflict, Message: fmt.Sprintf("%s: %s", app2.Name, &app2.Lock)} } rec.Log(u.Email, "swap", app1Name, app2Name) return app.Swap(&app1, &app2) }
func swap(w http.ResponseWriter, r *http.Request, t *auth.Token) error { u, err := t.User() if err != nil { return err } app1Name := r.URL.Query().Get("app1") app2Name := r.URL.Query().Get("app2") app1, err := getApp(app1Name, u) if err != nil { return err } app2, err := getApp(app2Name, u) if err != nil { return err } rec.Log(u.Email, "swap", app1Name, app2Name) return app.Swap(&app1, &app2) }
func swap(w http.ResponseWriter, r *http.Request, t auth.Token) error { u, err := t.User() if err != nil { return err } app1Name := r.URL.Query().Get("app1") app2Name := r.URL.Query().Get("app2") forceSwap := r.URL.Query().Get("force") if forceSwap == "" { forceSwap = "false" } locked1, err := app.AcquireApplicationLock(app1Name, t.GetUserName(), "/swap") if err != nil { return err } defer app.ReleaseApplicationLock(app1Name) locked2, err := app.AcquireApplicationLock(app2Name, t.GetUserName(), "/swap") if err != nil { return err } defer app.ReleaseApplicationLock(app2Name) app1, err := getApp(app1Name, u) if err != nil { return err } if !locked1 { return &errors.HTTP{Code: http.StatusConflict, Message: fmt.Sprintf("%s: %s", app1.Name, &app1.Lock)} } app2, err := getApp(app2Name, u) if err != nil { return err } if !locked2 { return &errors.HTTP{Code: http.StatusConflict, Message: fmt.Sprintf("%s: %s", app2.Name, &app2.Lock)} } // compare apps by platform type and number of units if forceSwap == "false" && ((len(app1.Units()) != len(app2.Units())) || (app1.Platform != app2.Platform)) { return app.ErrAppNotEqual } rec.Log(u.Email, "swap", app1Name, app2Name) return app.Swap(&app1, &app2) }
// title: app swap // path: /swap // method: POST // consume: application/x-www-form-urlencoded // responses: // 200: Ok // 400: Invalid data // 401: Unauthorized // 404: App not found // 409: App locked // 412: Number of units or platform don't match func swap(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) { app1Name := r.FormValue("app1") app2Name := r.FormValue("app2") forceSwap := r.FormValue("force") cnameOnly, _ := strconv.ParseBool(r.FormValue("cnameOnly")) if forceSwap == "" { forceSwap = "false" } locked1, err := app.AcquireApplicationLockWait(app1Name, t.GetUserName(), "/swap", lockWaitDuration) if err != nil { return err } defer app.ReleaseApplicationLock(app1Name) locked2, err := app.AcquireApplicationLockWait(app2Name, t.GetUserName(), "/swap", lockWaitDuration) if err != nil { return err } defer app.ReleaseApplicationLock(app2Name) app1, err := getApp(app1Name) if err != nil { return err } if !locked1 { return &errors.HTTP{Code: http.StatusConflict, Message: fmt.Sprintf("%s: %s", app1.Name, &app1.Lock)} } app2, err := getApp(app2Name) if err != nil { return err } if !locked2 { return &errors.HTTP{Code: http.StatusConflict, Message: fmt.Sprintf("%s: %s", app2.Name, &app2.Lock)} } allowed1 := permission.Check(t, permission.PermAppUpdateSwap, contextsForApp(app1)..., ) allowed2 := permission.Check(t, permission.PermAppUpdateSwap, contextsForApp(app2)..., ) if !allowed1 || !allowed2 { return permission.ErrUnauthorized } evt1, err := event.New(&event.Opts{ Target: appTarget(app1Name), Kind: permission.PermAppUpdateSwap, Owner: t, CustomData: event.FormToCustomData(r.Form), Allowed: event.Allowed(permission.PermAppReadEvents, contextsForApp(app1)...), }) if err != nil { return err } evt2, err := event.New(&event.Opts{ Target: appTarget(app2Name), Kind: permission.PermAppUpdateSwap, Owner: t, CustomData: event.FormToCustomData(r.Form), Allowed: event.Allowed(permission.PermAppReadEvents, contextsForApp(app2)...), }) if err != nil { return err } defer func() { evt1.Done(err); evt2.Done(err) }() // compare apps by platform type and number of units if forceSwap == "false" { if app1.Platform != app2.Platform { return &errors.HTTP{ Code: http.StatusPreconditionFailed, Message: "platforms don't match", } } app1Units, err := app1.Units() if err != nil { return err } app2Units, err := app2.Units() if err != nil { return err } if len(app1Units) != len(app2Units) { return &errors.HTTP{ Code: http.StatusPreconditionFailed, Message: "number of units doesn't match", } } } return app.Swap(app1, app2, cnameOnly) }
func swap(w http.ResponseWriter, r *http.Request, t auth.Token) error { u, err := t.User() if err != nil { return err } app1Name := r.URL.Query().Get("app1") app2Name := r.URL.Query().Get("app2") forceSwap := r.URL.Query().Get("force") if forceSwap == "" { forceSwap = "false" } locked1, err := app.AcquireApplicationLockWait(app1Name, t.GetUserName(), "/swap", lockWaitDuration) if err != nil { return err } defer app.ReleaseApplicationLock(app1Name) locked2, err := app.AcquireApplicationLockWait(app2Name, t.GetUserName(), "/swap", lockWaitDuration) if err != nil { return err } defer app.ReleaseApplicationLock(app2Name) app1, err := getApp(app1Name, u) if err != nil { return err } if !locked1 { return &errors.HTTP{Code: http.StatusConflict, Message: fmt.Sprintf("%s: %s", app1.Name, &app1.Lock)} } app2, err := getApp(app2Name, u) if err != nil { return err } if !locked2 { return &errors.HTTP{Code: http.StatusConflict, Message: fmt.Sprintf("%s: %s", app2.Name, &app2.Lock)} } // compare apps by platform type and number of units if forceSwap == "false" { if app1.Platform != app2.Platform { return &errors.HTTP{ Code: http.StatusPreconditionFailed, Message: "platforms don't match", } } app1Units, err := app1.Units() if err != nil { return err } app2Units, err := app2.Units() if err != nil { return err } if len(app1Units) != len(app2Units) { return &errors.HTTP{ Code: http.StatusPreconditionFailed, Message: "number of units doesn't match", } } } rec.Log(u.Email, "swap", "app1="+app1Name, "app2="+app2Name) return app.Swap(app1, app2) }
func swap(w http.ResponseWriter, r *http.Request, t auth.Token) error { getApp := func(name string, u *auth.User, r *http.Request) (app.App, error) { a, err := app.GetByName(name) if err != nil { return app.App{}, &errors.HTTP{Code: http.StatusNotFound, Message: fmt.Sprintf("App %s not found.", name)} } if u == nil || u.IsAdmin() { return *a, nil } if !auth.CheckUserAccess(a.Teams, u) { return *a, &errors.HTTP{Code: http.StatusForbidden, Message: "user does not have access to this app"} } return *a, nil } u, err := t.User() if err != nil { return err } app1Name := r.URL.Query().Get("app1") app2Name := r.URL.Query().Get("app2") forceSwap := r.URL.Query().Get("force") if forceSwap == "" { forceSwap = "false" } locked1, err := app.AcquireApplicationLockWait(app1Name, t.GetUserName(), "/swap", lockWaitDuration) if err != nil { return err } defer app.ReleaseApplicationLock(app1Name) locked2, err := app.AcquireApplicationLockWait(app2Name, t.GetUserName(), "/swap", lockWaitDuration) if err != nil { return err } defer app.ReleaseApplicationLock(app2Name) app1, err := getApp(app1Name, u, r) if err != nil { return err } if !locked1 { return &errors.HTTP{Code: http.StatusConflict, Message: fmt.Sprintf("%s: %s", app1.Name, &app1.Lock)} } app2, err := getApp(app2Name, u, r) if err != nil { return err } if !locked2 { return &errors.HTTP{Code: http.StatusConflict, Message: fmt.Sprintf("%s: %s", app2.Name, &app2.Lock)} } // compare apps by platform type and number of units if forceSwap == "false" { if app1.Platform != app2.Platform { return &errors.HTTP{ Code: http.StatusPreconditionFailed, Message: "platforms don't match", } } if len(app1.Units()) != len(app2.Units()) { return &errors.HTTP{ Code: http.StatusPreconditionFailed, Message: "number of units doesn't match", } } } rec.Log(u.Email, "swap", "app1="+app1Name, "app2="+app2Name) return app.Swap(&app1, &app2) }
func swap(w http.ResponseWriter, r *http.Request, t auth.Token) error { u, err := t.User() if err != nil { return err } app1Name := r.URL.Query().Get("app1") app2Name := r.URL.Query().Get("app2") forceSwap := r.URL.Query().Get("force") cnameOnly, _ := strconv.ParseBool(r.URL.Query().Get("cnameOnly")) if forceSwap == "" { forceSwap = "false" } locked1, err := app.AcquireApplicationLockWait(app1Name, t.GetUserName(), "/swap", lockWaitDuration) if err != nil { return err } defer app.ReleaseApplicationLock(app1Name) locked2, err := app.AcquireApplicationLockWait(app2Name, t.GetUserName(), "/swap", lockWaitDuration) if err != nil { return err } defer app.ReleaseApplicationLock(app2Name) app1, err := getApp(app1Name) if err != nil { return err } if !locked1 { return &errors.HTTP{Code: http.StatusConflict, Message: fmt.Sprintf("%s: %s", app1.Name, &app1.Lock)} } app2, err := getApp(app2Name) if err != nil { return err } if !locked2 { return &errors.HTTP{Code: http.StatusConflict, Message: fmt.Sprintf("%s: %s", app2.Name, &app2.Lock)} } allowed1 := permission.Check(t, permission.PermAppUpdateSwap, append(permission.Contexts(permission.CtxTeam, app1.Teams), permission.Context(permission.CtxApp, app1.Name), permission.Context(permission.CtxPool, app1.Pool), )..., ) allowed2 := permission.Check(t, permission.PermAppUpdateSwap, append(permission.Contexts(permission.CtxTeam, app2.Teams), permission.Context(permission.CtxApp, app2.Name), permission.Context(permission.CtxPool, app2.Pool), )..., ) if !allowed1 || !allowed2 { return permission.ErrUnauthorized } // compare apps by platform type and number of units if forceSwap == "false" { if app1.Platform != app2.Platform { return &errors.HTTP{ Code: http.StatusPreconditionFailed, Message: "platforms don't match", } } app1Units, err := app1.Units() if err != nil { return err } app2Units, err := app2.Units() if err != nil { return err } if len(app1Units) != len(app2Units) { return &errors.HTTP{ Code: http.StatusPreconditionFailed, Message: "number of units doesn't match", } } } rec.Log(u.Email, "swap", "app1="+app1Name, "app2="+app2Name) return app.Swap(app1, app2, cnameOnly) }