// 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, mergeErr("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 out, err } out.Password = string(hash) } else { out.Password = u.Password } currentRoles := types.NewUnsafeSet(u.Roles...) for _, g := range n.Grant { if currentRoles.Contains(g) { return out, mergeErr("Granting duplicate role %s for user %s", g, n.User) } currentRoles.Add(g) } for _, r := range n.Revoke { if !currentRoles.Contains(r) { return out, mergeErr("Revoking ungranted role %s for user %s", r, n.User) } currentRoles.Remove(r) } out.Roles = currentRoles.Values() return out, nil }
func (s *Store) createUserInternal(user User) error { hash, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost) if err != nil { return err } user.Password = string(hash) _, err = s.createResource("/users/"+user.User, user) return err }