func removeTeam(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) {
	ctx := r.Context()
	name := r.URL.Query().Get(":name")
	allowed := permission.Check(t, permission.PermTeamDelete,
		permission.Context(permTypes.CtxTeam, name),
	)
	if !allowed {
		return &errors.HTTP{Code: http.StatusNotFound, Message: fmt.Sprintf(`Team "%s" not found.`, name)}
	}
	evt, err := event.New(&event.Opts{
		Target:     teamTarget(name),
		Kind:       permission.PermTeamDelete,
		Owner:      t,
		CustomData: event.FormToCustomData(InputFields(r)),
		Allowed:    event.Allowed(permission.PermTeamReadEvents, permission.Context(permTypes.CtxTeam, name)),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	err = servicemanager.Team.Remove(ctx, name)
	if err != nil {
		if _, ok := err.(*authTypes.ErrTeamStillUsed); ok {
			msg := fmt.Sprintf("This team cannot be removed because there are still references to it:\n%s", err)
			return &errors.HTTP{Code: http.StatusForbidden, Message: msg}
		}
		if err == authTypes.ErrTeamNotFound {
			return &errors.HTTP{Code: http.StatusNotFound, Message: fmt.Sprintf(`Team "%s" not found.`, name)}
		}
		return err
	}
	return nil
}
title: remove team
path: /teams/{name}
method: DELETE
responses:
200: Team removed
401: Unauthorized
403: Forbidden
404: Not found
package api
import (
	"context"
	"encoding/json"
	"fmt"
	"net/http"
	"reflect"
	"runtime"
	"github.com/tsuru/config"
	"github.com/tsuru/tsuru/app"
	"github.com/tsuru/tsuru/auth"
	"github.com/tsuru/tsuru/errors"
	"github.com/tsuru/tsuru/event"
	"github.com/tsuru/tsuru/log"
	"github.com/tsuru/tsuru/permission"
	"github.com/tsuru/tsuru/provision/pool"
	"github.com/tsuru/tsuru/service"
	"github.com/tsuru/tsuru/servicemanager"
	authTypes "github.com/tsuru/tsuru/types/auth"
	permTypes "github.com/tsuru/tsuru/types/permission"
	"github.com/tsuru/tsuru/volume"
)
const (
	nonManagedSchemeMsg = "Authentication scheme does not allow this operation."
	createDisabledMsg   = "User registration is disabled for non-admin users."
)
var createDisabledErr = &errors.HTTP{Code: http.StatusUnauthorized, Message: createDisabledMsg}
func handleAuthError(err error) error {
	if err == authTypes.ErrUserNotFound {
		return &errors.HTTP{Code: http.StatusNotFound, Message: err.Error()}
	}
	switch err.(type) {
	case *errors.ValidationError:
		return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()}
	case *errors.ConflictError:
		return &errors.HTTP{Code: http.StatusConflict, Message: err.Error()}
	case *errors.NotAuthorizedError:
		return &errors.HTTP{Code: http.StatusForbidden, Message: err.Error()}
	case auth.AuthenticationFailure:
		return &errors.HTTP{Code: http.StatusUnauthorized, Message: err.Error()}
	default:
		return err
	}
}
func userTarget(u string) event.Target {
	return event.Target{Type: event.TargetTypeUser, Value: u}
}
func teamTarget(t string) event.Target {
	return event.Target{Type: event.TargetTypeTeam, Value: t}
}
func createUser(w http.ResponseWriter, r *http.Request) error {
	ctx := r.Context()
	registrationEnabled, _ := config.GetBool("auth:user-registration")
	if !registrationEnabled {
		token := r.Header.Get("Authorization")
		t, err := app.AuthScheme.Auth(ctx, token)
		if err != nil {
			return createDisabledErr
		}
		if !permission.Check(t, permission.PermUserCreate) {
			return createDisabledErr
		}
	}
	email := InputValue(r, "email")
	password := InputValue(r, "password")
	evt, err := event.New(&event.Opts{
		Target:     userTarget(email),
		Kind:       permission.PermUserCreate,
		RawOwner:   event.Owner{Type: event.OwnerTypeUser, Name: email},
		CustomData: event.FormToCustomData(InputFields(r, "password")),
		Allowed:    event.Allowed(permission.PermUserReadEvents, permission.Context(permTypes.CtxUser, email)),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	u := auth.User{
		Email:    email,
		Password: password,
	}
	_, err = app.AuthScheme.Create(ctx, &u)
	if err != nil {
		return handleAuthError(err)
	}
	w.WriteHeader(http.StatusCreated)
	return nil
}
func login(w http.ResponseWriter, r *http.Request) (err error) {
	ctx := r.Context()
	params := map[string]string{
		"email": r.URL.Query().Get(":email"),
	}
	fields := InputFields(r)
	for key, values := range fields {
		params[key] = values[0]
	}
	token, err := app.AuthScheme.Login(ctx, params)
	if err != nil {
		return handleAuthError(err)
	}
	return json.NewEncoder(w).Encode(map[string]string{"token": token.GetValue()})
}
func logout(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) {
	return app.AuthScheme.Logout(r.Context(), t.GetValue())
}
func changePassword(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) {
	ctx := r.Context()
	managed, ok := app.AuthScheme.(auth.ManagedScheme)
	if !ok {
		return &errors.HTTP{Code: http.StatusBadRequest, Message: nonManagedSchemeMsg}
	}
	evt, err := event.New(&event.Opts{
		Target:  userTarget(t.GetUserName()),
		Kind:    permission.PermUserUpdatePassword,
		Owner:   t,
		Allowed: event.Allowed(permission.PermUserReadEvents, permission.Context(permTypes.CtxUser, t.GetUserName())),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	oldPassword := InputValue(r, "old")
	newPassword := InputValue(r, "new")
	confirmPassword := InputValue(r, "confirm")
	if oldPassword == "" || newPassword == "" {
		return &errors.HTTP{
			Code:    http.StatusBadRequest,
			Message: "Both the old and the new passwords are required.",
		}
	}
	if newPassword != confirmPassword {
		return &errors.HTTP{
			Code:    http.StatusBadRequest,
			Message: "New password and password confirmation didn't match.",
		}
	}
	err = managed.ChangePassword(ctx, t, oldPassword, newPassword)
	if err != nil {
		return handleAuthError(err)
	}
	return nil
}
func resetPassword(w http.ResponseWriter, r *http.Request) (err error) {
	ctx := r.Context()
	managed, ok := app.AuthScheme.(auth.ManagedScheme)
	if !ok {
		return &errors.HTTP{Code: http.StatusBadRequest, Message: nonManagedSchemeMsg}
	}
	email := r.URL.Query().Get(":email")
	token := InputValue(r, "token")
	evt, err := event.New(&event.Opts{
		Target:     userTarget(email),
		Kind:       permission.PermUserUpdateReset,
		RawOwner:   event.Owner{Type: event.OwnerTypeUser, Name: email},
		CustomData: event.FormToCustomData(InputFields(r)),
		Allowed:    event.Allowed(permission.PermUserReadEvents, permission.Context(permTypes.CtxUser, email)),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	u, err := auth.GetUserByEmail(email)
	if err != nil {
		if err == authTypes.ErrUserNotFound {
			return &errors.HTTP{Code: http.StatusNotFound, Message: err.Error()}
		}
		return err
	}
	if token == "" {
		return managed.StartPasswordReset(ctx, u)
	}
	return managed.ResetPassword(ctx, u, token)
}
var teamRenameFns = []func(ctx context.Context, oldName, newName string) error{
	app.RenameTeam,
	service.RenameServiceTeam,
	service.RenameServiceInstanceTeam,
	volume.RenameTeam,
	pool.RenamePoolTeam,
}
func updateTeam(w http.ResponseWriter, r *http.Request, t auth.Token) error {
	ctx := r.Context()
	name := r.URL.Query().Get(":name")
	type teamChange struct {
		NewName string
		Tags    []string
	}
	changeRequest := teamChange{}
	if err := ParseInput(r, &changeRequest); err != nil {
		return err
	}
	tags, _ := InputValues(r, "tag")
	changeRequest.Tags = append(changeRequest.Tags, tags...)  
	allowed := permission.Check(t, permission.PermTeamUpdate,
		permission.Context(permTypes.CtxTeam, name),
	)
	if !allowed {
		return permission.ErrUnauthorized
	}
	_, err := servicemanager.Team.FindByName(ctx, name)
	if err != nil {
		if err == authTypes.ErrTeamNotFound {
			return &errors.HTTP{Code: http.StatusNotFound, Message: err.Error()}
		}
		return err
	}
	evt, err := event.New(&event.Opts{
		Target:     teamTarget(name),
		Kind:       permission.PermTeamUpdate,
		Owner:      t,
		CustomData: event.FormToCustomData(InputFields(r)),
		Allowed:    event.Allowed(permission.PermTeamReadEvents, permission.Context(permTypes.CtxTeam, name)),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	if changeRequest.NewName == "" {
		return servicemanager.Team.Update(ctx, name, changeRequest.Tags)
	}
	u, err := t.User()
	if err != nil {
		return err
	}
	err = servicemanager.Team.Create(ctx, changeRequest.NewName, changeRequest.Tags, u)
	if err != nil {
		return err
	}
	var toRollback []func(ctx context.Context, oldName, newName string) error
	defer func() {
		if err == nil {
			return
		}
		rollbackErr := servicemanager.Team.Remove(ctx, changeRequest.NewName)
		if rollbackErr != nil {
			log.Errorf("error rolling back team creation from %v to %v", name, changeRequest.NewName)
		}
		for _, rollbackFn := range toRollback {
			rollbackErr := rollbackFn(ctx, changeRequest.NewName, name)
			if rollbackErr != nil {
				fnName := runtime.FuncForPC(reflect.ValueOf(rollbackFn).Pointer()).Name()
				log.Errorf("error rolling back team name change in %v from %q to %q", fnName, name, changeRequest.NewName)
			}
		}
	}()
	for _, fn := range teamRenameFns {
		err = fn(ctx, name, changeRequest.NewName)
		if err != nil {
			return err
		}
		toRollback = append(toRollback, fn)
	}
	return servicemanager.Team.Remove(ctx, name)
}
func createTeam(w http.ResponseWriter, r *http.Request, t auth.Token) error {
	ctx := r.Context()
	allowed := permission.Check(t, permission.PermTeamCreate)
	if !allowed {
		return permission.ErrUnauthorized
	}
	var team authTypes.Team
	if err := ParseInput(r, &team); err != nil {
		return err
	}
	tags, _ := InputValues(r, "tag")
	team.Tags = append(team.Tags, tags...)  
	evt, err := event.New(&event.Opts{
		Target:     teamTarget(team.Name),
		Kind:       permission.PermTeamCreate,
		Owner:      t,
		CustomData: event.FormToCustomData(InputFields(r)),
		Allowed:    event.Allowed(permission.PermTeamReadEvents, permission.Context(permTypes.CtxTeam, team.Name)),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	u, err := t.User()
	if err != nil {
		return err
	}
	err = servicemanager.Team.Create(ctx, team.Name, team.Tags, u)
	switch err {
	case authTypes.ErrInvalidTeamName:
		return &errors.HTTP{Code: http.StatusBadRequest, Message: err.Error()}
	case authTypes.ErrTeamAlreadyExists:
		return &errors.HTTP{Code: http.StatusConflict, Message: err.Error()}
	}
	if err == nil {
		w.WriteHeader(http.StatusCreated)
	}
	return err
}