BuildingBlocks.Cloud - Technical Documentation
Write-Side Operations Documentation
Version 1.0 - April 2025
This documentation covers the command operations (write-side) of the BuildingBlocks.Cloud component, which provides a unified interface for cloud provider authentication, storage, and messaging services.
Table of Contents
Architecture Overview
Authentication Commands
Storage Write Operations
Messaging Send Operations
Configuration Guide
Usage Examples
Error Handling
1. Architecture Overview
BuildingBlocks.Cloud is structured following Clean Architecture principles with CQRS separation for each cloud service domain. The write-side operations (commands) are handled by dedicated handlers that interact with cloud providers through provider-specific adapters.
Component Diagram
┌─────────────────────────────────────┐
│ Application Layer │
│ ┌─────────────┐ ┌─────────────┐ │
│ │ Commands │ │ Handlers │ │
│ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────┘
│
┌─────────────▼─────────────────────┐
│ Domain Layer │
│ ┌─────────────┐ ┌────────────┐ │
│ │ Services │ │ Entities │ │
│ └─────────────┘ └────────────┘ │
└─────────────────────────────────┘
│
┌─────────────▼─────────────────────────┐
│ Infrastructure Layer │
│ ┌─────────────┐ ┌───────────────┐ │
│ │ Providers │ │ External APIs │ │
│ └─────────────┘ └───────────────┘ │
└───────────────────────────────────────┘
Write-Side Flow
Commands are created by application code
Command handlers validate and process commands
Domain services implement business logic
Provider adapters translate operations to provider-specific APIs
Cloud provider APIs execute the actual operations
2. Authentication Commands
InitiateLoginCommand
Initiates OAuth2 login flow for a cloud provider.
public class InitiateLoginCommand : IRequest<string>
{
public CloudProviderType ProviderType { get; set; }
public string RedirectUri { get; set; }
public string[] Scopes { get; set; }
public string State { get; set; }
public Guid? OrganizationId { get; set; }
}
HandleOAuthCallbackCommand
Processes OAuth2 callback to complete authentication.
public class HandleOAuthCallbackCommand : IRequest<AuthResult>
{
public CloudProviderType ProviderType { get; set; }
public string Code { get; set; }
public string RedirectUri { get; set; }
public string State { get; set; }
public Guid? OrganizationId { get; set; }
}
RevokeTokenCommand
Revokes an OAuth token.
public class RevokeTokenCommand : IRequest<bool>
{
public CloudProviderType ProviderType { get; set; }
public string Token { get; set; }
public TokenType TokenType { get; set; }
public string UserId { get; set; }
public Guid? OrganizationId { get; set; }
}
StoreTokenCommand
Securely stores OAuth tokens.
public class StoreTokenCommand : IRequest<bool>
{
public CloudProviderType ProviderType { get; set; }
public TokenResponse Tokens { get; set; }
public string UserId { get; set; }
public Guid? OrganizationId { get; set; }
}
3. Storage Write Operations
CreateFileCommand
Creates a new file in cloud storage.
public class CreateFileCommand : IRequest<StorageFile>
{
public CloudProviderType ProviderType { get; set; }
public string Name { get; set; }
public string MimeType { get; set; }
public byte[] Content { get; set; }
public string ParentFolderId { get; set; }
public IDictionary<string, string> Metadata { get; set; }
public Guid? OrganizationId { get; set; }
}
CreateFolderCommand
Creates a new folder in cloud storage.
public class CreateFolderCommand : IRequest<StorageFolder>
{
public CloudProviderType ProviderType { get; set; }
public string Name { get; set; }
public string ParentFolderId { get; set; }
public IDictionary<string, string> Metadata { get; set; }
public Guid? OrganizationId { get; set; }
}
UpdateFileCommand
Updates an existing file in cloud storage.
public class UpdateFileCommand : IRequest<StorageFile>
{
public CloudProviderType ProviderType { get; set; }
public string FileId { get; set; }
public string NewName { get; set; }
public byte[] Content { get; set; }
public bool UpdateContent { get; set; }
public IDictionary<string, string> Metadata { get; set; }
public Guid? OrganizationId { get; set; }
}
DeleteFileCommand
Deletes a file from cloud storage.
public class DeleteFileCommand : IRequest<bool>
{
public CloudProviderType ProviderType { get; set; }
public string FileId { get; set; }
public bool Permanent { get; set; }
public Guid? OrganizationId { get; set; }
}
DeleteFolderCommand
Deletes a folder from cloud storage.
public class DeleteFolderCommand : IRequest<bool>
{
public CloudProviderType ProviderType { get; set; }
public string FolderId { get; set; }
public bool Recursive { get; set; }
public bool Permanent { get; set; }
public Guid? OrganizationId { get; set; }
}
ShareItemCommand
Creates a shareable link for a file or folder.
public class ShareItemCommand : IRequest<StorageSharedLink>
{
public CloudProviderType ProviderType { get; set; }
public string ItemId { get; set; }
public SharePermission Permission { get; set; }
public DateTime? ExpiresAt { get; set; }
public string Password { get; set; }
public bool AllowDownload { get; set; }
public Guid? OrganizationId { get; set; }
}
4. Messaging Send Operations
SendEmailCommand
Sends an email message.
public class SendEmailCommand : IRequest<MessageResponse>
{
public CloudProviderType ProviderType { get; set; }
public string From { get; set; }
public string FromName { get; set; }
public List<string> To { get; set; }
public List<string> Cc { get; set; }
public List<string> Bcc { get; set; }
public string Subject { get; set; }
public string PlainTextBody { get; set; }
public string HtmlBody { get; set; }
public List<EmailAttachment> Attachments { get; set; }
public IDictionary<string, string> Headers { get; set; }
public MessagePriority Priority { get; set; } = MessagePriority.Normal;
public Guid? OrganizationId { get; set; }
}
SendTemplatedEmailCommand
Sends an email using a template.
public class SendTemplatedEmailCommand : IRequest<MessageResponse>
{
public CloudProviderType ProviderType { get; set; }
public string From { get; set; }
public string FromName { get; set; }
public List<string> To { get; set; }
public List<string> Cc { get; set; }
public List<string> Bcc { get; set; }
public string Subject { get; set; }
public string TemplateId { get; set; }
public object TemplateData { get; set; }
public List<EmailAttachment> Attachments { get; set; }
public MessagePriority Priority { get; set; } = MessagePriority.Normal;
public Guid? OrganizationId { get; set; }
}
SendSmsCommand
Sends an SMS message.
public class SendSmsCommand : IRequest<MessageResponse>
{
public CloudProviderType ProviderType { get; set; }
public string From { get; set; }
public string To { get; set; }
public string Message { get; set; }
public MessagePriority Priority { get; set; } = MessagePriority.Normal;
public Guid? OrganizationId { get; set; }
}
5. Configuration Guide
OAuth2 Configuration
{
"Cloud": {
"Google": {
"Auth": {
"ClientId": "your-google-client-id",
"ClientSecret": "your-google-client-secret",
"AuthorizationEndpoint": "https://accounts.google.com/o/oauth2/auth",
"TokenEndpoint": "https://oauth2.googleapis.com/token",
"UserInfoEndpoint": "https://www.googleapis.com/oauth2/v2/userinfo",
"DefaultScopes": [
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/userinfo.profile"
]
},
"Storage": {
"DriveApiEndpoint": "https://www.googleapis.com/drive/v3",
"DefaultFolderId": "root"
}
},
"Microsoft": {
"Auth": {
"ClientId": "your-microsoft-client-id",
"ClientSecret": "your-microsoft-client-secret",
"TenantId": "common",
"AuthorizationEndpoint": "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/authorize",
"TokenEndpoint": "https://login.microsoftonline.com/{tenant}/oauth2/v2.0/token",
"UserInfoEndpoint": "https://graph.microsoft.com/v1.0/me",
"DefaultScopes": [
"User.Read",
"Files.ReadWrite"
]
}
}
}
}
Token Storage Configuration
{
"Cloud": {
"TokenStorage": {
"Type": "EncryptedFile", // Options: InMemory, EncryptedFile, Database
"FilePath": "tokens", // For EncryptedFile
"ConnectionString": "", // For Database
"EncryptionKey": "" // Leave empty to use data protection API
}
}
}
6. Usage Examples
Authentication Flow
// 1. Inject the service
private readonly ICloudLoginService _cloudLoginService;
private readonly ITokenManager _tokenManager;
// 2. Initiate login (usually in controller action)
public async Task<IActionResult> LoginWithGoogle()
{
var redirectUri = "https://yourapp.com/oauth/callback/google";
var scopes = new[] {
"https://www.googleapis.com/auth/userinfo.email",
"https://www.googleapis.com/auth/userinfo.profile",
"https://www.googleapis.com/auth/drive"
};
var loginUrl = await _cloudLoginService.InitiateLoginAsync(
CloudProviderType.Google,
redirectUri,
scopes);
return Redirect(loginUrl);
}
// 3. Handle the callback
public async Task<IActionResult> GoogleCallback(string code, string state)
{
var redirectUri = "https://yourapp.com/oauth/callback/google";
var result = await _cloudLoginService.HandleCallbackAsync(
CloudProviderType.Google,
code,
redirectUri,
state);
if (result.Success)
{
// User authenticated successfully
// Store user information in your system
return RedirectToAction("Dashboard");
}
return RedirectToAction("Error", new { message = "Authentication failed" });
}
Storage Operations
// File upload
public async Task<IActionResult> UploadFile(IFormFile file, string folderId)
{
using var memoryStream = new MemoryStream();
await file.CopyToAsync(memoryStream);
var command = new CreateFileCommand
{
ProviderType = CloudProviderType.Google,
Name = file.FileName,
MimeType = file.ContentType,
Content = memoryStream.ToArray(),
ParentFolderId = folderId,
OrganizationId = _currentUser.OrganizationId
};
var result = await _mediator.Send(command);
return Ok(new { FileId = result.Id, Name = result.Name });
}
// Create folder
public async Task<IActionResult> CreateFolder(string name, string parentFolderId)
{
var command = new CreateFolderCommand
{
ProviderType = CloudProviderType.Google,
Name = name,
ParentFolderId = parentFolderId,
OrganizationId = _currentUser.OrganizationId
};
var result = await _mediator.Send(command);
return Ok(new { FolderId = result.Id, Name = result.Name });
}
// Create shareable link
public async Task<IActionResult> ShareFile(string fileId)
{
var command = new ShareItemCommand
{
ProviderType = CloudProviderType.Google,
ItemId = fileId,
Permission = SharePermission.View,
ExpiresAt = DateTime.UtcNow.AddDays(7),
AllowDownload = true,
OrganizationId = _currentUser.OrganizationId
};
var result = await _mediator.Send(command);
return Ok(new { Url = result.Url, ExpiresAt = result.ExpiresAt });
}
Messaging Operations
// Send email
public async Task<IActionResult> SendWelcomeEmail(string to, string username)
{
var command = new SendTemplatedEmailCommand
{
ProviderType = CloudProviderType.Google,
From = "noreply@yourdomain.com",
FromName = "Your App",
To = new List<string> { to },
Subject = "Welcome to Our Platform",
TemplateId = "welcome-email",
TemplateData = new { Username = username, Year = DateTime.Now.Year },
Priority = MessagePriority.High,
OrganizationId = _currentUser.OrganizationId
};
var result = await _mediator.Send(command);
return Ok(new { Success = result.Success, MessageId = result.MessageId });
}
// Send SMS
public async Task<IActionResult> SendVerificationSms(string phoneNumber, string code)
{
var command = new SendSmsCommand
{
ProviderType = CloudProviderType.Twilio,
From = "+15551234567",
To = phoneNumber,
Message = $"Your verification code is: {code}",
Priority = MessagePriority.High,
OrganizationId = _currentUser.OrganizationId
};
var result = await _mediator.Send(command);
return Ok(new { Success = result.Success, MessageId = result.MessageId });
}
7. Error Handling
The BuildingBlocks.Cloud package uses a consistent exception model for write operations:
Exception Type | Description | HTTP Status Code |
|---|
CloudAuthenticationException
| Authentication failures | 401 Unauthorized |
CloudProviderException
| Provider-specific errors | 502 Bad Gateway |
CloudPermissionException
| Permission/authorization issues | 403 Forbidden |
CloudValidationException
| Invalid input or configuration | 400 Bad Request |
CloudStorageException
| Storage operation failures | 500 Internal Error |
CloudMessagingException
| Messaging operation failures | 500 Internal Error |
Example error handling:
try
{
var result = await _mediator.Send(command);
return Ok(result);
}
catch (CloudAuthenticationException ex)
{
_logger.LogWarning(ex, "Authentication error");
return Unauthorized(new { error = ex.Message });
}
catch (CloudPermissionException ex)
{
_logger.LogWarning(ex, "Permission error");
return Forbid(ex.Message);
}
catch (CloudValidationException ex)
{
_logger.LogWarning(ex, "Validation error");
return BadRequest(new { error = ex.Message, details = ex.Errors });
}
catch (CloudException ex)
{
_logger.LogError(ex, "Cloud operation error");
return StatusCode(500, new { error = "An error occurred processing your request" });
}
This technical documentation covers the key write-side operations of the BuildingBlocks.Cloud component. For additional details, refer to the API reference documentation and example projects included with the package.
Similar code found with 4 license types
Last modified: 20 December 2025