Skip to content

Commit

Permalink
Merge pull request #427 from canonical/IAM-1049
Browse files Browse the repository at this point in the history
feat: add the create email cli command for admin to compensate user invitation email failure
  • Loading branch information
wood-push-melon authored Sep 27, 2024
2 parents 3d7ce46 + 34ba19d commit d4d91a4
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 41 deletions.
119 changes: 119 additions & 0 deletions cmd/createEmail.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
package cmd

import (
"context"
"fmt"
"os"

"github.com/canonical/identity-platform-admin-ui/internal/authorization"
"github.com/canonical/identity-platform-admin-ui/internal/config"
"github.com/canonical/identity-platform-admin-ui/internal/kratos"
"github.com/canonical/identity-platform-admin-ui/internal/logging"
"github.com/canonical/identity-platform-admin-ui/internal/mail"
"github.com/canonical/identity-platform-admin-ui/internal/monitoring"
"github.com/canonical/identity-platform-admin-ui/internal/openfga"
"github.com/canonical/identity-platform-admin-ui/internal/pool"
"github.com/canonical/identity-platform-admin-ui/internal/tracing"
"github.com/canonical/identity-platform-admin-ui/pkg/identities"
"github.com/kelseyhightower/envconfig"
"github.com/spf13/cobra"
)

var sendInvitationCmd = &cobra.Command{
Use: "send-invite [identity-id]",
Short: "Send an invitation email for an identity",
Example: `Send an invitation email:
identity-platform-admin-ui send-invite d0bebe60-f4fa-4bdc-b6d6-dff9eb42d287`,
Long: `Send an invitation email for an identity if previous email sending efforts failed.`,
Args: cobra.ExactArgs(1),
Run: sendInvitationHandler,
}

func init() {
rootCmd.AddCommand(sendInvitationCmd)
}

func sendInvitationHandler(cmd *cobra.Command, args []string) {
ctx := context.Background()

logger := logging.NewNoopLogger()
tracer := tracing.NewNoopTracer()
monitor := monitoring.NewNoopMonitor("", logger)
wpool := pool.NewWorkerPool(1, tracer, monitor, logger)
defer wpool.Stop()

// Initialize environment variables
specs, err := initializeEnv()
if err != nil {
panic(err)
}

// Initialize identity service
service := initializeIdentityService(specs, logger, tracer, monitor, wpool)

// Get the identity
identityID := args[0]
identityData, err := service.GetIdentity(ctx, identityID)
if err != nil {
panic(fmt.Errorf("failed to get the identity: %v", err))
}

ids := identityData.Identities
if len(ids) == 0 {
cmd.PrintErrln("No identity found for identity:", identityID)
os.Exit(1)
}

identity := &ids[0]

// Send invitation email
err = service.SendUserCreationEmail(ctx, identity)
if err != nil {
panic(fmt.Errorf("failed to send the invitation email: %v", err))
}

cmd.Printf("Invitation email sent for identity: %s\n", identity.GetId())
}

func initializeEnv() (*config.EnvSpec, error) {
specs := new(config.EnvSpec)
if err := envconfig.Process("", specs); err != nil {
return nil, fmt.Errorf("failed to populate environment variables: %v", err)
}

return specs, nil
}

func initializeIdentityService(specs *config.EnvSpec, logger logging.LoggerInterface, tracer tracing.TracingInterface, monitor monitoring.MonitorInterface, wpool pool.WorkerPoolInterface) *identities.Service {
// Set up Kratos client
kratosClient := kratos.NewClient(specs.KratosAdminURL, specs.Debug)

// Set up OpenFGA authorization
openfgaConfig := openfga.NewConfig(
specs.ApiScheme,
specs.ApiHost,
specs.StoreId,
specs.ApiToken,
specs.ModelId,
specs.Debug,
tracer,
monitor,
logger,
)
openfgaClient := openfga.NewClient(openfgaConfig)
authorizer := authorization.NewAuthorizer(openfgaClient, wpool, tracer, monitor, logger)

// Set up mail service
mailConfig := mail.NewConfig(
specs.MailHost,
specs.MailPort,
specs.MailUsername,
specs.MailPassword,
specs.MailFromAddress,
specs.MailSendTimeoutSeconds,
)
mailService := mail.NewEmailService(mailConfig, tracer, monitor, logger)

return identities.NewService(kratosClient.IdentityAPI(), authorizer, mailService, tracer, monitor, logger)
}
47 changes: 6 additions & 41 deletions cmd/createIdentity.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,10 @@ import (
"io"
"os"

"github.com/canonical/identity-platform-admin-ui/internal/authorization"
"github.com/canonical/identity-platform-admin-ui/internal/config"
"github.com/canonical/identity-platform-admin-ui/internal/kratos"
"github.com/canonical/identity-platform-admin-ui/internal/logging"
"github.com/canonical/identity-platform-admin-ui/internal/mail"
"github.com/canonical/identity-platform-admin-ui/internal/monitoring"
"github.com/canonical/identity-platform-admin-ui/internal/openfga"
"github.com/canonical/identity-platform-admin-ui/internal/pool"
"github.com/canonical/identity-platform-admin-ui/internal/tracing"
"github.com/canonical/identity-platform-admin-ui/pkg/identities"
"github.com/kelseyhightower/envconfig"
kClient "github.com/ory/kratos-client-go"
"github.com/spf13/cobra"
)
Expand Down Expand Up @@ -91,42 +84,14 @@ func createIdentity(identity kClient.CreateIdentityBody) (*kClient.Identity, err
wpool := pool.NewWorkerPool(1, tracer, monitor, logger)
defer wpool.Stop()

specs := new(config.EnvSpec)
if err := envconfig.Process("", specs); err != nil {
return nil, fmt.Errorf("failed to populate environment variables: %v", err)
// Initialize environment variables
specs, err := initializeEnv()
if err != nil {
panic(err)
}

// Set up Kratos client
kratosClient := kratos.NewClient(specs.KratosAdminURL, specs.Debug)

// Set up authorization service
openfgaConfig := openfga.NewConfig(
specs.ApiScheme,
specs.ApiHost,
specs.StoreId,
specs.ApiToken,
specs.ModelId,
specs.Debug,
tracer,
monitor,
logger,
)
openfgaClient := openfga.NewClient(openfgaConfig)
authorizer := authorization.NewAuthorizer(openfgaClient, wpool, tracer, monitor, logger)

// Set up email service
mailConfig := mail.NewConfig(
specs.MailHost,
specs.MailPort,
specs.MailUsername,
specs.MailPassword,
specs.MailFromAddress,
specs.MailSendTimeoutSeconds,
)
mailService := mail.NewEmailService(mailConfig, tracer, monitor, logger)

// Set up identity service
service := identities.NewService(kratosClient.IdentityAPI(), authorizer, mailService, tracer, monitor, logger)
// Initialize identity service
service := initializeIdentityService(specs, logger, tracer, monitor, wpool)

// Create the identity
identityData, err := service.CreateIdentity(ctx, &identity)
Expand Down

0 comments on commit d4d91a4

Please sign in to comment.