Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Reworking NanoBlog #52

Merged
merged 1 commit into from
Oct 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 0 additions & 25 deletions .dockerignore

This file was deleted.

5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@ _ReSharper.Caches/
.DS_Store
.vscode/
*.Dot[sS]ettings.user
global.json
global.json
blog-files/
blog-export/
docker/data/*
25 changes: 10 additions & 15 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,15 @@ MIT License

Copyright (c) 2022-2024 Niklas Schmidt

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the Software without restriction, including without limitation the
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit
persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the
Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Original file line number Diff line number Diff line change
Expand Up @@ -113,8 +113,8 @@ private static ResourceExecutingContext BuildContext(string? authenticationToken
RouteData = new RouteData(),
ActionDescriptor = new ActionDescriptor()
},
new List<IFilterMetadata>(),
new List<IValueProviderFactory>()
[],
[]
);

return actionExecutedContext;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
using NanoBlog.Containers;

namespace NanoBlog.Test.Services.MimeTypes.MimeTypeProvider;

public class ProvideMimeTypeAsyncByFileName
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
using NanoBlog.Containers;
using NanoBlog.Extensions;

namespace NanoBlog.Test.Services.MimeTypes.MimeTypeProvider;

public class ProvideMimeTypeAsyncByFormFile
Expand Down Expand Up @@ -108,7 +105,7 @@ private static IFormFile BuildFormFile(string fileName, string? mimeType)
headers[HeaderNames.ContentType] = new StringValues(mimeType);
}

return new FormFile(new MemoryStream(Array.Empty<byte>()), 0, 0, fileName, fileName)
return new FormFile(new MemoryStream([]), 0, 0, fileName, fileName)
{
Headers = headers
};
Expand Down
3 changes: 2 additions & 1 deletion NanoBlog.Test/Usings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
global using Microsoft.AspNetCore.Mvc;
global using Microsoft.AspNetCore.Mvc.Abstractions;
global using Microsoft.AspNetCore.Mvc.Filters;
global using Microsoft.AspNetCore.Mvc.ModelBinding;
global using Microsoft.AspNetCore.Routing;
global using Microsoft.Extensions.Primitives;
global using Microsoft.Net.Http.Headers;
global using NanoBlog.Containers;
global using NanoBlog.Extensions;
global using System.Text;
global using Xunit;
3 changes: 3 additions & 0 deletions NanoBlog/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
bin
obj
*.Development.json
6 changes: 3 additions & 3 deletions NanoBlog/Attributes/AuthenticationActionFilter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ namespace NanoBlog.Attributes;

public class AuthenticationActionFilter(string configuredAuthenticationToken) : IResourceFilter
{
private const string _AUTHENTICATION_HEADER_BEARER_PREFIX = "Bearer ";
private const string AuthenticationHeaderBearerPrefix = "Bearer ";

public void OnResourceExecuting(ResourceExecutingContext context)
{
Expand All @@ -13,13 +13,13 @@ public void OnResourceExecuting(ResourceExecutingContext context)
return;
}

if (!token.StartsWith(_AUTHENTICATION_HEADER_BEARER_PREFIX, StringComparison.InvariantCultureIgnoreCase))
if (!token.StartsWith(AuthenticationHeaderBearerPrefix, StringComparison.InvariantCultureIgnoreCase))
{
context.Result = new UnauthorizedResult();
return;
}

var givenAuthenticationToken = token[_AUTHENTICATION_HEADER_BEARER_PREFIX.Length..].Trim();
var givenAuthenticationToken = token[AuthenticationHeaderBearerPrefix.Length..].Trim();

if (string.IsNullOrEmpty(givenAuthenticationToken))
{
Expand Down
6 changes: 3 additions & 3 deletions NanoBlog/Attributes/FileNameValidationAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class All() : ValidFileName(AllRegex());
[GeneratedRegex(@"^[A-Za-z0-9\-]+\.(png|jpg|jpeg|gif|svg|txt|html)")]
private static partial Regex AllRegex();

private const int _MAX_FILE_LENGTH = 100;
private const int MaxFileLength = 100;
private readonly Regex _validFileNameRegex;

private ValidFileName(Regex validFileNameRegex)
Expand All @@ -33,9 +33,9 @@ private ValidFileName(Regex validFileNameRegex)
return new ValidationResult($"Attributed value is not of type {typeof(string)}");
}

if (fileName.Length > _MAX_FILE_LENGTH)
if (fileName.Length > MaxFileLength)
{
return new ValidationResult($"File name exceeded max length ({_MAX_FILE_LENGTH}).");
return new ValidationResult($"File name exceeded max length ({MaxFileLength}).");
}

return _validFileNameRegex.IsMatch(fileName)
Expand Down
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
79 changes: 57 additions & 22 deletions NanoBlog/Configuration.cs
Original file line number Diff line number Diff line change
@@ -1,40 +1,75 @@
// ReSharper disable AutoPropertyCanBeMadeGetOnly.Global
// ReSharper disable MemberCanBePrivate.Global

namespace NanoBlog;

public class Configuration : IConfiguration
{
public bool UsePagination { get; init; } = IConfiguration.DEFAULT_USE_PAGINATION;
public int PageSize { get; init; } = IConfiguration.DEFAULT_PAGE_SIZE;
public string Language { get; init; } = IConfiguration.DEFAULT_LANGUAGE;
public string BlogRootServerDirectory { get; init; } = IConfiguration.DEFAULT_BLOG_ROOT_SERVER_DIRECTORY;
public ICollection<string> ExportKeepFileNames { get; } = new List<string>();
public string PagePlaceholderPosts { get; init; } = string.Empty;
public string PagePlaceholderNavigation { get; init; } = string.Empty;
public string PostPlaceholderContent { get; init; } = string.Empty;
public string PostPlaceholderName { get; init; } = string.Empty;

public static DirectoryInfo GetStageAssetsDirectoryInfo()
public bool UsePagination { get; init; } = false;
public string PageTemplate { get; init; } = string.Empty;
public string PostTemplate { get; init; } = string.Empty;
public int? PageSize { get; init; } = null;

public string PostDirectory { get; init; } = string.Empty;
public string AssetDirectory { get; init; } = string.Empty;

public string ExportDirectory { get; init; } = string.Empty;

public ICollection<string> KeepExportFiles { get; init; } = [];

public DirectoryInfo GetAssetsDirectoryInfo()
{
EnsureNotEmpty(AssetDirectory);
return EnsureExisting(Path.Combine(Directory.GetCurrentDirectory(), AssetDirectory));
}

public DirectoryInfo GetPostsDirectoryInfo()
{
EnsureNotEmpty(PostDirectory);
return EnsureExisting(Path.Combine(Directory.GetCurrentDirectory(), PostDirectory));
}

public DirectoryInfo GetExportDirectoryInfo()
{
EnsureNotEmpty(ExportDirectory);
return EnsureExisting(Path.Combine(Directory.GetCurrentDirectory(), ExportDirectory));
}

public DirectoryInfo GetExportAssetsDirectoryInfo()
{
return new DirectoryInfo(
Path.Combine(Directory.GetCurrentDirectory(), IConfiguration.STAGE_ASSETS_DIRECTORY_NAME)
);
EnsureNotEmpty(ExportDirectory);
return EnsureExisting(Path.Combine(Directory.GetCurrentDirectory(), ExportDirectory, "assets"));
}

public static DirectoryInfo GetStagePostsDirectoryInfo()
public DirectoryInfo GetExportArchiveDirectoryInfo()
{
return new DirectoryInfo(
Path.Combine(Directory.GetCurrentDirectory(), IConfiguration.STAGE_POSTS_DIRECTORY_NAME)
);
EnsureNotEmpty(ExportDirectory);
return EnsureExisting(Path.Combine(Directory.GetCurrentDirectory(), ExportDirectory, "archive"));
}

public static DirectoryInfo GetStageStructureDirectoryInfo()
private static DirectoryInfo EnsureExisting(string path)
{
return new DirectoryInfo(
Path.Combine(Directory.GetCurrentDirectory(), IConfiguration.STAGE_STRUCTURE_DIRECTORY_NAME)
);
var directoryInfo = new DirectoryInfo(path);

if (!directoryInfo.Exists)
{
directoryInfo.Create();
}

return directoryInfo.EnsureSecureMode();
}

public static DirectoryInfo GetExportDirectoryInfo()
private static void EnsureNotEmpty(string path)
{
return new DirectoryInfo(
Path.Combine(Directory.GetCurrentDirectory(), IConfiguration.EXPORT_DIRECTORY_NAME)
);
if (!string.IsNullOrWhiteSpace(path))
{
return;
}

throw new Exception("Path not configured");
}
}
6 changes: 0 additions & 6 deletions NanoBlog/Containers/GeneratedPageContentsContainer.cs

This file was deleted.

9 changes: 0 additions & 9 deletions NanoBlog/Containers/IStageDirectoryContainer.cs

This file was deleted.

3 changes: 1 addition & 2 deletions NanoBlog/Containers/PostExcerpt.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@ namespace NanoBlog.Containers;

public record PostExcerpt(
string Name,
string Excerpt
);
string Excerpt);
26 changes: 0 additions & 26 deletions NanoBlog/Containers/StageDirectoryContainer.cs

This file was deleted.

15 changes: 0 additions & 15 deletions NanoBlog/Containers/StageFilesContentContainer.cs

This file was deleted.

Loading
Loading