mirror of
https://github.com/coder/coder.git
synced 2025-07-03 16:13:58 +00:00
feat: notify about created user account (#14010)
This commit is contained in:
@ -12,6 +12,8 @@ import (
|
||||
"github.com/google/uuid"
|
||||
"golang.org/x/xerrors"
|
||||
|
||||
"cdr.dev/slog"
|
||||
|
||||
"github.com/coder/coder/v2/coderd/audit"
|
||||
"github.com/coder/coder/v2/coderd/database"
|
||||
"github.com/coder/coder/v2/coderd/database/db2sdk"
|
||||
@ -20,6 +22,7 @@ import (
|
||||
"github.com/coder/coder/v2/coderd/gitsshkey"
|
||||
"github.com/coder/coder/v2/coderd/httpapi"
|
||||
"github.com/coder/coder/v2/coderd/httpmw"
|
||||
"github.com/coder/coder/v2/coderd/notifications"
|
||||
"github.com/coder/coder/v2/coderd/rbac"
|
||||
"github.com/coder/coder/v2/coderd/rbac/policy"
|
||||
"github.com/coder/coder/v2/coderd/searchquery"
|
||||
@ -1200,7 +1203,8 @@ func (api *API) organizationByUserAndName(rw http.ResponseWriter, r *http.Reques
|
||||
|
||||
type CreateUserRequest struct {
|
||||
codersdk.CreateUserRequest
|
||||
LoginType database.LoginType
|
||||
LoginType database.LoginType
|
||||
SkipNotifications bool
|
||||
}
|
||||
|
||||
func (api *API) CreateUser(ctx context.Context, store database.Store, req CreateUserRequest) (database.User, uuid.UUID, error) {
|
||||
@ -1211,7 +1215,7 @@ func (api *API) CreateUser(ctx context.Context, store database.Store, req Create
|
||||
}
|
||||
|
||||
var user database.User
|
||||
return user, req.OrganizationID, store.InTx(func(tx database.Store) error {
|
||||
err := store.InTx(func(tx database.Store) error {
|
||||
orgRoles := make([]string, 0)
|
||||
// Organization is required to know where to allocate the user.
|
||||
if req.OrganizationID == uuid.Nil {
|
||||
@ -1272,6 +1276,37 @@ func (api *API) CreateUser(ctx context.Context, store database.Store, req Create
|
||||
}
|
||||
return nil
|
||||
}, nil)
|
||||
if err != nil || req.SkipNotifications {
|
||||
return user, req.OrganizationID, err
|
||||
}
|
||||
|
||||
// Notify all users with user admin permission including owners
|
||||
// Notice: we can't scrape the user information in parallel as pq
|
||||
// fails with: unexpected describe rows response: 'D'
|
||||
owners, err := store.GetUsers(ctx, database.GetUsersParams{
|
||||
RbacRole: []string{codersdk.RoleOwner},
|
||||
})
|
||||
if err != nil {
|
||||
return user, req.OrganizationID, xerrors.Errorf("get owners: %w", err)
|
||||
}
|
||||
userAdmins, err := store.GetUsers(ctx, database.GetUsersParams{
|
||||
RbacRole: []string{codersdk.RoleUserAdmin},
|
||||
})
|
||||
if err != nil {
|
||||
return user, req.OrganizationID, xerrors.Errorf("get user admins: %w", err)
|
||||
}
|
||||
|
||||
for _, u := range append(owners, userAdmins...) {
|
||||
if _, err := api.NotificationsEnqueuer.Enqueue(ctx, u.ID, notifications.TemplateUserAccountCreated,
|
||||
map[string]string{
|
||||
"created_account_name": user.Username,
|
||||
}, "api-users-create",
|
||||
user.ID,
|
||||
); err != nil {
|
||||
api.Logger.Warn(ctx, "unable to notify about created user", slog.F("created_user", user.Username), slog.Error(err))
|
||||
}
|
||||
}
|
||||
return user, req.OrganizationID, err
|
||||
}
|
||||
|
||||
func convertUsers(users []database.User, organizationIDsByUserID map[uuid.UUID][]uuid.UUID) []codersdk.User {
|
||||
|
Reference in New Issue
Block a user