Exemple #1
0
func canUseRole(t auth.Token, roleName, contextValue string) error {
	role, err := permission.FindRole(roleName)
	if err != nil {
		if err == permission.ErrRoleNotFound {
			return &errors.HTTP{
				Code:    http.StatusNotFound,
				Message: err.Error(),
			}
		}
		return err
	}
	userPerms, err := t.Permissions()
	if err != nil {
		return err
	}
	perms := role.PermissionsFor(contextValue)
	for _, p := range perms {
		if !permission.CheckFromPermList(userPerms, p.Scheme, p.Context) {
			return &errors.HTTP{
				Code:    http.StatusForbidden,
				Message: fmt.Sprintf("User not authorized to use permission %s", p.String()),
			}
		}
	}
	return nil
}
Exemple #2
0
func createApiUser(perms []permission.Permission, user *auth.User, roleMap map[string]*permission.Role, includeAll bool) (*apiUser, error) {
	var permData []rolePermissionData
	roleData := make([]rolePermissionData, 0, len(user.Roles))
	if roleMap == nil {
		roleMap = make(map[string]*permission.Role)
	}
	allGlobal := true
	for _, userRole := range user.Roles {
		role := roleMap[userRole.Name]
		if role == nil {
			r, err := permission.FindRole(userRole.Name)
			if err != nil {
				return nil, err
			}
			role = &r
			roleMap[userRole.Name] = role
		}
		allPermsMatch := true
		permissions := role.PermissionsFor(userRole.ContextValue)
		if len(permissions) == 0 && !includeAll {
			continue
		}
		rolePerms := make([]rolePermissionData, len(permissions))
		for i, p := range permissions {
			if perms != nil && allPermsMatch && !permission.CheckFromPermList(perms, p.Scheme, p.Context) {
				allPermsMatch = false
				break
			}
			rolePerms[i] = rolePermissionData{
				Name:         p.Scheme.FullName(),
				ContextType:  string(p.Context.CtxType),
				ContextValue: p.Context.Value,
			}
		}
		if !allPermsMatch {
			continue
		}
		roleData = append(roleData, rolePermissionData{
			Name:         userRole.Name,
			ContextType:  string(role.ContextType),
			ContextValue: userRole.ContextValue,
		})
		permData = append(permData, rolePerms...)
		if role.ContextType != permission.CtxGlobal {
			allGlobal = false
		}
	}
	if len(roleData) == 0 || (!includeAll && allGlobal) {
		return nil, nil
	}
	return &apiUser{
		Email:       user.Email,
		Roles:       roleData,
		Permissions: permData,
	}, nil
}
Exemple #3
0
// Revoke removes the access from a team. It returns an error if the team do
// not have access to the app.
func (app *App) Revoke(team *auth.Team) error {
	if len(app.Teams) == 1 {
		return ErrCannotOrphanApp
	}
	index, found := app.findTeam(team)
	if !found {
		return ErrNoAccess
	}
	last := len(app.Teams) - 1
	app.Teams[index] = app.Teams[last]
	app.Teams = app.Teams[:last]
	conn, err := db.Conn()
	if err != nil {
		return err
	}
	defer conn.Close()
	err = conn.Apps().Update(bson.M{"name": app.Name}, bson.M{"$pull": bson.M{"teams": team.Name}})
	if err != nil {
		return err
	}
	users, err := auth.ListUsersWithPermissions(permission.Permission{
		Scheme:  permission.PermAppDeploy,
		Context: permission.Context(permission.CtxTeam, team.Name),
	})
	if err != nil {
		conn.Apps().Update(bson.M{"name": app.Name}, bson.M{"$addToSet": bson.M{"teams": team.Name}})
		return err
	}
	for _, user := range users {
		perms, err := user.Permissions()
		if err != nil {
			conn.Apps().Update(bson.M{"name": app.Name}, bson.M{"$addToSet": bson.M{"teams": team.Name}})
			return err
		}
		canDeploy := permission.CheckFromPermList(perms, permission.PermAppDeploy,
			append(permission.Contexts(permission.CtxTeam, app.Teams),
				permission.Context(permission.CtxApp, app.Name),
				permission.Context(permission.CtxPool, app.Pool),
			)...,
		)
		if canDeploy {
			continue
		}
		err = repository.Manager().RevokeAccess(app.Name, user.Email)
		if err != nil {
			conn.Apps().Update(bson.M{"name": app.Name}, bson.M{"$addToSet": bson.M{"teams": team.Name}})
			return err
		}
	}
	return nil
}
Exemple #4
0
func teamList(w http.ResponseWriter, r *http.Request, t auth.Token) error {
	rec.Log(t.GetUserName(), "list-teams")
	permsForTeam := permission.PermissionRegistry.PermissionsWithContextType(permission.CtxTeam)
	teams, err := auth.ListTeams()
	if err != nil {
		return err
	}
	teamsMap := map[string][]string{}
	perms, err := t.Permissions()
	if err != nil {
		return err
	}
	for _, team := range teams {
		teamCtx := permission.Context(permission.CtxTeam, team.Name)
		var parent *permission.PermissionScheme
		for _, p := range permsForTeam {
			if parent != nil && parent.IsParent(p) {
				continue
			}
			if permission.CheckFromPermList(perms, p, teamCtx) {
				parent = p
				teamsMap[team.Name] = append(teamsMap[team.Name], p.FullName())
			}
		}
	}
	if len(teamsMap) == 0 {
		w.WriteHeader(http.StatusNoContent)
		return nil
	}
	var result []map[string]interface{}
	for name, permissions := range teamsMap {
		result = append(result, map[string]interface{}{
			"name":        name,
			"permissions": permissions,
		})
	}
	w.Header().Set("Content-Type", "application/json")
	b, err := json.Marshal(result)
	if err != nil {
		return err
	}
	n, err := w.Write(b)
	if err != nil {
		return err
	}
	if n != len(b) {
		return &errors.HTTP{Code: http.StatusInternalServerError, Message: "Failed to write response body."}
	}
	return nil
}
Exemple #5
0
func ListUsersWithPermissions(wantedPerms ...permission.Permission) ([]User, error) {
	allUsers, err := ListUsers()
	if err != nil {
		return nil, err
	}
	var filteredUsers []User
	// TODO(cezarsa): Too slow! Think about faster implementation in the future.
usersLoop:
	for _, u := range allUsers {
		perms, err := u.Permissions()
		if err != nil {
			return nil, err
		}
		for _, p := range wantedPerms {
			if permission.CheckFromPermList(perms, p.Scheme, p.Context) {
				filteredUsers = append(filteredUsers, u)
				continue usersLoop
			}
		}
	}
	return filteredUsers, nil
}
Exemple #6
0
func createApiUser(perms []permission.Permission, user *auth.User, roleMap map[string]*permission.Role) (*apiUser, error) {
	permData := make([]rolePermissionData, 0, len(user.Roles))
	roleData := make([]rolePermissionData, len(user.Roles))
	if roleMap == nil {
		roleMap = make(map[string]*permission.Role)
	}
	for i, userRole := range user.Roles {
		role := roleMap[userRole.Name]
		if role == nil {
			r, err := permission.FindRole(userRole.Name)
			if err != nil {
				return nil, err
			}
			role = &r
			roleMap[userRole.Name] = role
		}
		roleData[i] = rolePermissionData{
			Name:         userRole.Name,
			ContextType:  string(role.ContextType),
			ContextValue: userRole.ContextValue,
		}
		permissions := role.PermissionsFor(userRole.ContextValue)
		for _, p := range permissions {
			if !permission.CheckFromPermList(perms, p.Scheme, p.Context) {
				return nil, nil
			}
			permData = append(permData, rolePermissionData{
				Name:         p.Scheme.FullName(),
				ContextType:  string(p.Context.CtxType),
				ContextValue: p.Context.Value,
			})
		}
	}
	return &apiUser{
		Email:       user.Email,
		Roles:       roleData,
		Permissions: permData,
	}, nil
}
Exemple #7
0
// title: team list
// path: /teams
// method: GET
// produce: application/json
// responses:
//   200: List teams
//   204: No content
//   401: Unauthorized
func teamList(w http.ResponseWriter, r *http.Request, t auth.Token) error {
	permsForTeam := permission.PermissionRegistry.PermissionsWithContextType(permission.CtxTeam)
	teams, err := auth.ListTeams()
	if err != nil {
		return err
	}
	teamsMap := map[string][]string{}
	perms, err := t.Permissions()
	if err != nil {
		return err
	}
	for _, team := range teams {
		teamCtx := permission.Context(permission.CtxTeam, team.Name)
		var parent *permission.PermissionScheme
		for _, p := range permsForTeam {
			if parent != nil && parent.IsParent(p) {
				continue
			}
			if permission.CheckFromPermList(perms, p, teamCtx) {
				parent = p
				teamsMap[team.Name] = append(teamsMap[team.Name], p.FullName())
			}
		}
	}
	if len(teamsMap) == 0 {
		w.WriteHeader(http.StatusNoContent)
		return nil
	}
	var result []map[string]interface{}
	for name, permissions := range teamsMap {
		result = append(result, map[string]interface{}{
			"name":        name,
			"permissions": permissions,
		})
	}
	w.Header().Set("Content-Type", "application/json")
	return json.NewEncoder(w).Encode(result)
}