Пример #1
0
func getServiceByOwner(name string, u *auth.User) (service.Service, error) {
	s := service.Service{Name: name}
	err := s.Get()
	if err != nil {
		return s, &errors.HTTP{Code: http.StatusNotFound, Message: "Service not found"}
	}
	if !auth.CheckUserAccess(s.OwnerTeams, u) {
		msg := "This user does not have access to this service"
		return s, &errors.HTTP{Code: http.StatusForbidden, Message: msg}
	}
	return s, err
}
Пример #2
0
func getApp(name string, u *auth.User) (*app.App, error) {
	a, err := app.GetByName(name)
	if err != nil {
		return nil, &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
}
Пример #3
0
func GetServiceInstance(serviceName string, instanceName string, u *auth.User) (*ServiceInstance, error) {
	conn, err := db.Conn()
	if err != nil {
		return nil, err
	}
	defer conn.Close()
	rec.Log(u.Email, "get-service-instance", instanceName)
	var instance ServiceInstance
	err = conn.ServiceInstances().Find(bson.M{"name": instanceName, "service_name": serviceName}).One(&instance)
	if err != nil {
		return nil, ErrServiceInstanceNotFound
	}
	if !auth.CheckUserAccess(instance.Teams, u) {
		return nil, ErrAccessNotAllowed
	}
	return &instance, nil
}
Пример #4
0
func getApp(name string, u *auth.User, r *http.Request) (app.App, error) {
	var err error
	a := context.GetApp(r)
	if a == nil {
		a, err = app.GetByName(name)
		if err != nil {
			return app.App{}, &errors.HTTP{Code: http.StatusNotFound, Message: fmt.Sprintf("App %s not found.", name)}
		}
		context.SetApp(r, a)
	}
	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
}
Пример #5
0
func getServiceAndTeam(serviceName string, teamName string, u *auth.User) (*service.Service, *auth.Team, error) {
	service := &service.Service{Name: serviceName}
	err := service.Get()
	if err != nil {
		return nil, nil, &errors.HTTP{Code: http.StatusNotFound, Message: "Service not found"}
	}
	if !auth.CheckUserAccess(service.Teams, u) {
		msg := "This user does not have access to this service"
		return nil, nil, &errors.HTTP{Code: http.StatusForbidden, Message: msg}
	}
	t := new(auth.Team)
	conn, err := db.Conn()
	if err != nil {
		return nil, nil, err
	}
	err = conn.Teams().Find(bson.M{"_id": teamName}).One(t)
	if err != nil {
		return nil, nil, &errors.HTTP{Code: http.StatusNotFound, Message: "Team not found"}
	}
	return service, t, nil
}
Пример #6
0
func getServiceInstance(serviceName, instanceName, appName string, u *auth.User) (*service.ServiceInstance, *app.App, error) {
	var app app.App
	conn, err := db.Conn()
	if err != nil {
		return nil, nil, err
	}
	defer conn.Close()
	instance, err := getServiceInstanceOrError(serviceName, instanceName, u)
	if err != nil {
		return nil, nil, err
	}
	err = conn.Apps().Find(bson.M{"name": appName}).One(&app)
	if err != nil {
		err = &errors.HTTP{Code: http.StatusNotFound, Message: fmt.Sprintf("App %s not found.", appName)}
		return nil, nil, err
	}
	if !auth.CheckUserAccess(app.Teams, u) {
		err = &errors.HTTP{Code: http.StatusForbidden, Message: "This user does not have access to this app"}
		return nil, nil, err
	}
	return instance, &app, nil
}
Пример #7
0
func removeTeam(w http.ResponseWriter, r *http.Request, t auth.Token) error {
	name := r.URL.Query().Get(":name")
	rec.Log(t.GetUserName(), "remove-team", name)
	user, err := t.User()
	if err != nil {
		return err
	}
	if !user.IsAdmin() && !auth.CheckUserAccess([]string{name}, user) {
		return &errors.HTTP{Code: http.StatusNotFound, Message: fmt.Sprintf(`Team "%s" not found.`, name)}
	}
	err = auth.RemoveTeam(name)
	if err != nil {
		if _, ok := err.(*auth.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 == auth.ErrTeamNotFound {
			return &errors.HTTP{Code: http.StatusNotFound, Message: fmt.Sprintf(`Team "%s" not found.`, name)}
		}
		return err
	}
	return nil
}
Пример #8
0
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)
}