dotnet/space-translate/SpaceTranslate/WebHook/SpaceTranslateWebHookHandler.Infrastructure.cs (113 lines of code) (raw):

using JetBrains.Space.Client; using Microsoft.EntityFrameworkCore; using SpaceTranslate.Database; namespace SpaceTranslate.WebHook; public partial class SpaceTranslateWebHookHandler { public override async Task<ApplicationExecutionResult> HandleInitAsync(InitPayload payload) { // Validation if (payload.State == null) { _logger.LogWarning("No state parameter is provided in the in the request payload"); return new ApplicationExecutionResult("No state parameter is provided in the request payload.", 400); } var organization = await _db.Organizations.FirstOrDefaultAsync(it => it.ClientId == payload.ClientId); if (organization != null) { _logger.LogWarning("The organization is already registered. ClientId={ClientId}; ServerUrl={ServerUrl}", payload.ClientId, payload.ServerUrl); return new ApplicationExecutionResult("The organization server URL is already registered.", 400); } // Create organization locally organization = new Organization { Created = DateTimeOffset.UtcNow, ServerUrl = payload.ServerUrl, ClientId = payload.ClientId, ClientSecret = payload.ClientSecret, UserId = payload.UserId, SigningKey = "pending" }; _db.Organizations.Add(organization); await _db.SaveChangesAsync(); // Connect to Space var connection = organization.CreateConnection(); var applicationClient = new ApplicationClient(connection); // Store signing key var signingKey = await applicationClient.SigningKey.GetSigningKeyAsync(ApplicationIdentifier.Me); organization.SigningKey = signingKey; await _db.SaveChangesAsync(); // Initialize Space organization var applicationInfo = await applicationClient.GetApplicationAsync(ApplicationIdentifier.Me); if (string.IsNullOrEmpty(applicationInfo.Picture)) { await using var logoStream = GetType().Assembly.GetManifestResourceStream("SpaceTranslate.Resources.logo.png")!; var uploadClient = new UploadClient(connection); var uploadedFileAttachmentId = await uploadClient.UploadAsync( storagePrefix: "file", fileName: "spacetranslate-logo.png", uploadStream: logoStream, mediaType: null); if (!string.IsNullOrEmpty(uploadedFileAttachmentId)) { await applicationClient.UpdateApplicationAsync( application: ApplicationIdentifier.Me, pictureAttachmentId: uploadedFileAttachmentId); } } await applicationClient.Authorizations.AuthorizedRights.RequestRightsAsync( application: ApplicationIdentifier.Me, contextIdentifier: PermissionContextIdentifier.Global, rightCodes: new List<PermissionIdentifier> { PermissionIdentifier.ViewMemberProfiles, PermissionIdentifier.ViewMessages, PermissionIdentifier.ViewChannelInfo }); await applicationClient.SetUiExtensionsAsync( contextIdentifier: PermissionContextIdentifier.Global, extensions: new List<AppUiExtensionIn> { new ChatMessageMenuItemUiExtensionIn( displayName: "Translate", description: "Translates the message into English.", menuItemUniqueCode: "translate-message", visibilityFilters: new List<ChatMessageMenuItemVisibilityFilterIn>()) // no filters - visible to everyone }); return await base.HandleInitAsync(payload); } public override async Task<ApplicationExecutionResult> HandleChangeClientSecretRequestAsync(ChangeClientSecretPayload payload) { var organization = await _db.Organizations.FirstOrDefaultAsync(it => it.ClientId == payload.ClientId); if (organization == null) { _logger.LogWarning("The organization does not exist. ClientId={ClientId}", payload.ClientId); return new ApplicationExecutionResult("The organization does not exist.", 400); } organization.ClientSecret = payload.NewClientSecret; await _db.SaveChangesAsync(); return await base.HandleChangeClientSecretRequestAsync(payload); } public override async Task<ApplicationExecutionResult> HandleChangeServerUrlAsync(ChangeServerUrlPayload payload) { var organization = await _db.Organizations.FirstOrDefaultAsync(it => it.ClientId == payload.ClientId); if (organization == null) { _logger.LogWarning("The organization does not exist. ClientId={ClientId}", payload.ClientId); return new ApplicationExecutionResult("The organization does not exist.", 400); } organization.ServerUrl = payload.NewServerUrl; await _db.SaveChangesAsync(); return await base.HandleChangeServerUrlAsync(payload); } public override async Task<ApplicationExecutionResult> HandleUninstalledAsync(ApplicationUninstalledPayload payload) { // Uninstall application var organization = await _db.Organizations .Include(it => it.Users) .FirstOrDefaultAsync(it => it.ClientId == payload.ClientId); if (organization == null) { _logger.LogWarning("The organization is already uninstalled. ClientId={ClientId}; ServerUrl={ServerUrl}", payload.ClientId, payload.ServerUrl); return new ApplicationExecutionResult("The organization is already uninstalled."); } // Delete related entities _db.RemoveRange(organization.Users); _db.RemoveRange(organization); await _db.SaveChangesAsync(); return new ApplicationExecutionResult("The organization has been uninstalled."); } }