Skip to content

Commit

Permalink
Merge pull request #735 from EdiWang/master
Browse files Browse the repository at this point in the history
Release v12.12.0
  • Loading branch information
EdiWang authored Jul 31, 2023
2 parents 2aaa52a + 1ad7916 commit 6026cf0
Show file tree
Hide file tree
Showing 60 changed files with 255 additions and 327 deletions.
2 changes: 1 addition & 1 deletion Features.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@

### OIDC

- Azure Active Directory
- Microsoft Entra ID

### 本地账号

Expand Down
53 changes: 22 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,15 @@ The [.NET](https://dotnet.microsoft.com/) blog system of [edi.wang](https://edi.

### ☁ Full Deploy on Azure (Recommend)

This is the way https://edi.wang is deployed, by taking advantage of as many Azure services as possible, the blog can run very fast and secure.
This is the way https://edi.wang is deployed, by taking advantage of as many Azure services as possible, the blog can run very fast and secure.

This diagram shows a full Azure deployment for Moonglade for reference.
But there is no automated script to deploy it, you need to manually create all the resources and configure them.

![image](https://cdn-blog.edi.wang/web-assets/ediwang-azure-arch-visio-nov2022.png)

### 🐋 Quick Deploy on Azure
### 🐋 Quick Deploy on Azure (App Service on Linux)

Use automated deployment script to get your Moonglade up and running in 10 minutes, follow instructions [here](https://github.com/EdiWang/Moonglade/wiki/Quick-Deploy-on-Azure)
Use automated deployment script to get your Moonglade up and running in 10 minutes with minimal Azure components, follow instructions [here](https://github.com/EdiWang/Moonglade/wiki/Quick-Deploy-on-Azure)

### 🐧 Quick Deploy on Linux without Docker

Expand All @@ -39,42 +39,32 @@ Tools | Alternative

Moonglade supports three types of database. You can choose from SQL Server, PostgreSQL or MySQL.

#### SQL Server

Create a SQL Server 2022 database, e.g. ```moonglade```
Update your database connection string in `appsettings.*.json`

Set the `MoongladeDatabase` to your database connection string in `appsettings.Development.json`
#### SQL Server

```json
"MoongladeDatabase": "Server=(localdb)\\MSSQLLocalDB;Database=moonglade;Trusted_Connection=True;"
"ConnectionStrings": {
"MoongladeDatabase": "Server=(localdb)\\MSSQLLocalDB;Database=Moonglade;Trusted_Connection=True;",
"DatabaseType": "SqlServer"
}
```

#### MySQL

Set `DatabaseType` to `MySql`

```json
"DatabaseType": "MySql"
```

Set the `MoongladeDatabase` to your database connection string in `appsettings.Development.json`

```json
"MoongladeDatabase": "Server=localhost;Port=3306;Database=moonglade;Uid=root;Pwd=******;"
"ConnectionStrings": {
"MoongladeDatabase": "Server=localhost;Port=3306;Database=moonglade;Uid=root;Pwd=******;",
"DatabaseType": "MySql"
}
```

#### PostgreSql

Set `DatabaseType` to `PostgreSql`

```json
"DatabaseType": "PostgreSql"
```

Set the `MoongladeDatabase` to your database connection string in `appsettings.Development.json`

```json
"MoongladeDatabase": "User ID=****;Password=****;Host=localhost;Port=5432;Database=****;Pooling=true;"
"ConnectionStrings": {
"MoongladeDatabase": "User ID=****;Password=****;Host=localhost;Port=5432;Database=****;Pooling=true;",
"DatabaseType": "PostgreSql"
}
```

### 🔨 Build Source
Expand All @@ -92,9 +82,9 @@ Build and run `./src/Moonglade.sln`

### 🛡 Authentication

#### [Azure Active Directory](https://azure.microsoft.com/en-us/services/active-directory/)
#### [Microsoft Entra ID](https://azure.microsoft.com/en-us/services/active-directory/)

See [Wiki document](https://github.com/EdiWang/Moonglade/wiki/Use-Azure-Active-Directory-Authentication)
See [Wiki document](https://github.com/EdiWang/Moonglade/wiki/Use-Microsoft-Entra-ID-Authentication)

#### Local Account (Alternative)

Expand Down Expand Up @@ -166,7 +156,7 @@ You can also choose File System for image storage if you don't have a cloud opti

### 📧 Email Notification

If you need email notification for new comments, new replies and pingbacks, you have to setup the [Moonglade.Notification Azure Function](https://github.com/EdiWang/Moonglade.Notification) first, and then enable notification in admin portal.
If you need email notification for new comments, new replies and pingbacks, you have to setup the [Moonglade.Email Azure Function](https://github.com/EdiWang/Moonglade.Email) first, and then enable notification in admin portal.

### 🔩 Others

Expand Down Expand Up @@ -202,5 +192,6 @@ There are a few individuals already setup thier blogs using Moonglade on Azure (
- [AllenMasters](https://allenmasters.com)
- [Hao's House](https://haxu.dev/)
- [Sascha.Manns](https://saschamanns.de/)
- [王高峰博客](https://blog.wanggaofeng.net)

*Just Submit PR or issue if you want your blog to be listed here*
6 changes: 3 additions & 3 deletions src/Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<Authors>Edi Wang</Authors>
<Company>edi.wang</Company>
<Copyright>(C) 2023 edi.wang@outlook.com</Copyright>
<AssemblyVersion>12.11.0.0</AssemblyVersion>
<FileVersion>12.11.0.0</FileVersion>
<Version>12.11.0</Version>
<AssemblyVersion>12.12.0.0</AssemblyVersion>
<FileVersion>12.12.0.0</FileVersion>
<Version>12.12.0</Version>
</PropertyGroup>
</Project>
2 changes: 1 addition & 1 deletion src/Moonglade.Auth/Moonglade.Auth.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<ItemGroup>
<FrameworkReference Include="Microsoft.AspNetCore.App" />

<PackageReference Include="Microsoft.Identity.Web" Version="2.11.1" />
<PackageReference Include="Microsoft.Identity.Web" Version="2.13.2" />
</ItemGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion src/Moonglade.Comments/GetApprovedCommentsQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,6 @@ public Task<IReadOnlyList<Comment>> Handle(GetApprovedCommentsQuery request, Can
ReplyContent = cr.ReplyContent,
ReplyTimeUtc = cr.CreateTimeUtc
}).ToList()
});
}, ct);
}
}
2 changes: 1 addition & 1 deletion src/Moonglade.Comments/GetCommentsQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public class GetCommentsQueryHandler : IRequestHandler<GetCommentsQuery, IReadOn
public Task<IReadOnlyList<CommentDetailedItem>> Handle(GetCommentsQuery request, CancellationToken ct)
{
var spec = new CommentSpec(request.PageSize, request.PageIndex);
var comments = _repo.SelectAsync(spec, CommentDetailedItem.EntitySelector);
var comments = _repo.SelectAsync(spec, CommentDetailedItem.EntitySelector, ct);

return comments;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@

namespace Moonglade.Comments.Moderators;

public class LocalWordFilterModerator : ICommentModerator
public class LocalModerator : ICommentModerator
{
private readonly IMaskWordFilter _filter;

public LocalWordFilterModerator(IBlogConfig blogConfig)
public LocalModerator(IBlogConfig blogConfig)
{
var sw = new StringWordSource(blogConfig.ContentSettings.DisharmonyWords);
_filter = new MaskWordFilter(sw);
Expand Down
2 changes: 1 addition & 1 deletion src/Moonglade.Comments/Moonglade.Comments.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<ItemGroup>
<PackageReference Include="Edi.WordFilter" Version="1.7.0" />
<PackageReference Include="Edi.Captcha" Version="3.15.0" />
<PackageReference Include="Edi.Captcha" Version="3.16.0" />
<PackageReference Include="Microsoft.Azure.CognitiveServices.ContentModerator" Version="2.0.0" />
</ItemGroup>

Expand Down
2 changes: 1 addition & 1 deletion src/Moonglade.Comments/ServiceCollectionExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public static IServiceCollection AddComments(this IServiceCollection services, I
}
else
{
services.AddScoped<ICommentModerator, LocalWordFilterModerator>();
services.AddScoped<ICommentModerator, LocalModerator>();
}

return services;
Expand Down
7 changes: 2 additions & 5 deletions src/Moonglade.Configuration/AdvancedSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,8 @@ public class AdvancedSettings : IBlogSettings
[MaxLength(1024)]
public string RobotsTxtContent { get; set; }

[Display(Name = "Enable Pingback send")]
public bool EnablePingbackSend { get; set; } = true;

[Display(Name = "Enable Pingback receive")]
public bool EnablePingbackReceive { get; set; } = true;
[Display(Name = "Enable Pingback")]
public bool EnablePingback { get; set; } = true;

[Display(Name = "Enable MetaWeblog API")]
public bool EnableMetaWeblog { get; set; } = true;
Expand Down
2 changes: 1 addition & 1 deletion src/Moonglade.Core/PostFeature/ListArchiveQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class ListArchiveQueryHandler : IRequestHandler<ListArchiveQuery, IReadOn
public Task<IReadOnlyList<PostDigest>> Handle(ListArchiveQuery request, CancellationToken ct)
{
var spec = new PostSpec(request.Year, request.Month.GetValueOrDefault());
var list = _repo.SelectAsync(spec, PostDigest.EntitySelector);
var list = _repo.SelectAsync(spec, PostDigest.EntitySelector, ct);
return list;
}
}
2 changes: 1 addition & 1 deletion src/Moonglade.Core/PostFeature/ListByTagQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ public Task<IReadOnlyList<PostDigest>> Handle(ListByTagQuery request, Cancellati
if (request.TagId <= 0) throw new ArgumentOutOfRangeException(nameof(request.TagId));
Helper.ValidatePagingParameters(request.PageSize, request.PageIndex);

var posts = _repo.SelectAsync(new PostTagSpec(request.TagId, request.PageSize, request.PageIndex), PostDigest.EntitySelectorByTag);
var posts = _repo.SelectAsync(new PostTagSpec(request.TagId, request.PageSize, request.PageIndex), PostDigest.EntitySelectorByTag, ct);
return posts;
}
}
2 changes: 1 addition & 1 deletion src/Moonglade.Core/PostFeature/ListFeaturedQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public Task<IReadOnlyList<PostDigest>> Handle(ListFeaturedQuery request, Cancell
var (pageSize, pageIndex) = request;
Helper.ValidatePagingParameters(pageSize, pageIndex);

var posts = _repo.SelectAsync(new FeaturedPostSpec(pageSize, pageIndex), PostDigest.EntitySelector);
var posts = _repo.SelectAsync(new FeaturedPostSpec(pageSize, pageIndex), PostDigest.EntitySelector, ct);
return posts;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ public class ListPostSegmentByStatusQueryHandler : IRequestHandler<ListPostSegme
public Task<IReadOnlyList<PostSegment>> Handle(ListPostSegmentByStatusQuery request, CancellationToken ct)
{
var spec = new PostSpec(request.Status);
return _repo.SelectAsync(spec, PostSegment.EntitySelector);
return _repo.SelectAsync(spec, PostSegment.EntitySelector, ct);
}
}
2 changes: 1 addition & 1 deletion src/Moonglade.Core/PostFeature/ListPostSegmentQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class ListPostSegmentQueryHandler : IRequestHandler<ListPostSegmentQuery,
}

var spec = new PostPagingSpec(request.PostStatus, request.Keyword, request.PageSize, request.Offset);
var posts = await _repo.SelectAsync(spec, PostSegment.EntitySelector);
var posts = await _repo.SelectAsync(spec, PostSegment.EntitySelector, ct);

Expression<Func<PostEntity, bool>> countExp = p => null == request.Keyword || p.Title.Contains(request.Keyword);

Expand Down
2 changes: 1 addition & 1 deletion src/Moonglade.Core/PostFeature/ListPostsQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ public Task<IReadOnlyList<PostDigest>> Handle(ListPostsQuery request, Cancellati
Helper.ValidatePagingParameters(request.PageSize, request.PageIndex);

var spec = new PostPagingSpec(request.PageSize, request.PageIndex, request.CatId, request.SortBy);
return _repo.SelectAsync(spec, PostDigest.EntitySelector);
return _repo.SelectAsync(spec, PostDigest.EntitySelector, ct);
}
}
2 changes: 0 additions & 2 deletions src/Moonglade.Core/PostFeature/PostEditModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ public class PostEditModel
[MaxLength(64)]
public string Author { get; set; }

[Required]
[MinLength(1)]
public Guid[] SelectedCatIds { get; set; }

[Required]
Expand Down
2 changes: 1 addition & 1 deletion src/Moonglade.Core/TagFeature/GetHotTagsQuery.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public async Task<IReadOnlyList<KeyValuePair<Tag, int>>> Handle(GetHotTagsQuery
Id = t.Id,
DisplayName = t.DisplayName,
NormalizedName = t.NormalizedName
}, t.Posts.Count));
}, t.Posts.Count), ct);

