func removeKeyFromGandalf(key *auth.Key, u *auth.User) error { gURL := repository.ServerURL() if err := (&gandalf.Client{Endpoint: gURL}).RemoveKey(u.Email, key.Name); err != nil { return fmt.Errorf("Failed to remove the key from git server: %s", err) } return nil }
func createUser(w http.ResponseWriter, r *http.Request) error { var u auth.User err := json.NewDecoder(r.Body).Decode(&u) if err != nil { return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()} } if !validation.ValidateEmail(u.Email) { return &errors.HTTP{Code: http.StatusBadRequest, Message: emailError} } if !validation.ValidateLength(u.Password, passwordMinLen, passwordMaxLen) { return &errors.HTTP{Code: http.StatusBadRequest, Message: passwordError} } gURL := repository.ServerURL() c := gandalf.Client{Endpoint: gURL} if _, err := c.NewUser(u.Email, keyToMap(u.Keys)); err != nil { return fmt.Errorf("Failed to create user in the git server: %s", err) } if err := u.Create(); err == nil { rec.Log(u.Email, "create-user") if limit, err := config.GetUint("quota:apps-per-user"); err == nil { quota.Create(u.Email, uint(limit)) } w.WriteHeader(http.StatusCreated) return nil } if _, err = auth.GetUserByEmail(u.Email); err == nil { err = &errors.HTTP{Code: http.StatusConflict, Message: "This email is already registered"} } return err }
func removeUserFromTeamInGandalf(u *auth.User, team *auth.Team) error { gURL := repository.ServerURL() teamApps, err := team.AllowedApps() if err != nil { return err } userApps, err := u.AllowedApps() if err != nil { return err } appsToRemove := make([]string, 0, len(teamApps)) for _, teamApp := range teamApps { found := false for _, userApp := range userApps { if userApp == teamApp { found = true break } } if !found { appsToRemove = append(appsToRemove, teamApp) } } client := gandalf.Client{Endpoint: gURL} if err := client.RevokeAccess(appsToRemove, []string{u.Email}); err != nil { return fmt.Errorf("Failed to revoke access from git repositories: %s", err) } return nil }
func addKeyInGandalf(key *auth.Key, u *auth.User) error { key.Name = fmt.Sprintf("%s-%d", u.Email, len(u.Keys)+1) gURL := repository.ServerURL() if err := (&gandalf.Client{Endpoint: gURL}).AddKey(u.Email, keyToMap([]auth.Key{*key})); err != nil { return fmt.Errorf("Failed to add key to git server: %s", err) } return nil }
func removeUserFromTeamInGandalf(u *auth.User, team string) error { gURL := repository.ServerURL() alwdApps, err := u.AllowedAppsByTeam(team) if err != nil { return err } if err := (&gandalf.Client{Endpoint: gURL}).RevokeAccess(alwdApps, []string{u.Email}); err != nil { return fmt.Errorf("Failed to revoke access from git repositories: %s", err) } return nil }
func addUserToTeamInGandalf(email string, u *auth.User, t *auth.Team) error { gURL := repository.ServerURL() alwdApps, err := u.AllowedApps() if err != nil { return fmt.Errorf("Failed to obtain allowed apps to grant: %s", err.Error()) } if err := (&gandalf.Client{Endpoint: gURL}).GrantAccess(alwdApps, []string{email}); err != nil { return fmt.Errorf("Failed to grant access to git repositories: %s", err) } return nil }
// removeUser removes the user from the database and from gandalf server // // If the user is the only one in a team an error will be returned. func removeUser(w http.ResponseWriter, r *http.Request, t *auth.Token) error { u, err := t.User() if err != nil { return err } gURL := repository.ServerURL() c := gandalf.Client{Endpoint: gURL} alwdApps, err := u.AllowedApps() if err != nil { return err } if err := c.RevokeAccess(alwdApps, []string{u.Email}); err != nil { log.Printf("Failed to revoke access in Gandalf: %s", err) return fmt.Errorf("Failed to revoke acess from git repositories: %s", err) } teams, err := u.Teams() if err != nil { return err } conn, err := db.Conn() if err != nil { return err } defer conn.Close() for _, team := range teams { if len(team.Users) < 2 { msg := fmt.Sprintf(`This user is the last member of the team "%s", so it cannot be removed. Please remove the team, them remove the user.`, team.Name) return &errors.HTTP{Code: http.StatusForbidden, Message: msg} } err = team.RemoveUser(u) if err != nil { return err } // this can be done without the loop err = conn.Teams().Update(bson.M{"_id": team.Name}, team) if err != nil { return err } } rec.Log(u.Email, "remove-user") if err := c.RemoveUser(u.Email); err != nil { log.Printf("Failed to remove user from gandalf: %s", err) return fmt.Errorf("Failed to remove the user from the git server: %s", err) } quota.Delete(u.Email) return conn.Users().Remove(bson.M{"email": u.Email}) }
func revokeAppAccess(w http.ResponseWriter, r *http.Request, t *auth.Token) error { u, err := t.User() if err != nil { return err } appName := r.URL.Query().Get(":app") teamName := r.URL.Query().Get(":team") rec.Log(u.Email, "revoke-app-access", "app="+appName, "team="+teamName) team := new(auth.Team) app, err := getApp(appName, u) if err != nil { return err } conn, err := db.Conn() if err != nil { return err } defer conn.Close() err = conn.Teams().Find(bson.M{"_id": teamName}).One(team) if err != nil { return &errors.HTTP{Code: http.StatusNotFound, Message: "Team not found"} } if len(app.Teams) == 1 { msg := "You can not revoke the access from this team, because it is the unique team with access to the app, and an app can not be orphaned" return &errors.HTTP{Code: http.StatusForbidden, Message: msg} } err = app.Revoke(team) if err != nil { return &errors.HTTP{Code: http.StatusNotFound, Message: err.Error()} } err = conn.Apps().Update(bson.M{"name": app.Name}, app) if err != nil { return err } users := getEmailsForRevoking(&app, team) if len(users) > 0 { gURL := repository.ServerURL() if err := (&gandalf.Client{Endpoint: gURL}).RevokeAccess([]string{app.Name}, users); err != nil { return fmt.Errorf("Failed to revoke access in the git server: %s", err) } } return nil }
// Delete deletes an app. // // Delete an app is a process composed of four steps: // // 1. Destroy the bucket and S3 credentials (if bucket-support is // enabled). // 2. Destroy the app unit using juju // 3. Unbind all service instances from the app // 4. Remove the app from the database func Delete(app *App) error { gURL := repository.ServerURL() (&gandalf.Client{Endpoint: gURL}).RemoveRepository(app.Name) useS3, _ := config.GetBool("bucket-support") if useS3 { destroyBucket(app) } if len(app.Units) > 0 { Provisioner.Destroy(app) app.unbind() } token := app.Env["TSURU_APP_TOKEN"].Value auth.DeleteToken(token) quota.Release(app.Owner, app.Name) conn, err := db.Conn() if err != nil { return err } defer conn.Close() quota.Delete(app.Name) return conn.Apps().Remove(bson.M{"name": app.Name}) }
func grantAppAccess(w http.ResponseWriter, r *http.Request, t *auth.Token) error { u, err := t.User() if err != nil { return err } appName := r.URL.Query().Get(":app") teamName := r.URL.Query().Get(":team") rec.Log(u.Email, "grant-app-access", "app="+appName, "team="+teamName) team := new(auth.Team) app, err := getApp(appName, u) if err != nil { return err } conn, err := db.Conn() if err != nil { return err } defer conn.Close() err = conn.Teams().Find(bson.M{"_id": teamName}).One(team) if err != nil { return &errors.HTTP{Code: http.StatusNotFound, Message: "Team not found"} } err = app.Grant(team) if err != nil { return &errors.HTTP{Code: http.StatusConflict, Message: err.Error()} } err = conn.Apps().Update(bson.M{"name": app.Name}, app) if err != nil { return err } gURL := repository.ServerURL() gClient := gandalf.Client{Endpoint: gURL} if err := gClient.GrantAccess([]string{app.Name}, team.Users); err != nil { return fmt.Errorf("Failed to grant access in the git server: %s.", err) } return nil }
func (u *User) ListKeys() (map[string]string, error) { gURL := repository.ServerURL() c := gandalf.Client{Endpoint: gURL} return c.ListKeys(u.Email) }
} // createRepository creates a repository for the app in Gandalf. var createRepository = action.Action{ Name: "create-repository", Forward: func(ctx action.FWContext) (action.Result, error) { var app App switch ctx.Params[0].(type) { case App: app = ctx.Params[0].(App) case *App: app = *ctx.Params[0].(*App) default: return nil, errors.New("First parameter must be App or *App.") } gURL := repository.ServerURL() var users []string for _, t := range app.GetTeams() { users = append(users, t.Users...) } c := gandalf.Client{Endpoint: gURL} _, err := c.NewRepository(app.Name, users, false) return &app, err }, Backward: func(ctx action.BWContext) { app := ctx.FWResult.(*App) app.Get() gURL := repository.ServerURL() c := gandalf.Client{Endpoint: gURL} c.RemoveRepository(app.Name) },
MinParams: 1, } // createRepository creates a repository for the app in Gandalf. var createRepository = action.Action{ Forward: func(ctx action.FWContext) (action.Result, error) { var app App switch ctx.Params[0].(type) { case App: app = ctx.Params[0].(App) case *App: app = *ctx.Params[0].(*App) default: return nil, errors.New("First parameter must be App or *App.") } gUrl := repository.ServerURL() var users []string for _, t := range app.GetTeams() { users = append(users, t.Users...) } c := gandalf.Client{Endpoint: gUrl} _, err := c.NewRepository(app.Name, users, false) return &app, err }, Backward: func(ctx action.BWContext) { app := ctx.FWResult.(*App) app.Get() gUrl := repository.ServerURL() c := gandalf.Client{Endpoint: gUrl} c.RemoveRepository(app.Name) },