Code
·
160 lines
·
6811 bytes
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160using MailSharp.WebManager.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace MailSharp.WebManager.Controllers;
[Authorize(Roles = "Administrator")]
[Route("~/api/[controller]")]
[ApiController]
public class DomainController(DomainService domainService, IConfiguration configuration) : ControllerBase
{
[HttpGet]
public IActionResult GetAll() => Ok(domainService.GetAll());
[HttpGet("{id}")]
public IActionResult GetById(string id)
{
var d = domainService.GetById(id);
return d is null ? NotFound() : Ok(d);
}
[HttpPost]
public IActionResult Create([FromBody] CreateDomainDto dto)
{
if (string.IsNullOrWhiteSpace(dto.Name))
return BadRequest("Name is required.");
return Ok(domainService.Create(dto.Name));
}
[HttpDelete("{id}")]
public IActionResult Delete(string id) =>
domainService.Delete(id) ? Ok() : NotFound();
// ── General ────────────────────────────────────────────────
[HttpPut("{id}/general")]
public IActionResult UpdateGeneral(string id, [FromBody] GeneralDto dto)
{
if (string.IsNullOrWhiteSpace(dto.Name)) return BadRequest("Name is required.");
return domainService.PatchGeneral(id, dto.Name, dto.Enabled, dto.CatchAll ?? "") ? Ok() : NotFound();
}
// ── Limits ─────────────────────────────────────────────────
[HttpPut("{id}/limits")]
public IActionResult UpdateLimits(string id, [FromBody] DomainLimits dto) =>
domainService.PatchLimits(id, dto) ? Ok() : NotFound();
// ── DKIM ───────────────────────────────────────────────────
[HttpPut("{id}/dkim")]
public IActionResult UpdateDkim(string id, [FromBody] DkimConfig dto) =>
domainService.PatchDkim(id, dto) ? Ok() : NotFound();
// ── Domain aliases ─────────────────────────────────────────
[HttpPost("{id}/aliases")]
public IActionResult AddAlias(string id, [FromBody] AliasValueDto dto)
{
if (string.IsNullOrWhiteSpace(dto.Value)) return BadRequest("Alias is required.");
return domainService.AddAlias(id, dto.Value) ? Ok() : NotFound();
}
[HttpDelete("{id}/aliases/{alias}")]
public IActionResult RemoveAlias(string id, string alias) =>
domainService.RemoveAlias(id, alias) ? Ok() : NotFound();
// ── Users ──────────────────────────────────────────────────
[HttpPost("{id}/users")]
public IActionResult AddUser(string id, [FromBody] DomainUser dto)
{
if (string.IsNullOrWhiteSpace(dto.Username)) return BadRequest("Username is required.");
if (string.IsNullOrWhiteSpace(dto.Password)) return BadRequest("Password is required.");
dto.Id = Guid.NewGuid().ToString();
return domainService.AddUser(id, dto) ? Ok(dto) : NotFound();
}
[HttpPut("{id}/users/{userId}")]
public IActionResult UpdateUser(string id, string userId, [FromBody] DomainUser dto) =>
domainService.UpdateUser(id, userId, dto) ? Ok() : NotFound();
[HttpDelete("{id}/users/{userId}")]
public IActionResult DeleteUser(string id, string userId) =>
domainService.DeleteUser(id, userId) ? Ok() : NotFound();
// ── User aliases ───────────────────────────────────────────
[HttpPost("{id}/useraliases")]
public IActionResult AddUserAlias(string id, [FromBody] UserAlias dto)
{
if (string.IsNullOrWhiteSpace(dto.Alias)) return BadRequest("Alias is required.");
if (string.IsNullOrWhiteSpace(dto.Target)) return BadRequest("Target is required.");
return domainService.AddUserAlias(id, dto) ? Ok() : NotFound();
}
[HttpDelete("{id}/useraliases/{alias}")]
public IActionResult RemoveUserAlias(string id, string alias) =>
domainService.RemoveUserAlias(id, alias) ? Ok() : NotFound();
// ── Email lists ────────────────────────────────────────────
[HttpPost("{id}/lists")]
public IActionResult AddList(string id, [FromBody] ListNameDto dto)
{
if (string.IsNullOrWhiteSpace(dto.Name)) return BadRequest("Name is required.");
var list = new EmailList { Name = dto.Name.Trim().ToLowerInvariant() };
return domainService.AddEmailList(id, list) ? Ok(list) : NotFound();
}
[HttpDelete("{id}/lists/{listId}")]
public IActionResult RemoveList(string id, string listId) =>
domainService.RemoveEmailList(id, listId) ? Ok() : NotFound();
[HttpPost("{id}/lists/{listId}/members")]
public IActionResult AddMember(string id, string listId, [FromBody] AliasValueDto dto)
{
if (string.IsNullOrWhiteSpace(dto.Value)) return BadRequest("Member is required.");
return domainService.AddListMember(id, listId, dto.Value) ? Ok() : NotFound();
}
[HttpDelete("{id}/lists/{listId}/members/{member}")]
public IActionResult RemoveMember(string id, string listId, string member) =>
domainService.RemoveListMember(id, listId, member) ? Ok() : NotFound();
// ── User stats ─────────────────────────────────────────────
[HttpGet("{id}/userstats")]
public IActionResult UserStats(string id)
{
var domain = domainService.GetById(id);
if (domain is null) return NotFound();
var storagePath = configuration["MailboxSettings:StoragePath"];
var stats = domain.Users.Select(u =>
{
var address = $"{u.Username}@{domain.Name}";
var mailbox = string.IsNullOrEmpty(storagePath) ? null : Path.Combine(storagePath, address);
var sizeMb = 0.0;
DateTime? lastActivity = null;
if (mailbox != null && Directory.Exists(mailbox))
{
var files = Directory.GetFiles(mailbox, "*.eml", SearchOption.AllDirectories);
sizeMb = files.Sum(f => new FileInfo(f).Length) / 1_048_576.0;
if (files.Length > 0)
lastActivity = files.Select(f => System.IO.File.GetLastWriteTimeUtc(f)).Max();
}
return new { userId = u.Id, sizeMb = Math.Round(sizeMb, 2), lastActivity };
});
return Ok(stats);
}
}
public class CreateDomainDto { public string Name { get; set; } = string.Empty; }
public class GeneralDto { public string Name { get; set; } = string.Empty; public bool Enabled { get; set; } public string? CatchAll { get; set; } }
public class AliasValueDto { public string Value { get; set; } = string.Empty; }
public class ListNameDto { public string Name { get; set; } = string.Empty; }