return tags;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="7.0.9" />
</ItemGroup>

<ItemGroup>
Expand Down
4 changes: 2 additions & 2 deletions src/Moonglade.Data/Infrastructure/DbContextRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ public async Task<IReadOnlyList<TResult>> SelectAsync<TResult>(Expression<Func<T
await DbContext.Set<T>().AsNoTracking().Select(selector).ToListAsync(cancellationToken: ct);

public async Task<IReadOnlyList<TResult>> SelectAsync<TResult>(
ISpecification<T> spec, Expression<Func<T, TResult>> selector) =>
await ApplySpecification(spec).AsNoTracking().Select(selector).ToListAsync();
ISpecification<T> spec, Expression<Func<T, TResult>> selector, CancellationToken ct = default) =>
await ApplySpecification(spec).AsNoTracking().Select(selector).ToListAsync(ct);

public Task<TResult> FirstOrDefaultAsync<TResult>(
ISpecification<T> spec, Expression<Func<T, TResult>> selector) =>
Expand Down
2 changes: 1 addition & 1 deletion src/Moonglade.Data/Infrastructure/IRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public interface IRepository<T> where T : class

Task<IReadOnlyList<TResult>> SelectAsync<TResult>(Expression<Func<T, TResult>> selector, CancellationToken ct = default);

