public async Task <ICommandResult> HandleAsync(ProjectIdentityCreateCommand command, IAsyncCollector <ICommand> commandQueue, IDurableOrchestrationContext orchestrationContext, ILogger log)
    {
        if (command is null)
        {
            throw new ArgumentNullException(nameof(command));
        }

        if (commandQueue is null)
        {
            throw new ArgumentNullException(nameof(commandQueue));
        }

        var commandResult   = command.CreateResult();
        var projectIdentity = command.Payload;

        try
        {
            var servicePrincipal = await graphService
                                   .CreateServicePrincipalAsync(projectIdentity.Id)
                                   .ConfigureAwait(false);

            projectIdentity.ObjectId     = servicePrincipal.Id;
            projectIdentity.TenantId     = servicePrincipal.TenantId;
            projectIdentity.ClientId     = servicePrincipal.AppId;
            projectIdentity.ClientSecret = servicePrincipal.Password;

            if (projectIdentity.RedirectUrls is not null)
            {
                projectIdentity.RedirectUrls = await graphService
                                               .SetServicePrincipalRedirectUrlsAsync(projectIdentity.ObjectId.ToString(), projectIdentity.RedirectUrls)
                                               .ConfigureAwait(false);
            }

            commandResult.Result = await projectIdentityRepository
                                   .AddAsync(projectIdentity)
                                   .ConfigureAwait(false);

            commandResult.RuntimeStatus = CommandRuntimeStatus.Completed;
        }
        catch (Exception exc)
        {
            await commandQueue
            .AddAsync(new ProjectIdentityDeleteCommand(command.User, projectIdentity))
            .ConfigureAwait(false);

            commandResult.Errors.Add(exc);
        }

        return(commandResult);
    }
Пример #2
0
#pragma warning restore CS0618 // Type or member is obsolete

    public virtual async Task <AzureServicePrincipal> GetServiceIdentityAsync(Component component, bool withPassword = false)
    {
        if (this is IAdapterIdentity)
        {
            var servicePrincipalKey = Guid.Parse(component.Organization)
                                      .Combine(Guid.Parse(component.DeploymentScopeId), Guid.Parse(component.ProjectId));

            var servicePrincipalName = $"{this.GetType().Name}/{servicePrincipalKey}";

            var servicePrincipal = await graphService
                                   .GetServicePrincipalAsync(servicePrincipalName)
                                   .ConfigureAwait(false);

            if (servicePrincipal is null)
            {
                // there is no service principal for the current deployment scope
                // create a new one that we can use to create/update the corresponding
                // service endpoint in the current team project

                servicePrincipal = await graphService
                                   .CreateServicePrincipalAsync(servicePrincipalName)
                                   .ConfigureAwait(false);
            }
            else if (servicePrincipal.ExpiresOn.GetValueOrDefault(DateTime.MinValue) < DateTime.UtcNow)
            {
                // a service principal exists, but its secret is expired. lets refresh
                // the service principal (create a new secret) so we can move on
                // creating/updating the corresponding service endpoint.

                servicePrincipal = await graphService
                                   .RefreshServicePrincipalAsync(servicePrincipalName)
                                   .ConfigureAwait(false);
            }

            if (!string.IsNullOrEmpty(servicePrincipal.Password))
            {
                var project = await projectRepository
                              .GetAsync(component.Organization, component.ProjectId)
                              .ConfigureAwait(false);

                var secretsStore = await secretsStoreProvider
                                   .GetSecretsStoreAsync(project)
                                   .ConfigureAwait(false);

                servicePrincipal = await secretsStore
                                   .SetSecretAsync(servicePrincipal.Id.ToString(), servicePrincipal)
                                   .ConfigureAwait(false);
            }
            else if (withPassword)
            {
                var project = await projectRepository
                              .GetAsync(component.Organization, component.ProjectId)
                              .ConfigureAwait(false);

                var secretsStore = await secretsStoreProvider
                                   .GetSecretsStoreAsync(project)
                                   .ConfigureAwait(false);

                servicePrincipal = (await secretsStore
                                    .GetSecretAsync <AzureServicePrincipal>(servicePrincipal.Id.ToString())
                                    .ConfigureAwait(false)) ?? servicePrincipal;
            }

            return(servicePrincipal);
        }

        return(null);
    }