Esempio n. 1
0
// merge applies the properties of the passed-in User to the User on which it
// is called and returns a new User with these modifications applied. Think of
// all Users as immutable sets of data. Merge allows you to perform the set
// operations (desired grants and revokes) atomically
func (u User) merge(n User) (User, error) {
	var out User
	if u.User != n.User {
		return out, authErr(http.StatusConflict, "Merging user data with conflicting usernames: %s %s", u.User, n.User)
	}
	out.User = u.User
	if n.Password != "" {
		hash, err := bcrypt.GenerateFromPassword([]byte(n.Password), bcrypt.DefaultCost)
		if err != nil {
			return User{}, err
		}
		out.Password = string(hash)
	} else {
		out.Password = u.Password
	}
	currentRoles := types.NewUnsafeSet(u.Roles...)
	for _, g := range n.Grant {
		if currentRoles.Contains(g) {
			plog.Noticef("granting duplicate role %s for user %s", g, n.User)
			return User{}, authErr(http.StatusConflict, fmt.Sprintf("Granting duplicate role %s for user %s", g, n.User))
		}
		currentRoles.Add(g)
	}
	for _, r := range n.Revoke {
		if !currentRoles.Contains(r) {
			plog.Noticef("revoking ungranted role %s for user %s", r, n.User)
			return User{}, authErr(http.StatusConflict, fmt.Sprintf("Revoking ungranted role %s for user %s", r, n.User))
		}
		currentRoles.Remove(r)
	}
	out.Roles = currentRoles.Values()
	sort.Strings(out.Roles)
	return out, nil
}
Esempio n. 2
0
func (s *store) createUserInternal(user User) (User, error) {
	if user.Password == "" {
		return user, authErr(http.StatusBadRequest, "Cannot create user %s with an empty password", user.User)
	}
	hash, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
	if err != nil {
		return user, err
	}
	user.Password = string(hash)

	_, err = s.createResource("/users/"+user.User, user)
	if err != nil {
		if e, ok := err.(*etcderr.Error); ok {
			if e.ErrorCode == etcderr.EcodeNodeExist {
				return user, authErr(http.StatusConflict, "User %s already exists.", user.User)
			}
		}
	}
	return user, err
}