Task<IReadOnlyList<TResult>> SelectAsync<TResult>(ISpecification<T> spec, Expression<Func<T, TResult>> selector);
Task<IReadOnlyList<TResult>> SelectAsync<TResult>(ISpecification<T> spec, Expression<Func<T, TResult>> selector, CancellationToken ct = default);

Task<TResult> FirstOrDefaultAsync<TResult>(ISpecification<T> spec, Expression<Func<T, TResult>> selector);

Expand Down
4 changes: 2 additions & 2 deletions src/Moonglade.Data/Moonglade.Data.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
<ItemGroup>
<Using Include="Microsoft.EntityFrameworkCore" />
<PackageReference Include="CsvHelper" Version="30.0.1" />
<PackageReference Include="MediatR" Version="12.0.1" />
<PackageReference Include="MediatR" Version="12.1.1" />
<FrameworkReference Include="Microsoft.AspNetCore.App" />

<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="7.0.7" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="7.0.9" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
using Azure.Storage.Queues;
using System.Text;
using System.Text.Json;
using Azure.Storage.Queues;
using Microsoft.Extensions.Logging;
using Moonglade.Configuration;
using Moonglade.Data.Exporting.Exporters;
using System.Text;
using System.Text.Json;

namespace Moonglade.Notification.Client;
namespace Moonglade.Email.Client;

