aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcrupest <crupest@outlook.com>2022-12-02 18:43:17 +0800
committercrupest <crupest@outlook.com>2022-12-20 20:32:52 +0800
commit691a23f5f8b7f58a23d8dea841d3576b047b5336 (patch)
tree4c20ee1fb813898d31220eeb18ee9973c4ad9e77
parent608caf10276a8ebccf1a5c4497e71e2157c3340b (diff)
downloadcrupest-691a23f5f8b7f58a23d8dea841d3576b047b5336.tar.gz
crupest-691a23f5f8b7f58a23d8dea841d3576b047b5336.tar.bz2
crupest-691a23f5f8b7f58a23d8dea841d3576b047b5336.zip
Develop secret api.
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi.Commons/Config.cs23
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi.Files/CrupestApi.Files.csproj5
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi.Secrets/CrupestApi.Secrets.csproj5
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi.Secrets/SecretsService.cs109
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosService.cs5
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosServiceCollectionExtensions.cs3
-rw-r--r--docker/crupest-api/CrupestApi/CrupestApi/Program.cs2
-rw-r--r--template/crupest-api-config.json.template12
8 files changed, 152 insertions, 12 deletions
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Commons/Config.cs b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Config.cs
new file mode 100644
index 0000000..0ca3547
--- /dev/null
+++ b/docker/crupest-api/CrupestApi/CrupestApi.Commons/Config.cs
@@ -0,0 +1,23 @@
+namespace CrupestApi.Commons;
+
+public class CrupestApiConfig
+{
+ public string DataDir { get; set; } = string.Empty;
+}
+
+public static class CrupestApiConfigExtensions
+{
+ public static IServiceCollection AddCrupestApiConfig(this IServiceCollection services)
+ {
+ services.AddOptions<CrupestApiConfig>().BindConfiguration("CrupestApi");
+ services.PostConfigure<CrupestApiConfig>(config =>
+ {
+ if (config.DataDir is null || config.DataDir.Length == 0)
+ {
+ config.DataDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "crupest-api");
+ }
+ });
+
+ return services;
+ }
+} \ No newline at end of file
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Files/CrupestApi.Files.csproj b/docker/crupest-api/CrupestApi/CrupestApi.Files/CrupestApi.Files.csproj
index 86460e3..2221809 100644
--- a/docker/crupest-api/CrupestApi/CrupestApi.Files/CrupestApi.Files.csproj
+++ b/docker/crupest-api/CrupestApi/CrupestApi.Files/CrupestApi.Files.csproj
@@ -4,6 +4,11 @@
<ProjectReference Include="..\CrupestApi.Commons\CrupestApi.Commons.csproj" />
</ItemGroup>
+ <ItemGroup>
+ <PackageReference Include="Dapper" Version="2.0.123" />
+ <PackageReference Include="Microsoft.Data.Sqlite" Version="7.0.0" />
+ </ItemGroup>
+
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetType>library</TargetType>
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Secrets/CrupestApi.Secrets.csproj b/docker/crupest-api/CrupestApi/CrupestApi.Secrets/CrupestApi.Secrets.csproj
index 86460e3..70c83f3 100644
--- a/docker/crupest-api/CrupestApi/CrupestApi.Secrets/CrupestApi.Secrets.csproj
+++ b/docker/crupest-api/CrupestApi/CrupestApi.Secrets/CrupestApi.Secrets.csproj
@@ -4,6 +4,11 @@
<ProjectReference Include="..\CrupestApi.Commons\CrupestApi.Commons.csproj" />
</ItemGroup>
+ <ItemGroup>
+ <PackageReference Include="Dapper" Version="2.0.123" />
+ <PackageReference Include="Microsoft.Data.Sqlite" Version="7.0.0" />
+ </ItemGroup>
+
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<TargetType>library</TargetType>
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Secrets/SecretsService.cs b/docker/crupest-api/CrupestApi/CrupestApi.Secrets/SecretsService.cs
new file mode 100644
index 0000000..3913a0b
--- /dev/null
+++ b/docker/crupest-api/CrupestApi/CrupestApi.Secrets/SecretsService.cs
@@ -0,0 +1,109 @@
+using CrupestApi.Commons;
+using Dapper;
+using Microsoft.Data.Sqlite;
+using Microsoft.Extensions.Options;
+
+namespace CrupestApi.Secrets;
+
+public class SecretsService : ISecretsService
+{
+ private readonly IOptionsSnapshot<CrupestApiConfig> _crupestApiConfig;
+ private readonly ILogger<SecretsService> _logger;
+
+ public SecretsService(IOptionsSnapshot<CrupestApiConfig> crupestApiConfig, ILogger<SecretsService> logger)
+ {
+ _crupestApiConfig = crupestApiConfig;
+ _logger = logger;
+ }
+
+ private string GetDatabasePath()
+ {
+ return Path.Combine(_crupestApiConfig.Value.DataDir, "secrets.db");
+ }
+
+ private async Task<SqliteConnection> EnsureDatabase()
+ {
+ var dataSource = GetDatabasePath();
+ var connectionStringBuilder = new SqliteConnectionStringBuilder()
+ {
+ DataSource = dataSource
+ };
+
+ if (!File.Exists(dataSource))
+ {
+ _logger.LogInformation("Data source {0} does not exist. Create one.", dataSource);
+ connectionStringBuilder.Mode = SqliteOpenMode.ReadWriteCreate;
+ var connectionString = connectionStringBuilder.ToString();
+ var connection = new SqliteConnection(connectionString);
+ var transaction = await connection.BeginTransactionAsync();
+
+ connection.Execute(@"
+CREATE TABLE secrets (
+ Id INTEGER PRIMARY KEY AUTOINCREMENT,
+ Key TEXT NOT NULL,
+ Secret TEXT NOT NULL,
+ Description TEXT NOT NULL,
+ ExpireTime TEXT,
+ Revoked INTEGER NOT NULL,
+ CreateTime TEXT NOT NULL
+);
+
+CREATE INDEX secrets_key ON secrets (key);
+
+INSERT INTO secrets (Key, Secret, Description, ExpireTime, Revoked, CreateTime) VALUES (@SecretManagementKey, 'crupest', 'This is the default secret management key.', NULL, 0, @CreateTime);
+ ",
+ new
+ {
+ SecretManagementKey = SecretsConstants.SecretManagementKey,
+ CreateTime = DateTime.Now.ToString("O"),
+ });
+
+ await transaction.CommitAsync();
+
+ _logger.LogInformation("{0} created with 'crupest' as the default secret management value. Please immediate revoke it and create a new one.", dataSource);
+ return connection;
+ }
+ else
+ {
+ _logger.LogInformation("Data source {0} already exists. Will use it.");
+ connectionStringBuilder.Mode = SqliteOpenMode.ReadWrite;
+ var connectionString = connectionStringBuilder.ToString();
+ return new SqliteConnection(connectionString);
+ }
+ }
+
+ public Task<SecretInfo> CreateSecretAsync(string key, string description, DateTime? expireTime = null)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<List<SecretInfo>> GetSecretListAsync(bool includeExpired = false, bool includeRevoked = false)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<List<SecretInfo>> GetSecretListByKeyAsync(string key, bool includeExpired = false, bool includeRevoked = false)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<SecretInfo> ModifySecretAsync(string secret, SecretModifyRequest modifyRequest)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task RevokeSecretAsync(string secret)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task<bool> VerifySecretAsync(string key, string secret)
+ {
+ throw new NotImplementedException();
+ }
+
+ public Task VerifySecretForHttpRequestAsync(HttpRequest request, string key, string queryKey = "secret")
+ {
+ throw new NotImplementedException();
+ }
+}
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosService.cs b/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosService.cs
index f5ccc09..ac20af2 100644
--- a/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosService.cs
+++ b/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosService.cs
@@ -1,12 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Net.Http;
using System.Net.Http.Headers;
using System.Net.Mime;
using System.Text;
using System.Text.Json;
-using System.Threading.Tasks;
-using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
namespace CrupestApi.Todos;
diff --git a/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosServiceCollectionExtensions.cs b/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosServiceCollectionExtensions.cs
index cdf174d..5041094 100644
--- a/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosServiceCollectionExtensions.cs
+++ b/docker/crupest-api/CrupestApi/CrupestApi.Todos/TodosServiceCollectionExtensions.cs
@@ -1,4 +1,3 @@
-using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
namespace CrupestApi.Todos;
@@ -7,7 +6,7 @@ public static class TodosServiceCollectionExtensions
{
public static IServiceCollection AddTodos(this IServiceCollection services)
{
- services.AddOptions<TodosConfiguration>().BindConfiguration("Todos");
+ services.AddOptions<TodosConfiguration>().BindConfiguration("CrupestApi.Todos");
services.PostConfigure<TodosConfiguration>(config =>
{
if (config.Count == 0)
diff --git a/docker/crupest-api/CrupestApi/CrupestApi/Program.cs b/docker/crupest-api/CrupestApi/CrupestApi/Program.cs
index ff8f02f..be72617 100644
--- a/docker/crupest-api/CrupestApi/CrupestApi/Program.cs
+++ b/docker/crupest-api/CrupestApi/CrupestApi/Program.cs
@@ -8,6 +8,8 @@ string configFilePath = Environment.GetEnvironmentVariable("CRUPEST_API_CONFIG_F
builder.Configuration.AddJsonFile(configFilePath, optional: false, reloadOnChange: true);
builder.Services.AddJsonOptions();
+builder.Services.AddCrupestApiConfig();
+
builder.Services.AddTodos();
var app = builder.Build();
diff --git a/template/crupest-api-config.json.template b/template/crupest-api-config.json.template
index fc5eb85..65a7944 100644
--- a/template/crupest-api-config.json.template
+++ b/template/crupest-api-config.json.template
@@ -1,8 +1,10 @@
{
- "Todos": {
- "Username": "$CRUPEST_GITHUB_USERNAME",
- "ProjectNumber": "$CRUPEST_GITHUB_PROJECT_NUMBER",
- "Token": "$CRUPEST_GITHUB_TOKEN",
- "Count": "$CRUPEST_GITHUB_TODO_COUNT"
+ "CrupestApi": {
+ "Todos": {
+ "Username": "$CRUPEST_GITHUB_USERNAME",
+ "ProjectNumber": "$CRUPEST_GITHUB_PROJECT_NUMBER",
+ "Token": "$CRUPEST_GITHUB_TOKEN",
+ "Count": "$CRUPEST_GITHUB_TODO_COUNT"
+ }
}
}