Mail support
Deploy Promiscuity Auth API / deploy (push) Successful in 48s
Deploy Promiscuity Character API / deploy (push) Successful in 59s
Deploy Promiscuity Inventory API / deploy (push) Successful in 46s
Deploy Promiscuity Locations API / deploy (push) Successful in 1m0s
Deploy Promiscuity Mail API / deploy (push) Successful in 1m9s
k8s smoke test / test (push) Successful in 9s
Deploy Promiscuity Auth API / deploy (push) Successful in 48s
Deploy Promiscuity Character API / deploy (push) Successful in 59s
Deploy Promiscuity Inventory API / deploy (push) Successful in 46s
Deploy Promiscuity Locations API / deploy (push) Successful in 1m0s
Deploy Promiscuity Mail API / deploy (push) Successful in 1m9s
k8s smoke test / test (push) Successful in 9s
This commit is contained in:
@@ -0,0 +1,137 @@
|
||||
using MailApi.Models;
|
||||
using MongoDB.Bson;
|
||||
using MongoDB.Bson.Serialization.Attributes;
|
||||
using MongoDB.Driver;
|
||||
|
||||
namespace MailApi.Services;
|
||||
|
||||
public class MailStore
|
||||
{
|
||||
private readonly IMongoCollection<MailMessage> _messages;
|
||||
private readonly IMongoCollection<CharacterDocument> _characters;
|
||||
|
||||
public MailStore(IConfiguration cfg)
|
||||
{
|
||||
var cs = cfg["MongoDB:ConnectionString"] ?? "mongodb://127.0.0.1:27017";
|
||||
var dbName = cfg["MongoDB:DatabaseName"] ?? "promiscuity";
|
||||
var client = new MongoClient(cs);
|
||||
var db = client.GetDatabase(dbName);
|
||||
_messages = db.GetCollection<MailMessage>("MailMessages");
|
||||
_characters = db.GetCollection<CharacterDocument>("Characters");
|
||||
|
||||
_messages.Indexes.CreateOne(new CreateIndexModel<MailMessage>(
|
||||
Builders<MailMessage>.IndexKeys.Ascending(m => m.RecipientCharacterId).Descending(m => m.CreatedUtc)));
|
||||
_messages.Indexes.CreateOne(new CreateIndexModel<MailMessage>(
|
||||
Builders<MailMessage>.IndexKeys.Ascending(m => m.SenderCharacterId).Descending(m => m.CreatedUtc)));
|
||||
}
|
||||
|
||||
public async Task<CharacterAccessResult> ResolveCharacterAsync(string characterId, string userId, bool allowAnyOwner)
|
||||
{
|
||||
var character = await _characters.Find(c => c.Id == characterId).FirstOrDefaultAsync();
|
||||
if (character is null)
|
||||
return new CharacterAccessResult { Exists = false };
|
||||
|
||||
return new CharacterAccessResult
|
||||
{
|
||||
Exists = true,
|
||||
IsAuthorized = allowAnyOwner || character.OwnerUserId == userId,
|
||||
CharacterId = character.Id ?? string.Empty,
|
||||
CharacterName = character.Name,
|
||||
OwnerUserId = character.OwnerUserId
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<List<MailMessage>> GetInboxAsync(string characterId) =>
|
||||
await _messages.Find(m => m.RecipientCharacterId == characterId)
|
||||
.SortByDescending(m => m.CreatedUtc)
|
||||
.ToListAsync();
|
||||
|
||||
public async Task<List<MailMessage>> GetSentAsync(string characterId) =>
|
||||
await _messages.Find(m => m.SenderCharacterId == characterId)
|
||||
.SortByDescending(m => m.CreatedUtc)
|
||||
.ToListAsync();
|
||||
|
||||
public async Task<SendMailResult> SendAsync(string senderCharacterId, string recipientCharacterName, string subject, string body)
|
||||
{
|
||||
var sender = await _characters.Find(c => c.Id == senderCharacterId).FirstOrDefaultAsync();
|
||||
if (sender is null)
|
||||
return new SendMailResult { Status = SendMailStatus.SenderNotFound };
|
||||
|
||||
var normalizedRecipientName = recipientCharacterName.Trim();
|
||||
var recipients = await _characters.Find(c => c.Name == normalizedRecipientName).ToListAsync();
|
||||
if (recipients.Count == 0)
|
||||
return new SendMailResult { Status = SendMailStatus.RecipientNotFound };
|
||||
if (recipients.Count > 1)
|
||||
return new SendMailResult { Status = SendMailStatus.RecipientAmbiguous };
|
||||
|
||||
var recipient = recipients[0];
|
||||
if (recipient.Id == sender.Id)
|
||||
return new SendMailResult { Status = SendMailStatus.Invalid };
|
||||
|
||||
var message = new MailMessage
|
||||
{
|
||||
SenderCharacterId = sender.Id ?? string.Empty,
|
||||
SenderCharacterName = sender.Name,
|
||||
RecipientCharacterId = recipient.Id ?? string.Empty,
|
||||
RecipientCharacterName = recipient.Name,
|
||||
Subject = subject.Trim(),
|
||||
Body = body.Trim(),
|
||||
CreatedUtc = DateTime.UtcNow
|
||||
};
|
||||
|
||||
await _messages.InsertOneAsync(message);
|
||||
return new SendMailResult { Status = SendMailStatus.Ok, Message = message };
|
||||
}
|
||||
|
||||
public async Task<MailMessage?> MarkReadAsync(string characterId, string messageId)
|
||||
{
|
||||
var filter = Builders<MailMessage>.Filter.And(
|
||||
Builders<MailMessage>.Filter.Eq(m => m.Id, messageId),
|
||||
Builders<MailMessage>.Filter.Eq(m => m.RecipientCharacterId, characterId)
|
||||
);
|
||||
var update = Builders<MailMessage>.Update.Set(m => m.ReadUtc, DateTime.UtcNow);
|
||||
var options = new FindOneAndUpdateOptions<MailMessage> { ReturnDocument = ReturnDocument.After };
|
||||
return await _messages.FindOneAndUpdateAsync(filter, update, options);
|
||||
}
|
||||
|
||||
public class CharacterAccessResult
|
||||
{
|
||||
public bool Exists { get; set; }
|
||||
|
||||
public bool IsAuthorized { get; set; }
|
||||
|
||||
public string CharacterId { get; set; } = string.Empty;
|
||||
|
||||
public string CharacterName { get; set; } = string.Empty;
|
||||
|
||||
public string OwnerUserId { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class SendMailResult
|
||||
{
|
||||
public SendMailStatus Status { get; set; }
|
||||
|
||||
public MailMessage? Message { get; set; }
|
||||
}
|
||||
|
||||
public enum SendMailStatus
|
||||
{
|
||||
Ok,
|
||||
SenderNotFound,
|
||||
RecipientNotFound,
|
||||
RecipientAmbiguous,
|
||||
Invalid
|
||||
}
|
||||
|
||||
[BsonIgnoreExtraElements]
|
||||
private class CharacterDocument
|
||||
{
|
||||
[BsonId]
|
||||
[BsonRepresentation(BsonType.ObjectId)]
|
||||
public string? Id { get; set; }
|
||||
|
||||
public string OwnerUserId { get; set; } = string.Empty;
|
||||
|
||||
public string Name { get; set; } = string.Empty;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user