public interface IBlogNotification
{
Task EnqueueNotification<T>(MailMesageTypes type, string[] toAddresses, T payload) where T : class;
Task Enqueue<T>(MailMesageTypes type, string[] receipts, T payload) where T : class;
}

public class BlogNotification : IBlogNotification
Expand All @@ -25,7 +25,7 @@ public BlogNotification(
_notificationSettings = blogConfig.NotificationSettings;
}

public async Task EnqueueNotification<T>(MailMesageTypes type, string[] toAddresses, T payload) where T : class
public async Task Enqueue<T>(MailMesageTypes type, string[] receipts, T payload) where T : class
{
if (!_notificationSettings.EnableEmailSending) return;

Expand All @@ -35,7 +35,7 @@ public async Task EnqueueNotification<T>(MailMesageTypes type, string[] toAddres

var en = new EmailNotification
{
DistributionList = string.Join(';', toAddresses),
DistributionList = string.Join(';', receipts),
MessageType = type.ToString(),
MessageBody = JsonSerializer.Serialize(payload, MoongladeJsonSerializerOptions.Default),
};
Expand All @@ -62,11 +62,4 @@ private async Task InsertMessageAsync(QueueClient queue, EmailNotification email

await queue.SendMessageAsync(base64Json);
}
}

internal class EmailNotification
{
public string DistributionList { get; set; }
public string MessageType { get; set; }
public string MessageBody { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
using Moonglade.Configuration;
using Moonglade.Utils;

namespace Moonglade.Notification.Client;
namespace Moonglade.Email.Client;

public record CommentNotification(
string Username,
Expand Down Expand Up @@ -40,6 +40,6 @@ public async Task Handle(CommentNotification notification, CancellationToken ct)
);

var dl = new[] { _blogConfig.GeneralSettings.OwnerEmail };
await _blogNotification.EnqueueNotification(MailMesageTypes.NewCommentNotification, dl, payload);
await _blogNotification.Enqueue(MailMesageTypes.NewCommentNotification, dl, payload);
}
}
Loading

0 comments on commit 6026cf0

Please sign in to comment.