♻️ I have no idea what am I doing. Might be mixing stuff
This commit is contained in:
40
DysonNetwork.Shared/Content/TextSanitizer.cs
Normal file
40
DysonNetwork.Shared/Content/TextSanitizer.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System.Text;
|
||||
using System.Globalization;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace DysonNetwork.Shared.Content;
|
||||
|
||||
public abstract partial class TextSanitizer
|
||||
{
|
||||
[GeneratedRegex(@"[\u0000-\u001F\u007F\u200B-\u200F\u202A-\u202E\u2060-\u206F\uFFF0-\uFFFF]")]
|
||||
private static partial Regex WeirdUnicodeRegex();
|
||||
|
||||
[GeneratedRegex(@"[\r\n]+")]
|
||||
private static partial Regex NewlineRegex();
|
||||
|
||||
public static string? Sanitize(string? text)
|
||||
{
|
||||
if (text is null) return null;
|
||||
|
||||
// Normalize weird Unicode characters
|
||||
var cleaned = WeirdUnicodeRegex().Replace(text, "");
|
||||
|
||||
// Normalize bold/italic/fancy unicode letters to ASCII
|
||||
cleaned = NormalizeFancyUnicode(cleaned);
|
||||
|
||||
// Replace multiple newlines with a single newline
|
||||
cleaned = NewlineRegex().Replace(cleaned, "\n");
|
||||
|
||||
return cleaned;
|
||||
}
|
||||
|
||||
private static string NormalizeFancyUnicode(string input)
|
||||
{
|
||||
var sb = new StringBuilder(input.Length);
|
||||
foreach (var c in input.Normalize(NormalizationForm.FormKC).Where(c =>
|
||||
char.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark))
|
||||
sb.Append(c);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
19
DysonNetwork.Shared/CultureService.cs
Normal file
19
DysonNetwork.Shared/CultureService.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System.Globalization;
|
||||
using DysonNetwork.Shared.Proto;
|
||||
|
||||
namespace DysonNetwork.Shared;
|
||||
|
||||
public static class CultureService
|
||||
{
|
||||
public static void SetCultureInfo(string? languageCode)
|
||||
{
|
||||
var info = new CultureInfo(languageCode ?? "en-us", false);
|
||||
CultureInfo.CurrentCulture = info;
|
||||
CultureInfo.CurrentUICulture = info;
|
||||
}
|
||||
|
||||
public static void SetCultureInfo(Account account)
|
||||
{
|
||||
SetCultureInfo(account.Language);
|
||||
}
|
||||
}
|
@@ -3,6 +3,23 @@ using Google.Protobuf.WellKnownTypes;
|
||||
|
||||
namespace DysonNetwork.Shared.Data;
|
||||
|
||||
public enum ContentSensitiveMark
|
||||
{
|
||||
Language,
|
||||
SexualContent,
|
||||
Violence,
|
||||
Profanity,
|
||||
HateSpeech,
|
||||
Racism,
|
||||
AdultContent,
|
||||
DrugAbuse,
|
||||
AlcoholAbuse,
|
||||
Gambling,
|
||||
SelfHarm,
|
||||
ChildAbuse,
|
||||
Other
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The class that used in jsonb columns which referenced the cloud file.
|
||||
/// The aim of this class is to store some properties that won't change to a file to reduce the database load.
|
||||
|
50
DysonNetwork.Shared/Data/VerificationMark.cs
Normal file
50
DysonNetwork.Shared/Data/VerificationMark.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace DysonNetwork.Shared.Data;
|
||||
|
||||
/// <summary>
|
||||
/// The verification info of a resource
|
||||
/// stands, for it is really an individual or organization or a company in the real world.
|
||||
/// Besides, it can also be use for mark parody or fake.
|
||||
/// </summary>
|
||||
public class VerificationMark
|
||||
{
|
||||
public VerificationMarkType Type { get; set; }
|
||||
[MaxLength(1024)] public string? Title { get; set; }
|
||||
[MaxLength(8192)] public string? Description { get; set; }
|
||||
[MaxLength(1024)] public string? VerifiedBy { get; set; }
|
||||
|
||||
public Shared.Proto.VerificationMark ToProtoValue()
|
||||
{
|
||||
var proto = new Shared.Proto.VerificationMark
|
||||
{
|
||||
Type = Type switch
|
||||
{
|
||||
VerificationMarkType.Official => Shared.Proto.VerificationMarkType.Official,
|
||||
VerificationMarkType.Individual => Shared.Proto.VerificationMarkType.Individual,
|
||||
VerificationMarkType.Organization => Shared.Proto.VerificationMarkType.Organization,
|
||||
VerificationMarkType.Government => Shared.Proto.VerificationMarkType.Government,
|
||||
VerificationMarkType.Creator => Shared.Proto.VerificationMarkType.Creator,
|
||||
VerificationMarkType.Developer => Shared.Proto.VerificationMarkType.Developer,
|
||||
VerificationMarkType.Parody => Shared.Proto.VerificationMarkType.Parody,
|
||||
_ => Shared.Proto.VerificationMarkType.Unspecified
|
||||
},
|
||||
Title = Title ?? string.Empty,
|
||||
Description = Description ?? string.Empty,
|
||||
VerifiedBy = VerifiedBy ?? string.Empty
|
||||
};
|
||||
|
||||
return proto;
|
||||
}
|
||||
}
|
||||
|
||||
public enum VerificationMarkType
|
||||
{
|
||||
Official,
|
||||
Individual,
|
||||
Organization,
|
||||
Government,
|
||||
Creator,
|
||||
Developer,
|
||||
Parody
|
||||
}
|
@@ -73,4 +73,28 @@ public static class GrpcClientHelper
|
||||
return new PusherService.PusherServiceClient(CreateCallInvoker(url, clientCertPath, clientKeyPath,
|
||||
clientCertPassword));
|
||||
}
|
||||
|
||||
public static async Task<FileService.FileServiceClient> CreateFileServiceClient(
|
||||
IEtcdClient etcdClient,
|
||||
string clientCertPath,
|
||||
string clientKeyPath,
|
||||
string? clientCertPassword = null
|
||||
)
|
||||
{
|
||||
var url = await GetServiceUrlFromEtcd(etcdClient, "DysonNetwork.File");
|
||||
return new FileService.FileServiceClient(CreateCallInvoker(url, clientCertPath, clientKeyPath,
|
||||
clientCertPassword));
|
||||
}
|
||||
|
||||
public static async Task<FileReferenceService.FileReferenceServiceClient> CreateFileReferenceServiceClient(
|
||||
IEtcdClient etcdClient,
|
||||
string clientCertPath,
|
||||
string clientKeyPath,
|
||||
string? clientCertPassword = null
|
||||
)
|
||||
{
|
||||
var url = await GetServiceUrlFromEtcd(etcdClient, "DysonNetwork.FileReference");
|
||||
return new FileReferenceService.FileReferenceServiceClient(CreateCallInvoker(url, clientCertPath, clientKeyPath,
|
||||
clientCertPassword));
|
||||
}
|
||||
}
|
@@ -20,7 +20,7 @@ message Account {
|
||||
string language = 4;
|
||||
google.protobuf.Timestamp activated_at = 5;
|
||||
bool is_superuser = 6;
|
||||
|
||||
|
||||
AccountProfile profile = 7;
|
||||
repeated AccountContact contacts = 8;
|
||||
repeated AccountBadge badges = 9;
|
||||
@@ -43,17 +43,17 @@ message AccountProfile {
|
||||
google.protobuf.StringValue location = 9;
|
||||
google.protobuf.Timestamp birthday = 10;
|
||||
google.protobuf.Timestamp last_seen_at = 11;
|
||||
|
||||
|
||||
VerificationMark verification = 12;
|
||||
BadgeReferenceObject active_badge = 13;
|
||||
|
||||
|
||||
int32 experience = 14;
|
||||
int32 level = 15;
|
||||
double leveling_progress = 16;
|
||||
|
||||
|
||||
CloudFile picture = 19;
|
||||
CloudFile background = 20;
|
||||
|
||||
|
||||
string account_id = 21;
|
||||
}
|
||||
|
||||
@@ -155,24 +155,15 @@ message BadgeReferenceObject {
|
||||
|
||||
// Relationship represents a connection between two accounts
|
||||
message Relationship {
|
||||
string id = 1;
|
||||
string from_account_id = 2;
|
||||
string to_account_id = 3;
|
||||
RelationshipType type = 4;
|
||||
string note = 5;
|
||||
string account_id = 1;
|
||||
string related_id = 2;
|
||||
optional Account account = 3;
|
||||
optional Account related = 4;
|
||||
int32 type = 5;
|
||||
google.protobuf.Timestamp created_at = 6;
|
||||
google.protobuf.Timestamp updated_at = 7;
|
||||
}
|
||||
|
||||
// Enum for relationship types
|
||||
enum RelationshipType {
|
||||
RELATIONSHIP_TYPE_UNSPECIFIED = 0;
|
||||
FRIEND = 1;
|
||||
BLOCKED = 2;
|
||||
PENDING_INCOMING = 3;
|
||||
PENDING_OUTGOING = 4;
|
||||
}
|
||||
|
||||
// Leveling information
|
||||
message LevelingInfo {
|
||||
int32 current_level = 1;
|
||||
@@ -192,43 +183,30 @@ service AccountService {
|
||||
// Account Operations
|
||||
rpc GetAccount(GetAccountRequest) returns (Account) {}
|
||||
rpc GetAccountBatch(GetAccountBatchRequest) returns (GetAccountBatchResponse) {}
|
||||
rpc CreateAccount(CreateAccountRequest) returns (Account) {}
|
||||
rpc UpdateAccount(UpdateAccountRequest) returns (Account) {}
|
||||
rpc DeleteAccount(DeleteAccountRequest) returns (google.protobuf.Empty) {}
|
||||
rpc ListAccounts(ListAccountsRequest) returns (ListAccountsResponse) {}
|
||||
|
||||
|
||||
// Profile Operations
|
||||
rpc GetProfile(GetProfileRequest) returns (AccountProfile) {}
|
||||
rpc UpdateProfile(UpdateProfileRequest) returns (AccountProfile) {}
|
||||
|
||||
|
||||
// Contact Operations
|
||||
rpc AddContact(AddContactRequest) returns (AccountContact) {}
|
||||
rpc UpdateContact(UpdateContactRequest) returns (AccountContact) {}
|
||||
rpc RemoveContact(RemoveContactRequest) returns (google.protobuf.Empty) {}
|
||||
rpc ListContacts(ListContactsRequest) returns (ListContactsResponse) {}
|
||||
rpc VerifyContact(VerifyContactRequest) returns (AccountContact) {}
|
||||
|
||||
|
||||
// Badge Operations
|
||||
rpc AddBadge(AddBadgeRequest) returns (AccountBadge) {}
|
||||
rpc RemoveBadge(RemoveBadgeRequest) returns (google.protobuf.Empty) {}
|
||||
rpc ListBadges(ListBadgesRequest) returns (ListBadgesResponse) {}
|
||||
rpc SetActiveBadge(SetActiveBadgeRequest) returns (AccountProfile) {}
|
||||
|
||||
|
||||
// Authentication Factor Operations
|
||||
rpc AddAuthFactor(AddAuthFactorRequest) returns (AccountAuthFactor) {}
|
||||
rpc RemoveAuthFactor(RemoveAuthFactorRequest) returns (google.protobuf.Empty) {}
|
||||
rpc ListAuthFactors(ListAuthFactorsRequest) returns (ListAuthFactorsResponse) {}
|
||||
|
||||
|
||||
// Connection Operations
|
||||
rpc AddConnection(AddConnectionRequest) returns (AccountConnection) {}
|
||||
rpc RemoveConnection(RemoveConnectionRequest) returns (google.protobuf.Empty) {}
|
||||
rpc ListConnections(ListConnectionsRequest) returns (ListConnectionsResponse) {}
|
||||
|
||||
|
||||
// Relationship Operations
|
||||
rpc CreateRelationship(CreateRelationshipRequest) returns (Relationship) {}
|
||||
rpc UpdateRelationship(UpdateRelationshipRequest) returns (Relationship) {}
|
||||
rpc DeleteRelationship(DeleteRelationshipRequest) returns (google.protobuf.Empty) {}
|
||||
rpc ListRelationships(ListRelationshipsRequest) returns (ListRelationshipsResponse) {}
|
||||
|
||||
rpc GetRelationship(GetRelationshipRequest) returns (GetRelationshipResponse) {}
|
||||
rpc HasRelationship(GetRelationshipRequest) returns (google.protobuf.BoolValue) {}
|
||||
rpc ListFriends(ListUserRelationshipSimpleRequest) returns (ListUserRelationshipSimpleResponse) {}
|
||||
rpc ListBlocked(ListUserRelationshipSimpleRequest) returns (ListUserRelationshipSimpleResponse) {}
|
||||
}
|
||||
|
||||
// ====================================
|
||||
@@ -301,18 +279,6 @@ message AddContactRequest {
|
||||
bool is_primary = 4; // If this should be the primary contact
|
||||
}
|
||||
|
||||
message UpdateContactRequest {
|
||||
string id = 1; // Contact ID to update
|
||||
string account_id = 2; // Account ID (for validation)
|
||||
google.protobuf.StringValue content = 3; // New contact content
|
||||
google.protobuf.BoolValue is_primary = 4; // New primary status
|
||||
}
|
||||
|
||||
message RemoveContactRequest {
|
||||
string id = 1; // Contact ID to remove
|
||||
string account_id = 2; // Account ID (for validation)
|
||||
}
|
||||
|
||||
message ListContactsRequest {
|
||||
string account_id = 1; // Account ID to list contacts for
|
||||
AccountContactType type = 2; // Optional: filter by type
|
||||
@@ -330,20 +296,6 @@ message VerifyContactRequest {
|
||||
}
|
||||
|
||||
// Badge Requests/Responses
|
||||
message AddBadgeRequest {
|
||||
string account_id = 1; // Account to add badge to
|
||||
string type = 2; // Type of badge
|
||||
google.protobuf.StringValue label = 3; // Display label
|
||||
google.protobuf.StringValue caption = 4; // Description
|
||||
map<string, string> meta = 5; // Additional metadata
|
||||
google.protobuf.Timestamp expired_at = 6; // Optional expiration
|
||||
}
|
||||
|
||||
message RemoveBadgeRequest {
|
||||
string id = 1; // Badge ID to remove
|
||||
string account_id = 2; // Account ID (for validation)
|
||||
}
|
||||
|
||||
message ListBadgesRequest {
|
||||
string account_id = 1; // Account to list badges for
|
||||
string type = 2; // Optional: filter by type
|
||||
@@ -354,26 +306,6 @@ message ListBadgesResponse {
|
||||
repeated AccountBadge badges = 1; // List of badges
|
||||
}
|
||||
|
||||
message SetActiveBadgeRequest {
|
||||
string account_id = 1; // Account to update
|
||||
string badge_id = 2; // Badge ID to set as active (empty to clear)
|
||||
}
|
||||
|
||||
// Authentication Factor Requests/Responses
|
||||
message AddAuthFactorRequest {
|
||||
string account_id = 1; // Account to add factor to
|
||||
AccountAuthFactorType type = 2; // Type of factor
|
||||
string secret = 3; // Factor secret (hashed on server)
|
||||
map<string, string> config = 4; // Configuration
|
||||
int32 trustworthy = 5; // Trust level
|
||||
google.protobuf.Timestamp expired_at = 6; // Optional expiration
|
||||
}
|
||||
|
||||
message RemoveAuthFactorRequest {
|
||||
string id = 1; // Factor ID to remove
|
||||
string account_id = 2; // Account ID (for validation)
|
||||
}
|
||||
|
||||
message ListAuthFactorsRequest {
|
||||
string account_id = 1; // Account to list factors for
|
||||
bool active_only = 2; // Only return active (non-expired) factors
|
||||
@@ -383,21 +315,6 @@ message ListAuthFactorsResponse {
|
||||
repeated AccountAuthFactor factors = 1; // List of auth factors
|
||||
}
|
||||
|
||||
// Connection Requests/Responses
|
||||
message AddConnectionRequest {
|
||||
string account_id = 1; // Account to add connection to
|
||||
string provider = 2; // Provider name (e.g., "google", "github")
|
||||
string provided_identifier = 3; // Provider's user ID
|
||||
map<string, string> meta = 4; // Additional metadata
|
||||
google.protobuf.StringValue access_token = 5; // OAuth access token
|
||||
google.protobuf.StringValue refresh_token = 6; // OAuth refresh token
|
||||
}
|
||||
|
||||
message RemoveConnectionRequest {
|
||||
string id = 1; // Connection ID to remove
|
||||
string account_id = 2; // Account ID (for validation)
|
||||
}
|
||||
|
||||
message ListConnectionsRequest {
|
||||
string account_id = 1; // Account to list connections for
|
||||
string provider = 2; // Optional: filter by provider
|
||||
@@ -408,30 +325,9 @@ message ListConnectionsResponse {
|
||||
}
|
||||
|
||||
// Relationship Requests/Responses
|
||||
message CreateRelationshipRequest {
|
||||
string from_account_id = 1; // Source account ID
|
||||
string to_account_id = 2; // Target account ID
|
||||
RelationshipType type = 3; // Type of relationship
|
||||
string note = 4; // Optional note
|
||||
}
|
||||
|
||||
message UpdateRelationshipRequest {
|
||||
string id = 1; // Relationship ID to update
|
||||
string account_id = 2; // Account ID (for validation)
|
||||
RelationshipType type = 3; // New relationship type
|
||||
google.protobuf.StringValue note = 4; // New note
|
||||
}
|
||||
|
||||
message DeleteRelationshipRequest {
|
||||
string id = 1; // Relationship ID to delete
|
||||
string account_id = 2; // Account ID (for validation)
|
||||
}
|
||||
|
||||
message ListRelationshipsRequest {
|
||||
string account_id = 1; // Account to list relationships for
|
||||
RelationshipType type = 2; // Optional: filter by type
|
||||
bool incoming = 3; // If true, list incoming relationships
|
||||
bool outgoing = 4; // If true, list outgoing relationships
|
||||
optional int32 status = 2; // Filter by status
|
||||
int32 page_size = 5; // Number of results per page
|
||||
string page_token = 6; // Token for pagination
|
||||
}
|
||||
@@ -442,3 +338,20 @@ message ListRelationshipsResponse {
|
||||
int32 total_size = 3; // Total number of relationships
|
||||
}
|
||||
|
||||
message GetRelationshipRequest {
|
||||
string account_id = 1;
|
||||
string related_id = 2;
|
||||
optional int32 status = 3;
|
||||
}
|
||||
|
||||
message GetRelationshipResponse {
|
||||
optional Relationship relationship = 1;
|
||||
}
|
||||
|
||||
message ListUserRelationshipSimpleRequest {
|
||||
string account_id = 1;
|
||||
}
|
||||
|
||||
message ListUserRelationshipSimpleResponse {
|
||||
repeated string accounts_id = 1;
|
||||
}
|
@@ -65,6 +65,9 @@ enum ChallengePlatform {
|
||||
|
||||
service AuthService {
|
||||
rpc Authenticate(AuthenticateRequest) returns (AuthenticateResponse) {}
|
||||
|
||||
rpc ValidatePin(ValidatePinRequest) returns (ValidateResponse) {}
|
||||
rpc ValidateCaptcha(ValidateCaptchaRequest) returns (ValidateResponse) {}
|
||||
}
|
||||
|
||||
message AuthenticateRequest {
|
||||
@@ -77,6 +80,19 @@ message AuthenticateResponse {
|
||||
optional AuthSession session = 3;
|
||||
}
|
||||
|
||||
message ValidatePinRequest {
|
||||
string account_id = 1;
|
||||
string pin = 2;
|
||||
}
|
||||
|
||||
message ValidateCaptchaRequest {
|
||||
string token = 1;
|
||||
}
|
||||
|
||||
message ValidateResponse {
|
||||
bool valid = 1;
|
||||
}
|
||||
|
||||
// Permission related messages and services
|
||||
message PermissionNode {
|
||||
string id = 1;
|
||||
|
@@ -51,6 +51,7 @@ message CloudFile {
|
||||
service FileService {
|
||||
// Get file reference by ID
|
||||
rpc GetFile(GetFileRequest) returns (CloudFile);
|
||||
rpc GetFileBatch(GetFileBatchRequest) returns (GetFileBatchResponse);
|
||||
|
||||
// Update an existing file reference
|
||||
rpc UpdateFile(UpdateFileRequest) returns (CloudFile);
|
||||
@@ -73,6 +74,14 @@ message GetFileRequest {
|
||||
string id = 1;
|
||||
}
|
||||
|
||||
message GetFileBatchRequest {
|
||||
repeated string ids = 1;
|
||||
}
|
||||
|
||||
message GetFileBatchResponse {
|
||||
repeated CloudFile files = 1;
|
||||
}
|
||||
|
||||
// Request message for UpdateFile
|
||||
message UpdateFileRequest {
|
||||
CloudFile file = 1;
|
||||
@@ -157,6 +166,18 @@ message CreateReferenceRequest {
|
||||
optional google.protobuf.Duration duration = 5; // Alternative to expired_at
|
||||
}
|
||||
|
||||
message CreateReferenceBatchRequest {
|
||||
repeated string files_id = 1;
|
||||
string usage = 2;
|
||||
string resource_id = 3;
|
||||
optional google.protobuf.Timestamp expired_at = 4;
|
||||
optional google.protobuf.Duration duration = 5; // Alternative to expired_at
|
||||
}
|
||||
|
||||
message CreateReferenceBatchResponse {
|
||||
repeated CloudFileReference references = 1;
|
||||
}
|
||||
|
||||
message GetReferencesRequest {
|
||||
string file_id = 1;
|
||||
}
|
||||
@@ -239,6 +260,7 @@ message HasFileReferencesResponse {
|
||||
service FileReferenceService {
|
||||
// Creates a new reference to a file for a specific resource
|
||||
rpc CreateReference(CreateReferenceRequest) returns (CloudFileReference);
|
||||
rpc CreateReferenceBatch(CreateReferenceBatchRequest) returns (CreateReferenceBatchResponse);
|
||||
|
||||
// Gets all references to a file
|
||||
rpc GetReferences(GetReferencesRequest) returns (GetReferencesResponse);
|
||||
|
@@ -44,4 +44,37 @@ public static class ServiceHelper
|
||||
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IServiceCollection AddDriveService(this IServiceCollection services)
|
||||
{
|
||||
services.AddSingleton<FileService.FileServiceClient>(sp =>
|
||||
{
|
||||
var etcdClient = sp.GetRequiredService<IEtcdClient>();
|
||||
var config = sp.GetRequiredService<IConfiguration>();
|
||||
var clientCertPath = config["Service:ClientCert"]!;
|
||||
var clientKeyPath = config["Service:ClientKey"]!;
|
||||
var clientCertPassword = config["Service:CertPassword"];
|
||||
|
||||
return GrpcClientHelper
|
||||
.CreateFileServiceClient(etcdClient, clientCertPath, clientKeyPath, clientCertPassword)
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
});
|
||||
|
||||
services.AddSingleton<FileReferenceService.FileReferenceServiceClient>(sp =>
|
||||
{
|
||||
var etcdClient = sp.GetRequiredService<IEtcdClient>();
|
||||
var config = sp.GetRequiredService<IConfiguration>();
|
||||
var clientCertPath = config["Service:ClientCert"]!;
|
||||
var clientKeyPath = config["Service:ClientKey"]!;
|
||||
var clientCertPassword = config["Service:CertPassword"];
|
||||
|
||||
return GrpcClientHelper
|
||||
.CreateFileReferenceServiceClient(etcdClient, clientCertPath, clientKeyPath, clientCertPassword)
|
||||
.GetAwaiter()
|
||||
.GetResult();
|
||||
});
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user