REORG
This commit is contained in:
parent
8d68ee380a
commit
45514010f2
3505 changed files with 154 additions and 523 deletions
5
src/Server/.config/dotnet-tools.json
Normal file
5
src/Server/.config/dotnet-tools.json
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"version": 1,
|
||||
"isRoot": true,
|
||||
"tools": {}
|
||||
}
|
||||
12
src/Server/ChatUserFlags.cs
Normal file
12
src/Server/ChatUserFlags.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
namespace Yavsc
|
||||
{
|
||||
/// <summary>
|
||||
/// Chat User Flags
|
||||
/// </summary>
|
||||
public enum ChatUserFlags : byte
|
||||
{
|
||||
away = 1,
|
||||
invisible = 2,
|
||||
cop = 4
|
||||
}
|
||||
}
|
||||
89
src/Server/Config.cs
Normal file
89
src/Server/Config.cs
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
|
||||
using IdentityServer8;
|
||||
using IdentityServer8.Models;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Yavsc.Settings;
|
||||
|
||||
namespace Yavsc;
|
||||
|
||||
public static class Config
|
||||
{
|
||||
public static string? Authority { get; set; }
|
||||
|
||||
public static IConfigurationRoot? GoogleWebClientConfiguration { get; set; }
|
||||
public static GoogleServiceAccount? GServiceAccount { get; set; }
|
||||
|
||||
public static SiteSettings SiteSetup { get; set; } = new SiteSettings();
|
||||
public static FileServerOptions? UserFilesOptions { get; set; }
|
||||
public static FileServerOptions? GitOptions { get; set; }
|
||||
public static string AvatarsDirName { set; get; } = "Avatars";
|
||||
public static string GitDirName { set; get; } = "Git";
|
||||
|
||||
public static GoogleAuthSettings? GoogleSettings { get; set; }
|
||||
public static SmtpSettings? SmtpSetup { get; set; }
|
||||
public static string? Temp { get; set; }
|
||||
public static FileServerOptions? AvatarsOptions { get; set; }
|
||||
public static string UserBillsDirName { set; get; } = "Bills";
|
||||
public static string UserFilesDirName { set; get; } = "Files";
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Lists Available user profile classes,
|
||||
/// populated at startup, using reflection.
|
||||
/// </summary>
|
||||
public static List<Type> ProfileTypes = new List<Type>();
|
||||
|
||||
|
||||
public static IEnumerable<IdentityResource> IdentityResources =>
|
||||
[
|
||||
new IdentityResources.OpenId(),
|
||||
new IdentityResources.Profile(),
|
||||
new IdentityResources.Email()
|
||||
];
|
||||
|
||||
public static IEnumerable<ApiScope> ApiScopes =>
|
||||
[
|
||||
new ApiScope("scope1",new string[] {"scope1"}),
|
||||
new ApiScope("scope2",new string[] {"scope2"}),
|
||||
];
|
||||
|
||||
public static IEnumerable<Client> Clients =>
|
||||
[
|
||||
// m2m client credentials flow client
|
||||
new Client
|
||||
{
|
||||
ClientId = "m2m.client",
|
||||
ClientName = "Client Credentials Client",
|
||||
ClientSecrets = { new Secret("511536EF-F270-4058-80CA-1C89C192F69A".Sha256()) },
|
||||
|
||||
AllowedGrantTypes = GrantTypes.ResourceOwnerPasswordAndClientCredentials,
|
||||
AllowedScopes = { "scope1" }
|
||||
},
|
||||
|
||||
// interactive client using code flow + pkce
|
||||
new Client
|
||||
{
|
||||
ClientId = "mvc",
|
||||
ClientSecrets = { new Secret("49C1A7E1-0C79-4A89-A3D6-A37998FB86B0".Sha256()) },
|
||||
|
||||
AllowedGrantTypes = GrantTypes.Code,
|
||||
AlwaysIncludeUserClaimsInIdToken = true,
|
||||
|
||||
RedirectUris = { "https://localhost:5003/signin-oidc",
|
||||
"http://localhost:5002/signin-oidc" },
|
||||
PostLogoutRedirectUris = { "https://localhost:5003/signout-callback-oidc",
|
||||
"http://localhost:5002/signout-callback-oidc" },
|
||||
|
||||
AllowedScopes = {
|
||||
IdentityServerConstants.StandardScopes.OpenId,
|
||||
IdentityServerConstants.StandardScopes.Profile,
|
||||
IdentityServerConstants.StandardScopes.Email,
|
||||
IdentityServerConstants.StandardScopes.OfflineAccess,
|
||||
"scope2" },
|
||||
},
|
||||
];
|
||||
|
||||
public static PayPalSettings? PayPalSettings { get; set; }
|
||||
}
|
||||
17
src/Server/Constants.cs
Normal file
17
src/Server/Constants.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
namespace Yavsc.Server
|
||||
{
|
||||
|
||||
public static class ServerConstants
|
||||
{
|
||||
|
||||
public const string ApplicationName = "Yavsc";
|
||||
public const string CompanyInfoUrl = " https://societeinfo.com/app/rest/api/v1/company/json?registration_number={0}&key={1}";
|
||||
|
||||
|
||||
private static readonly string[] GoogleScopes = { "openid", "profile", "email" };
|
||||
public static readonly string[] GoogleCalendarScopes =
|
||||
{ "openid", "profile", "email", "https://www.googleapis.com/auth/calendar" };
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
17
src/Server/Exceptions/AuthorizationFailureException.cs
Normal file
17
src/Server/Exceptions/AuthorizationFailureException.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
namespace Yavsc.Server.Exceptions;
|
||||
|
||||
[Serializable]
|
||||
public class AuthorizationFailureException : Exception
|
||||
{
|
||||
public AuthorizationFailureException(Microsoft.AspNetCore.Authorization.AuthorizationResult auth) : base(auth?.Failure?.ToString()??auth?.ToString()??"AuthorizationResult failure")
|
||||
{
|
||||
}
|
||||
|
||||
public AuthorizationFailureException(string? message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public AuthorizationFailureException(string? message, Exception? innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
15
src/Server/Exceptions/InvalidActivityModelException.cs
Normal file
15
src/Server/Exceptions/InvalidActivityModelException.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
namespace Yavsc.Exceptions
|
||||
{
|
||||
public class InvalidWorkflowModelException : Exception
|
||||
{
|
||||
public InvalidWorkflowModelException(string descr) : base(descr)
|
||||
{
|
||||
|
||||
}
|
||||
public InvalidWorkflowModelException(string descr, Exception inner) : base(descr,inner)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
9
src/Server/Exceptions/InvalidPathException.cs
Normal file
9
src/Server/Exceptions/InvalidPathException.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
using System;
|
||||
|
||||
namespace Yavsc.Exceptions
|
||||
{
|
||||
public class InvalidPathException: Exception
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
18
src/Server/Exceptions/YavscInfrastructureException.cs
Normal file
18
src/Server/Exceptions/YavscInfrastructureException.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
namespace Yavsc.Services
|
||||
{
|
||||
[Serializable]
|
||||
internal class YavscInfrastructureException : Exception
|
||||
{
|
||||
public YavscInfrastructureException()
|
||||
{
|
||||
}
|
||||
|
||||
public YavscInfrastructureException(string? message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public YavscInfrastructureException(string? message, Exception? innerException) : base(message, innerException)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
29
src/Server/Helpers/BillingHelpers.cs
Normal file
29
src/Server/Helpers/BillingHelpers.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
using System.Globalization;
|
||||
using Yavsc.Billing;
|
||||
using Yavsc.Models.Billing;
|
||||
using Yavsc.Server.Helpers;
|
||||
using Yavsc.Services;
|
||||
|
||||
namespace Yavsc.Helpers
|
||||
{
|
||||
public static class BillingHelpers
|
||||
{
|
||||
public static decimal Addition(this List<IBillItem> items) => items.Aggregate<IBillItem, decimal>(0m, (t, l) => t + l.Count * l.UnitaryCost);
|
||||
|
||||
public static decimal Addition(this List<CommandLine> items) => items.Select(i=>((IBillItem)i)).ToList().Addition();
|
||||
|
||||
public static string GetBillText(this IBillable query) {
|
||||
string total = query.GetBillItems().Addition().ToString("C", CultureInfo.CurrentUICulture);
|
||||
string bill = string.Join("\n", query.GetBillItems().Select(l=> $"{l.Name} {l.Description} : {l.UnitaryCost} € " + ((l.Count != 1) ? "*"+l.Count.ToString() : ""))) +
|
||||
$"\n\nTotal: {total}";
|
||||
return bill;
|
||||
}
|
||||
|
||||
public static FileInfo GetBillInfo(this IBillable bill, IBillingService service)
|
||||
{
|
||||
var suffix = bill.GetIsAcquitted() ? "-ack":null;
|
||||
var filename = bill.GetFileBaseName(service)+".pdf";
|
||||
return new FileInfo(Path.Combine(AbstractFileSystemHelpers.UserBillsDirName, filename));
|
||||
}
|
||||
}
|
||||
}
|
||||
23
src/Server/Helpers/CompanyInfoHelpers.cs
Normal file
23
src/Server/Helpers/CompanyInfoHelpers.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Yavsc.Helpers
|
||||
{
|
||||
using Models.societe.com;
|
||||
using Yavsc.Server;
|
||||
|
||||
public static class ComapnyInfoHelpers {
|
||||
public static async Task<CompanyInfoMessage> CheckSiren(this HttpClient web,
|
||||
string siren, CompanyInfoSettings api)
|
||||
{
|
||||
using (var request = new HttpRequestMessage(HttpMethod.Get,
|
||||
string.Format(ServerConstants.CompanyInfoUrl,siren,api.ApiKey))) {
|
||||
using (var response = await web.SendAsync(request)) {
|
||||
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
|
||||
return payload.ToObject<CompanyInfoMessage>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
262
src/Server/Helpers/FileSystemHelpers.cs
Normal file
262
src/Server/Helpers/FileSystemHelpers.cs
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
|
||||
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNetCore.Html;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.FileSystem;
|
||||
using Yavsc.Models.Streaming;
|
||||
using Yavsc.ViewModels;
|
||||
using SixLabors.ImageSharp;
|
||||
using SixLabors.ImageSharp.Processing;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Yavsc.Exceptions;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Abstract.Helpers;
|
||||
namespace Yavsc.Server.Helpers
|
||||
{
|
||||
public static class FileSystemHelpers
|
||||
{
|
||||
public static async Task SaveAsAsync(this IFormFile formFile, string path)
|
||||
{
|
||||
if (formFile.Length > 0) {
|
||||
using (Stream fileStream = new FileStream(path, FileMode.Create)) {
|
||||
await formFile.CopyToAsync(fileStream);
|
||||
}
|
||||
}
|
||||
}
|
||||
public static FileReceivedInfo ReceiveProSignature(this ClaimsPrincipal user, string billingCode, long estimateId, IFormFile formFile, string signType)
|
||||
{
|
||||
var item = new FileReceivedInfo(
|
||||
Config.SiteSetup.Bills,
|
||||
AbstractFileSystemHelpers.SignFileNameFormat("pro", billingCode, estimateId));
|
||||
|
||||
var fi = new FileInfo(item.FullName);
|
||||
if (fi.Exists) item.Overridden = true;
|
||||
|
||||
using (var org = formFile.OpenReadStream())
|
||||
{
|
||||
using Image image = Image.Load(org);
|
||||
image.Save(fi.FullName);
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
public static string GetAvatarUri(this ApplicationUser user)
|
||||
{
|
||||
return $"/{Config.SiteSetup.Avatars}/{user.UserName}.png";
|
||||
}
|
||||
|
||||
public static string EnsureDestinationDirectory(
|
||||
this ClaimsPrincipal user,
|
||||
string subpath)
|
||||
{
|
||||
var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.Identity.Name);
|
||||
if (!string.IsNullOrWhiteSpace(subpath))
|
||||
{
|
||||
if (!subpath.IsValidYavscPath())
|
||||
{
|
||||
throw new InvalidPathException();
|
||||
}
|
||||
root = Path.Combine(root, subpath);
|
||||
}
|
||||
var di = new DirectoryInfo(root);
|
||||
if (!di.Exists) di.Create();
|
||||
return di.FullName;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes user file.
|
||||
/// User info is modified, but not save in db.
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="fileName"></param>
|
||||
|
||||
public static void DeleteUserFile(this ApplicationUser user, string fileName)
|
||||
{
|
||||
var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName);
|
||||
var fi = new FileInfo(Path.Combine(root, fileName));
|
||||
if (!fi.Exists) return ;
|
||||
fi.Delete();
|
||||
user.DiskUsage -= fi.Length;
|
||||
}
|
||||
|
||||
public static FsOperationInfo DeleteUserDirOrFile(this ApplicationUser user, string dirName)
|
||||
{
|
||||
var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName);
|
||||
if (string.IsNullOrEmpty(dirName))
|
||||
return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest, ErrorMessage = "specify a directory or file name"} ;
|
||||
|
||||
var di = new DirectoryInfo(Path.Combine(root, dirName));
|
||||
if (!di.Exists) {
|
||||
var fi = new FileInfo(Path.Combine(root, dirName));
|
||||
if (!fi.Exists) return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.NotFound, ErrorMessage = "non existent"} ;
|
||||
fi.Delete();
|
||||
user.DiskUsage -= fi.Length;
|
||||
}
|
||||
else {
|
||||
if (di.GetDirectories().Length>0 || di.GetFiles().Length>0)
|
||||
return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest, ErrorMessage = "dir is not empty, refusing to remove it"} ;
|
||||
di.Delete();
|
||||
}
|
||||
return new FsOperationInfo { Done = true };
|
||||
}
|
||||
|
||||
public static FsOperationInfo MoveUserDir(this ApplicationUser user, string fromDirName, string toDirName)
|
||||
{
|
||||
var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName);
|
||||
if (string.IsNullOrEmpty(fromDirName))
|
||||
return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest , ErrorMessage = "specify a dir name "} ;
|
||||
|
||||
var di = new DirectoryInfo(Path.Combine(root, fromDirName));
|
||||
if (!di.Exists) return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.NotFound, ErrorMessage = "fromDirName: non existent"} ;
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(toDirName)) toDirName = ".";
|
||||
var destPath = Path.Combine(root, toDirName);
|
||||
|
||||
|
||||
var fout = new FileInfo(destPath);
|
||||
if (fout.Exists) return new FsOperationInfo { Done = false, ErrorCode = ErrorCode.InvalidRequest, ErrorMessage = "destination is a regular file" } ;
|
||||
|
||||
|
||||
var dout = new DirectoryInfo(destPath);
|
||||
if (dout.Exists) {
|
||||
destPath = Path.Combine(destPath, dout.Name);
|
||||
}
|
||||
di.MoveTo(destPath);
|
||||
return new FsOperationInfo { Done = true };
|
||||
}
|
||||
public static FsOperationInfo MoveUserFileToDir(this ApplicationUser user, string fileNameFrom, string fileNameDest)
|
||||
{
|
||||
var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName);
|
||||
var fi = new FileInfo(Path.Combine(root, fileNameFrom));
|
||||
if (!fi.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.NotFound, ErrorMessage = "no file to move" } ;
|
||||
string dest;
|
||||
if (!string.IsNullOrEmpty(fileNameDest)) dest = Path.Combine(root, fileNameDest);
|
||||
else dest = root;
|
||||
var fo = new FileInfo(dest);
|
||||
if (fo.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.DestExists , ErrorMessage = "destination file name is an existing file" } ;
|
||||
var dout = new DirectoryInfo(dest);
|
||||
if (!dout.Exists) dout.Create();
|
||||
fi.MoveTo(Path.Combine(dout.FullName, fi.Name));
|
||||
return new FsOperationInfo { Done = true };
|
||||
}
|
||||
public static FsOperationInfo MoveUserFile(this ApplicationUser user, string fileNameFrom, string fileNameDest)
|
||||
{
|
||||
var root = Path.Combine(AbstractFileSystemHelpers.UserFilesDirName, user.UserName);
|
||||
var fi = new FileInfo(Path.Combine(root, fileNameFrom));
|
||||
if (!fi.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.NotFound, ErrorMessage = "no file to move" } ;
|
||||
var fo = new FileInfo(Path.Combine(root, fileNameDest));
|
||||
if (fo.Exists) return new FsOperationInfo { ErrorCode = ErrorCode.DestExists , ErrorMessage = "destination file name is an existing file" } ;
|
||||
fi.MoveTo(fo.FullName);
|
||||
return new FsOperationInfo { Done = true };
|
||||
}
|
||||
|
||||
static string ParseFileNameFromDisposition(string disposition)
|
||||
{
|
||||
// form-data_ name=_file__ filename=_Constants.Private.cs_
|
||||
var parts = disposition.Split(' ');
|
||||
var filename = parts[2].Split('=')[1];
|
||||
filename = filename.Substring(1,filename.Length-2);
|
||||
return filename;
|
||||
}
|
||||
|
||||
public static void AddQuota(this ApplicationUser user, int quota)
|
||||
{
|
||||
user.DiskQuota += quota;
|
||||
}
|
||||
public static FileReceivedInfo ReceiveUserFile(this ApplicationUser user, string root, IFormFile f, string destFileName = null)
|
||||
{
|
||||
return ReceiveUserFile(user, root, f.OpenReadStream(), destFileName ?? ParseFileNameFromDisposition(f.ContentDisposition), f.ContentType, CancellationToken.None);
|
||||
}
|
||||
|
||||
public static FileReceivedInfo ReceiveUserFile(this ApplicationUser user, string root, Stream inputStream, string destFileName, string contentType, CancellationToken token)
|
||||
{
|
||||
// TODO lock user's disk usage for this scope,
|
||||
// this process is not safe at concurrent access.
|
||||
long usage = user.DiskUsage;
|
||||
|
||||
var item = new FileReceivedInfo
|
||||
(root, AbstractFileSystemHelpers.FilterFileName(destFileName));
|
||||
var fi = new FileInfo(Path.Combine(root, item.FileName));
|
||||
if (fi.Exists)
|
||||
{
|
||||
item.Overridden = true;
|
||||
usage -= fi.Length;
|
||||
}
|
||||
using (var dest = fi.OpenWrite())
|
||||
{
|
||||
using (inputStream)
|
||||
{
|
||||
const int blen = 1024;
|
||||
byte[] buffer = new byte[blen];
|
||||
int len = 0;
|
||||
while (!token.IsCancellationRequested && (len=inputStream.Read(buffer, 0, blen))>0)
|
||||
{
|
||||
dest.Write(buffer, 0, len);
|
||||
usage += len;
|
||||
if (usage >= user.DiskQuota) break;
|
||||
}
|
||||
user.DiskUsage = usage;
|
||||
dest.Close();
|
||||
inputStream.Close();
|
||||
}
|
||||
}
|
||||
if (usage >= user.DiskQuota) {
|
||||
item.QuotaOffense = true;
|
||||
}
|
||||
user.DiskUsage = usage;
|
||||
return item;
|
||||
}
|
||||
|
||||
public static HtmlString FileLink(this RemoteFileInfo info, string username, string subpath)
|
||||
{
|
||||
return new HtmlString(
|
||||
$"{Config.UserFilesOptions.RequestPath}/{username}/{subpath}/{info.Name}" );
|
||||
}
|
||||
|
||||
public static RemoteFileInfo FileInfo(this ApplicationUser user, string path)
|
||||
{
|
||||
IFileInfo info = Config.UserFilesOptions.FileProvider.GetFileInfo($"{user.UserName}/{path}");
|
||||
if (!info.Exists) return null;
|
||||
return new RemoteFileInfo{ Name = info.Name, Size = info.Length, LastModified = info.LastModified.UtcDateTime };
|
||||
|
||||
}
|
||||
|
||||
public static FileReceivedInfo ReceiveAvatar(this ApplicationUser user, IFormFile formFile)
|
||||
{
|
||||
var item = new FileReceivedInfo
|
||||
(Config.AvatarsOptions.RequestPath.ToUriComponent(),
|
||||
user.UserName + ".png");
|
||||
using (var org = formFile.OpenReadStream())
|
||||
{
|
||||
using Image image = Image.Load(org);
|
||||
image.Mutate(x=>x.Resize(128,128));
|
||||
image.Save(Path.Combine(Config.SiteSetup.Avatars,item.FileName));
|
||||
image.Mutate(x=>x.Resize(64,64));
|
||||
image.Save(Path.Combine(Config.SiteSetup.Avatars,user.UserName + ".s.png"));
|
||||
image.Mutate(x=>x.Resize(32,32));
|
||||
image.Save(Path.Combine(Config.SiteSetup.Avatars,user.UserName + ".xs.png"));
|
||||
}
|
||||
user.Avatar = $"{item.DestDir}/{item.FileName}";
|
||||
return item;
|
||||
}
|
||||
|
||||
public static string GetFileUrl (this LiveFlow flow)
|
||||
{
|
||||
// no server-side backup for this stream
|
||||
return $"{Config.UserFilesOptions.RequestPath}/{flow.Owner.UserName}/live/"+GetFileName(flow);
|
||||
}
|
||||
|
||||
public static string GetFileName (this LiveFlow flow)
|
||||
{
|
||||
var fileInfo = new FileInfo(flow.DifferedFileName);
|
||||
var ext = fileInfo.Extension;
|
||||
var namelen = flow.DifferedFileName.Length - ext.Length;
|
||||
var basename = flow.DifferedFileName.Substring(0,namelen);
|
||||
return $"{basename}-{flow.SequenceNumber}{ext}";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
21
src/Server/Helpers/HtmlHelpers.cs
Normal file
21
src/Server/Helpers/HtmlHelpers.cs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
using Microsoft.AspNetCore.Html;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Yavsc.Models.Drawing;
|
||||
|
||||
namespace Yavsc.Helpers
|
||||
{
|
||||
public static class HtmlHelpers
|
||||
{
|
||||
public static HtmlString Color(this Color c)
|
||||
{
|
||||
if (c == null) return new HtmlString("#000");
|
||||
return new HtmlString(String.Format("#{0:X2}{1:X2}{2:X2}", c.Red, c.Green, c.Blue));
|
||||
}
|
||||
public static string ToAbsolute(this HttpRequest request, string url)
|
||||
{
|
||||
var host = request.Host;
|
||||
var isSecure = request.Headers[Constants.SshHeaderKey] == "on";
|
||||
return (isSecure ? "https" : "http") + $"://{host}/{url}";
|
||||
}
|
||||
}
|
||||
}
|
||||
175
src/Server/Helpers/PayPalHelpers.cs
Normal file
175
src/Server/Helpers/PayPalHelpers.cs
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Yavsc.Models.Billing;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using PayPal.PayPalAPIInterfaceService.Model;
|
||||
using PayPal.PayPalAPIInterfaceService;
|
||||
using Yavsc.ViewModels.PayPal;
|
||||
using Yavsc.Models;
|
||||
using System.Linq;
|
||||
using Yavsc.Models.Payment;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Yavsc.Helpers
|
||||
{
|
||||
public static class PayPalHelpers
|
||||
{
|
||||
private static Dictionary<string,string> payPalProperties = null;
|
||||
public static Dictionary<string,string> GetPayPalProperties() {
|
||||
if (payPalProperties==null) {
|
||||
|
||||
payPalProperties = new Dictionary<string,string>();
|
||||
var paypalSettings = Config.PayPalSettings;
|
||||
// Don't do:
|
||||
// payPalProperties.Add("mode", Startup.PayPalSettings.Mode);
|
||||
// Instead, set the endpoint parameter.
|
||||
if (paypalSettings.Mode == "production") {
|
||||
// use nvp end point: https://api-3t.paypal.com/nvp
|
||||
payPalProperties.Add("endpoint", "https://api-3t.paypal.com/nvp");
|
||||
|
||||
} else {
|
||||
payPalProperties.Add("endpoint", "https://api-3t.sandbox.paypal.com/nvp");
|
||||
}
|
||||
payPalProperties.Add("clientId", paypalSettings.ClientId);
|
||||
payPalProperties.Add("clientSecret", paypalSettings.ClientSecret);
|
||||
|
||||
int numClient = 0;
|
||||
if (paypalSettings.Accounts!=null)
|
||||
foreach (var account in paypalSettings.Accounts) {
|
||||
numClient++;
|
||||
payPalProperties.Add ($"account{numClient}.apiUsername",account.ApiUsername);
|
||||
payPalProperties.Add ($"account{numClient}.apiPassword",account.ApiPassword);
|
||||
payPalProperties.Add ($"account{numClient}.apiSignature",account.Signature);
|
||||
}
|
||||
}
|
||||
return payPalProperties;
|
||||
}
|
||||
private static PayPalAPIInterfaceServiceService payPalService = null;
|
||||
public static PayPalAPIInterfaceServiceService PayPalService {
|
||||
get {
|
||||
if (payPalService==null)
|
||||
payPalService = new PayPal.PayPalAPIInterfaceService.PayPalAPIInterfaceServiceService(GetPayPalProperties());
|
||||
return payPalService;
|
||||
}}
|
||||
|
||||
public class PaymentUrls
|
||||
{
|
||||
public string ReturnUrl { get; set; }
|
||||
public string CancelUrl { get; set; }
|
||||
public string CGVUrl { get; set; }
|
||||
}
|
||||
public static PaymentUrls GetPaymentUrls(this HttpRequest request, string controllerName, string id)
|
||||
{
|
||||
var result = new PaymentUrls
|
||||
{
|
||||
ReturnUrl = request.ToAbsolute($"{controllerName}/PaymentConfirmation/{id}"),
|
||||
CancelUrl = request.ToAbsolute($"{controllerName}/ClientCancel/{id}"),
|
||||
CGVUrl = request.ToAbsolute($"{controllerName}/CGV")
|
||||
};
|
||||
return result;
|
||||
}
|
||||
public static SetExpressCheckoutResponseType CreatePayment(this HttpRequest request, string controllerName, NominativeServiceCommand query, string intent = "sale", ILogger logger = null)
|
||||
{
|
||||
var items = query.GetBillItems();
|
||||
var total = items.Addition().ToString("F2");
|
||||
var coreq = new SetExpressCheckoutReq {};
|
||||
var urls = request.GetPaymentUrls(controllerName, query.Id.ToString());
|
||||
|
||||
var pitem = new PaymentDetailsItemType {};
|
||||
coreq.SetExpressCheckoutRequest = new SetExpressCheckoutRequestType{
|
||||
DetailLevel = new List<DetailLevelCodeType?> { DetailLevelCodeType.RETURNALL },
|
||||
SetExpressCheckoutRequestDetails = new SetExpressCheckoutRequestDetailsType
|
||||
{
|
||||
PaymentDetails = new List<PaymentDetailsType>( new [] { new PaymentDetailsType{
|
||||
OrderDescription = query.Description,
|
||||
OrderTotal = new BasicAmountType {
|
||||
currencyID = CurrencyCodeType.EUR,
|
||||
value = total
|
||||
},
|
||||
PaymentDetailsItem = new List <PaymentDetailsItemType> (
|
||||
items.Select(i => new PaymentDetailsItemType {
|
||||
Amount = new BasicAmountType { currencyID = CurrencyCodeType.EUR, value = i.UnitaryCost.ToString("F2") },
|
||||
Name = i.Name,
|
||||
Quantity = i.Count,
|
||||
Description = i.Description
|
||||
})
|
||||
)
|
||||
}}),
|
||||
InvoiceID = query.GetInvoiceId(),
|
||||
// NOTE don't set OrderDescription : "You cannot pass both the new and deprecated order description.","ErrorCode":"11804
|
||||
CancelURL = urls.CancelUrl,
|
||||
ReturnURL = urls.ReturnUrl
|
||||
}
|
||||
};
|
||||
|
||||
var d = new SetExpressCheckoutRequestDetailsType();
|
||||
|
||||
logger.LogInformation($"Creating express checkout for {Config.PayPalSettings.MerchantAccountUserName} : "+JsonConvert.SerializeObject(coreq));
|
||||
var response = PayPalService.SetExpressCheckout( coreq, Config.PayPalSettings.MerchantAccountUserName );
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
public static async Task<PaymentInfo> GetCheckoutInfo(
|
||||
this ApplicationDbContext context,
|
||||
string token)
|
||||
{
|
||||
return await CreatePaymentViewModel(context,token,GetExpressCheckoutDetails(token));
|
||||
}
|
||||
private static GetExpressCheckoutDetailsResponseType GetExpressCheckoutDetails(string token)
|
||||
{
|
||||
GetExpressCheckoutDetailsReq req = new GetExpressCheckoutDetailsReq{
|
||||
GetExpressCheckoutDetailsRequest = new GetExpressCheckoutDetailsRequestType {
|
||||
Token = token
|
||||
}
|
||||
};
|
||||
return PayPalService.GetExpressCheckoutDetails(req,Config.PayPalSettings.Accounts[0].ApiUsername);
|
||||
}
|
||||
public static async Task<PaymentInfo> ConfirmPayment(
|
||||
this ApplicationDbContext context,
|
||||
string userId,
|
||||
string payerId,
|
||||
string token)
|
||||
{
|
||||
var details = GetExpressCheckoutDetails(token);
|
||||
var payment = await context.PayPalPayment.SingleOrDefaultAsync(p=>p.CreationToken == token);
|
||||
if (payment == null)
|
||||
{
|
||||
payment = new PayPalPayment{
|
||||
ExecutorId = userId,
|
||||
PaypalPayerId = payerId,
|
||||
CreationToken = token,
|
||||
// NOTE: 1 order <=> 1 bill <=> 1 payment
|
||||
OrderReference = details.GetExpressCheckoutDetailsResponseDetails.InvoiceID,
|
||||
State = details.Ack.ToString()
|
||||
};
|
||||
|
||||
context.PayPalPayment.Add(payment);
|
||||
}
|
||||
else {
|
||||
payment.ExecutorId = userId;
|
||||
payment.PaypalPayerId = payerId;
|
||||
payment.State = details.Ack.ToString();
|
||||
}
|
||||
await context.SaveChangesAsync(userId);
|
||||
// GetCheckoutInfo(,token);
|
||||
return new PaymentInfo { DbContent = payment, DetailsFromPayPal = details };
|
||||
}
|
||||
public static async Task<PaymentInfo> CreatePaymentViewModel (
|
||||
this ApplicationDbContext context,
|
||||
string token, GetExpressCheckoutDetailsResponseType fromPayPal)
|
||||
{
|
||||
return new PaymentInfo {
|
||||
DbContent = await context.PayPalPayment
|
||||
.Include(p=>p.Executor)
|
||||
.SingleOrDefaultAsync(
|
||||
p=>p.CreationToken==token),
|
||||
DetailsFromPayPal = fromPayPal
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
139
src/Server/Helpers/RequestHelper.cs
Normal file
139
src/Server/Helpers/RequestHelper.cs
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
using Yavsc.Server.Model;
|
||||
|
||||
namespace Yavsc.Server.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Thanks to Stefan @ Stackoverflow
|
||||
/// </summary>
|
||||
public class RequestHelper
|
||||
{
|
||||
string WRPostMultipart(string url, Dictionary<string, object> parameters, string authorizationHeader = null)
|
||||
{
|
||||
|
||||
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
|
||||
byte[] boundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
|
||||
|
||||
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
|
||||
request.ContentType = "multipart/form-data; boundary=" + boundary;
|
||||
request.Method = "POST";
|
||||
request.KeepAlive = true;
|
||||
request.Credentials = System.Net.CredentialCache.DefaultCredentials;
|
||||
if (authorizationHeader != null)
|
||||
request.Headers["Authorization"] = authorizationHeader;
|
||||
if (parameters != null && parameters.Count > 0)
|
||||
{
|
||||
|
||||
using (Stream requestStream = request.GetRequestStream())
|
||||
{
|
||||
using (WebResponse response = request.GetResponse())
|
||||
{
|
||||
|
||||
|
||||
foreach (KeyValuePair<string, object> pair in parameters)
|
||||
{
|
||||
|
||||
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
|
||||
if (pair.Value is FormFile)
|
||||
{
|
||||
FormFile file = pair.Value as FormFile;
|
||||
string header = "Content-Disposition: form-data; name=\"" + pair.Key + "\"; filename=\"" + file.Name + "\"\r\nContent-Type: " + file.ContentType + "\r\n\r\n";
|
||||
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(header);
|
||||
requestStream.Write(bytes, 0, bytes.Length);
|
||||
byte[] buffer = new byte[32768];
|
||||
int bytesRead;
|
||||
if (file.Stream == null)
|
||||
{
|
||||
// upload from file
|
||||
using (FileStream fileStream = File.OpenRead(file.FilePath))
|
||||
{
|
||||
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
|
||||
requestStream.Write(buffer, 0, bytesRead);
|
||||
fileStream.Close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// upload from given stream
|
||||
while ((bytesRead = file.Stream.Read(buffer, 0, buffer.Length)) != 0)
|
||||
requestStream.Write(buffer, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
string data = "Content-Disposition: form-data; name=\"" + pair.Key + "\"\r\n\r\n" + pair.Value;
|
||||
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(data);
|
||||
requestStream.Write(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
|
||||
requestStream.Write(trailer, 0, trailer.Length);
|
||||
requestStream.Close();
|
||||
|
||||
using (Stream responseStream = response.GetResponseStream())
|
||||
using (StreamReader reader = new StreamReader(responseStream))
|
||||
{
|
||||
return reader.ReadToEnd();
|
||||
}
|
||||
} // end WebResponse response
|
||||
|
||||
} // end using requestStream
|
||||
|
||||
}
|
||||
else throw new ArgumentOutOfRangeException("no parameter found ");
|
||||
|
||||
}
|
||||
|
||||
public static async Task<string> PostMultipart(string url, FormFile[] formFiles, string access_token = null)
|
||||
{
|
||||
|
||||
if (formFiles != null && formFiles.Length > 0)
|
||||
{
|
||||
var client = new HttpClient();
|
||||
var formData = new MultipartFormDataContent();
|
||||
|
||||
if (access_token != null)
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", access_token);
|
||||
foreach (var formFile in formFiles)
|
||||
{
|
||||
HttpContent fileStreamContent = new StreamContent(formFile.Stream);
|
||||
if (formFile.ContentType!=null)
|
||||
fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue(formFile.ContentType);
|
||||
else fileStreamContent.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
|
||||
|
||||
// fileStreamContent.Headers.ContentDisposition = formFile.ContentDisposition!=null? new ContentDispositionHeaderValue(
|
||||
// formFile.ContentDisposition) : new ContentDispositionHeaderValue("form-data; name=\"file\"; filename=\"" + formFile.Name + "\"");
|
||||
fileStreamContent.Headers.Add("Content-Disposition", formFile.ContentDisposition);
|
||||
fileStreamContent.Headers.Add("Content-Length", formFile.Stream.Length.ToString());
|
||||
|
||||
//fileStreamContent.Headers.Add("FilePath", formFile.FilePath);
|
||||
|
||||
formData.Add(fileStreamContent, "file", formFile.Name);
|
||||
|
||||
}
|
||||
|
||||
var response = client.PostAsync(url, formData).Result;
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return await response.Content.ReadAsStringAsync();
|
||||
} // end if formFiles != null
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
6
src/Server/Helpers/ResourcesHelpers.cs
Normal file
6
src/Server/Helpers/ResourcesHelpers.cs
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
using Microsoft.Extensions.Localization;
|
||||
|
||||
public static class ResourcesHelpers {
|
||||
public static IStringLocalizer GlobalLocalizer = null ;
|
||||
|
||||
}
|
||||
82
src/Server/Helpers/SimpleJsonPostMethod.cs
Normal file
82
src/Server/Helpers/SimpleJsonPostMethod.cs
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
//
|
||||
// PostJson.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
using System.Net;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
namespace Yavsc.Server.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple json post method.
|
||||
/// </summary>
|
||||
public class SimpleJsonPostMethod : IDisposable
|
||||
{
|
||||
private readonly HttpWebRequest request=null;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the Yavsc.Helpers.SimpleJsonPostMethod class.
|
||||
/// </summary>
|
||||
/// <param name="pathToMethod">Path to method.</param>
|
||||
public SimpleJsonPostMethod (string pathToMethod, string authorizationHeader = null, string method = "POST")
|
||||
{
|
||||
request = (HttpWebRequest) WebRequest.Create (pathToMethod);
|
||||
request.Method = method;
|
||||
request.Accept = "application/json";
|
||||
request.ContentType = "application/json";
|
||||
request.SendChunked = true;
|
||||
request.TransferEncoding = "UTF-8";
|
||||
if (authorizationHeader!=null)
|
||||
request.Headers["Authorization"]=authorizationHeader;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
request.Abort();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invoke the specified query.
|
||||
/// </summary>
|
||||
/// <param name="query">Query.</param>
|
||||
public async Task<TAnswer> Invoke<TAnswer>(object query)
|
||||
{
|
||||
|
||||
using (Stream streamQuery = await request.GetRequestStreamAsync()) {
|
||||
using (StreamWriter writer = new StreamWriter(streamQuery)) {
|
||||
writer.Write (JsonConvert.SerializeObject(query));
|
||||
}}
|
||||
TAnswer ans = default (TAnswer);
|
||||
using (WebResponse response = await request.GetResponseAsync ()) {
|
||||
using (Stream responseStream = response.GetResponseStream ()) {
|
||||
using (StreamReader rdr = new StreamReader (responseStream)) {
|
||||
ans = (TAnswer) JsonConvert.DeserializeObject<TAnswer> (rdr.ReadToEnd ());
|
||||
}
|
||||
}
|
||||
response.Close();
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
28
src/Server/Helpers/UserHelpers.cs
Normal file
28
src/Server/Helpers/UserHelpers.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
using System.Security.Claims;
|
||||
|
||||
namespace Yavsc.Server.Helpers
|
||||
{
|
||||
public static class UserHelpers
|
||||
{
|
||||
public static string GetUserId(this ClaimsPrincipal user)
|
||||
{
|
||||
return user.FindFirstValue("sub");
|
||||
}
|
||||
|
||||
public static string GetUserName(this ClaimsPrincipal user)
|
||||
{
|
||||
return user.FindFirstValue("name");
|
||||
}
|
||||
|
||||
public static bool IsSignedIn(this ClaimsPrincipal user)
|
||||
{
|
||||
return user.Identity.IsAuthenticated;
|
||||
}
|
||||
|
||||
public static bool IsInMsRole(this ClaimsPrincipal user, string roleName)
|
||||
{
|
||||
return user.HasClaim("http://schemas.microsoft.com/ws/2008/06/identity/claims/role", roleName);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
95
src/Server/Helpers/WorkflowHelpers.cs
Normal file
95
src/Server/Helpers/WorkflowHelpers.cs
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
|
||||
|
||||
namespace Yavsc.Helpers
|
||||
{
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Yavsc.Abstract.Workflow;
|
||||
using Yavsc.Billing;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Billing;
|
||||
using Yavsc.Models.Haircut;
|
||||
using Yavsc.Models.Workflow;
|
||||
using Yavsc.Services;
|
||||
using Yavsc.ViewModels.FrontOffice;
|
||||
|
||||
public static class WorkflowHelpers
|
||||
{
|
||||
public static async Task<List<PerformerProfileViewModel>>
|
||||
ListPerformersAsync(this ApplicationDbContext context,
|
||||
IBillingService billing,
|
||||
string actCode)
|
||||
{
|
||||
|
||||
var actors = context.Performers
|
||||
.Include(p => p.Activity)
|
||||
.Include(p => p.Performer)
|
||||
.Where(p => p.Active && p.Activity.Any(u => u.DoesCode == actCode)).OrderBy(x => x.Rate)
|
||||
.ToArray();
|
||||
|
||||
List<PerformerProfileViewModel> result = new();
|
||||
foreach (var a in actors)
|
||||
{
|
||||
var settings = await billing.GetPerformersSettingsAsync(actCode, a.PerformerId);
|
||||
result.Add(new PerformerProfileViewModel(a, actCode, settings));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void RegisterBilling<T>(string code, Func<ApplicationDbContext, long,
|
||||
IDecidableQuery> getter) where T : IBillable
|
||||
{
|
||||
if (BillingService.Billing.ContainsKey(code)
|
||||
|| BillingService.GlobalBillingMap.ContainsKey(code))
|
||||
{
|
||||
throw new InvalidOperationException("Billing setup");
|
||||
}
|
||||
BillingService.Billing.Add(code, getter);
|
||||
BillingService.GlobalBillingMap.Add(typeof(T).Name, code);
|
||||
}
|
||||
|
||||
public static void ConfigureBillingService()
|
||||
{
|
||||
foreach (var a in System.AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
foreach (var c in a.GetTypes())
|
||||
{
|
||||
if (c.IsClass && !c.IsAbstract &&
|
||||
c.GetInterface("ISpecializationSettings") != null)
|
||||
{
|
||||
Config.ProfileTypes.Add(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var propertyInfo in typeof(ApplicationDbContext).GetProperties())
|
||||
{
|
||||
foreach (var attr in propertyInfo.CustomAttributes)
|
||||
{
|
||||
// something like a DbSet?
|
||||
if (typeof(Yavsc.Attributes.ActivitySettingsAttribute).IsAssignableFrom(attr.AttributeType))
|
||||
{
|
||||
BillingService.UserSettings.Add(propertyInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RegisterBilling<HairCutQuery>(BillingCodes.Brush, new Func<ApplicationDbContext, long, IDecidableQuery>
|
||||
((db, id) =>
|
||||
{
|
||||
var query = db.HairCutQueries.Include(q => q.Prestation).Include(q => q.Regularisation).Single(q => q.Id == id);
|
||||
query.SelectedProfile = db.BrusherProfile.Single(b => b.UserId == query.PerformerId);
|
||||
return query;
|
||||
}));
|
||||
|
||||
RegisterBilling<HairMultiCutQuery>(BillingCodes.MBrush, new Func<ApplicationDbContext, long, IDecidableQuery>
|
||||
((db, id) => db.HairMultiCutQueries.Include(q => q.Regularisation).Single(q => q.Id == id)));
|
||||
|
||||
RegisterBilling<RdvQuery>(BillingCodes.Rdv, new Func<ApplicationDbContext, long, IDecidableQuery>
|
||||
((db, id) => db.RdvQueries.Include(q => q.Regularisation).Single(q => q.Id == id)));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
401
src/Server/Hubs/ChatHub.cs
Normal file
401
src/Server/Hubs/ChatHub.cs
Normal file
|
|
@ -0,0 +1,401 @@
|
|||
//
|
||||
// ChatHub.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paul@pschneider.fr>
|
||||
//
|
||||
// Copyright (c) 2016-2019 GNU GPL
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace Yavsc
|
||||
{
|
||||
using System.Diagnostics;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Models;
|
||||
using Models.Chat;
|
||||
using Yavsc.Abstract.Chat;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Server.Helpers;
|
||||
using Yavsc.Services;
|
||||
public partial class ChatHub : Hub, IDisposable
|
||||
{
|
||||
private readonly ApplicationDbContext _dbContext;
|
||||
private readonly IConnexionManager _cxManager;
|
||||
private readonly IStringLocalizer _localizer;
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public HubInputValidator InputValidator { get; }
|
||||
|
||||
public ChatHub(ApplicationDbContext dbContext,
|
||||
ILoggerFactory loggerFactory,
|
||||
IStringLocalizerFactory stringLocalizerFactory,
|
||||
IConnexionManager connexionManager)
|
||||
{
|
||||
_dbContext = dbContext;
|
||||
_localizer = stringLocalizerFactory.Create(typeof(ChatHub));
|
||||
|
||||
_cxManager = connexionManager;
|
||||
_cxManager.SetErrorHandler ((context, error) =>
|
||||
{
|
||||
NotifyUser(NotificationTypes.Error, context, error);
|
||||
});
|
||||
_logger = loggerFactory.CreateLogger<ChatHub>();
|
||||
InputValidator = new HubInputValidator { NotifyUser = async (type, target, msg) => await this.NotifyUser(type, target, msg) };
|
||||
}
|
||||
|
||||
void SetUserName(string cxId, string userName)
|
||||
{
|
||||
_cxManager.SetUserName(cxId, userName);
|
||||
}
|
||||
|
||||
public override async Task OnConnectedAsync()
|
||||
{
|
||||
bool isAuth = Context.User?.Identity?.IsAuthenticated ?? false;
|
||||
bool isCop = false;
|
||||
string userName = setUserName();
|
||||
if (isAuth)
|
||||
{
|
||||
|
||||
var group = isAuth ?
|
||||
ChatHubConstants.HubGroupAuthenticated : ChatHubConstants.HubGroupAnonymous;
|
||||
// Log ("Cx: " + group);
|
||||
await Groups.AddToGroupAsync(Context.ConnectionId, group);
|
||||
_logger.LogInformation(_localizer.GetString(ChatHubConstants.LabAuthChatUser));
|
||||
|
||||
var userId = _dbContext.Users.First(u => u.UserName == Context.User.Identity.Name).Id;
|
||||
|
||||
await Clients.Group(ChatHubConstants.HubGroupFollowingPrefix + userId).SendAsync("notifyUser", NotificationTypes.Connected, userName, null);
|
||||
isCop = Context.User.IsInMsRole(Constants.AdminGroupName) ;
|
||||
if (isCop)
|
||||
{
|
||||
await Groups.AddToGroupAsync(Context.ConnectionId, ChatHubConstants.HubGroupCops);
|
||||
}
|
||||
|
||||
foreach (var uid in _dbContext.CircleMembers.Select(m => m.MemberId))
|
||||
{
|
||||
await Groups.AddToGroupAsync(Context.ConnectionId, ChatHubConstants.HubGroupFollowingPrefix + uid);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
await Groups.AddToGroupAsync(Context.ConnectionId, ChatHubConstants.HubGroupAnonymous);
|
||||
}
|
||||
_cxManager.OnConnected(Context.ConnectionId, isCop);
|
||||
await base.OnConnectedAsync();
|
||||
}
|
||||
|
||||
string setUserName(string queryUname = "anon")
|
||||
{
|
||||
if (Context.User != null)
|
||||
if (Context.User.Identity.IsAuthenticated)
|
||||
{
|
||||
SetUserName(Context.ConnectionId, Context.User.Identity.Name);
|
||||
return Context.User.Identity.Name;
|
||||
}
|
||||
anonymousSequence++;
|
||||
var aname = $"{ChatHubConstants.AnonymousUserNamePrefix}{queryUname}{anonymousSequence}";
|
||||
SetUserName(Context.ConnectionId, aname);
|
||||
return aname;
|
||||
}
|
||||
|
||||
static long anonymousSequence = 0;
|
||||
|
||||
public override async Task OnDisconnectedAsync(Exception ?ex)
|
||||
{
|
||||
string userName = Context.User?.Identity.Name;
|
||||
if (userName != null)
|
||||
{
|
||||
var user = _dbContext.Users.FirstOrDefault(u => u.UserName == userName);
|
||||
var userId = user.Id;
|
||||
await Clients.Group(ChatHubConstants.HubGroupFollowingPrefix + userId).SendAsync("notifyUser", NotificationTypes.DisConnected, userName, null);
|
||||
|
||||
_cxManager.OnDisctonnected(Context.ConnectionId);
|
||||
}
|
||||
await base.OnDisconnectedAsync(ex);
|
||||
}
|
||||
|
||||
|
||||
public async Task Nick(string nickName)
|
||||
{
|
||||
if (!InputValidator.ValidateUserName(nickName)) return;
|
||||
|
||||
var candidate = "?" + nickName;
|
||||
if (_cxManager.IsConnected(candidate))
|
||||
{
|
||||
await NotifyUser(NotificationTypes.ExistingUserName, nickName, "aborting");
|
||||
return;
|
||||
}
|
||||
_cxManager.SetUserName( Context.ConnectionId, candidate);
|
||||
}
|
||||
|
||||
bool IsPresent(string roomName, string userName)
|
||||
{
|
||||
return _cxManager.IsPresent(roomName, userName);
|
||||
}
|
||||
|
||||
public async Task<ChatRoomInfo> Join(string roomName)
|
||||
{
|
||||
_logger.LogInformation($"Join:{roomName}");
|
||||
if (!InputValidator.ValidateRoomName(roomName))
|
||||
{
|
||||
_logger.LogError("!InputValidator.ValidateRoomName(roomName)");
|
||||
return null;
|
||||
}
|
||||
|
||||
var roomGroupName = ChatHubConstants.HubGroupRomsPrefix + roomName;
|
||||
var user = _cxManager.GetUserName(Context.ConnectionId);
|
||||
await Groups.AddToGroupAsync(Context.ConnectionId, roomGroupName);
|
||||
ChatRoomInfo chanInfo;
|
||||
if (!_cxManager.IsPresent(roomName, user))
|
||||
{
|
||||
_logger.LogInformation($"Joining");
|
||||
chanInfo = _cxManager.Join(roomName, Context.ConnectionId);
|
||||
await Clients.Group(roomGroupName).SendAsync("notifyRoom", NotificationTypes.UserJoin, roomName, user);
|
||||
} else {
|
||||
_logger.LogInformation($"already present");
|
||||
// in case in an additional connection,
|
||||
// one only send info on room without
|
||||
// warning any other user.
|
||||
_cxManager.TryGetChanInfo(roomName, out chanInfo);
|
||||
}
|
||||
|
||||
_logger.LogInformation($"returning chan info");
|
||||
await Clients.Caller.SendAsync("joint", chanInfo);
|
||||
return chanInfo;
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
public void Register(string room)
|
||||
{
|
||||
if (!InputValidator.ValidateRoomName(room)) return ;
|
||||
var existent = _dbContext.ChatRoom.Any(r => r.Name == room);
|
||||
if (existent)
|
||||
{
|
||||
NotifyUserInRoom(NotificationTypes.Error, room, "already registered.");
|
||||
return;
|
||||
}
|
||||
Debug.Assert(Context.User != null);
|
||||
string userName = Context.User.GetUserName();
|
||||
var user = _dbContext.Users.FirstOrDefault(u => u.UserName == userName);
|
||||
|
||||
var newroom = new ChatRoom { Name = room, OwnerId = Context.User.GetUserId() };
|
||||
ChatRoomInfo chanInfo;
|
||||
if (_cxManager.TryGetChanInfo(room, out chanInfo))
|
||||
{
|
||||
// TODO get and require some admin status for current user on this chan
|
||||
newroom.Topic = chanInfo.Topic;
|
||||
}
|
||||
newroom.LatestJoinPart = DateTime.Now;
|
||||
|
||||
_dbContext.ChatRoom.Add(newroom);
|
||||
_dbContext.SaveChanges(user.Id);
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
public void KickBan(string roomName, string userName, string reason)
|
||||
{
|
||||
if (!InputValidator.ValidateRoomName(roomName)) return ;
|
||||
if (!InputValidator.ValidateUserName(userName)) return ;
|
||||
if (!InputValidator.ValidateReason(reason)) return;
|
||||
Kick(roomName, userName, reason);
|
||||
Ban(roomName, userName, reason);
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
public async Task Kick(string roomName, string userName, string reason)
|
||||
{
|
||||
if (!InputValidator.ValidateRoomName(roomName)) return ;
|
||||
if (!InputValidator.ValidateUserName(userName)) return ;
|
||||
if (!InputValidator.ValidateReason(reason)) return;
|
||||
ChatRoomInfo chanInfo;
|
||||
var roomGroupName = ChatHubConstants.HubGroupRomsPrefix + roomName;
|
||||
if (_cxManager.TryGetChanInfo(roomName, out chanInfo))
|
||||
{
|
||||
if (!_cxManager.IsPresent(roomName,userName))
|
||||
{
|
||||
NotifyErrorToCallerInRoom(roomName, $"{userName} was not found in {roomName}.");
|
||||
return;
|
||||
}
|
||||
// in case of Kick returned false, being not allowed to, or for what ever other else failure,
|
||||
// the error handler will send an error message while handling the error.
|
||||
if (!_cxManager.Kick(Context.ConnectionId, userName, roomName, reason)) return;
|
||||
}
|
||||
var ukeys = _cxManager.GetConnexionIds(userName);
|
||||
if (ukeys!=null) foreach(var ukey in ukeys)
|
||||
await Groups.RemoveFromGroupAsync(ukey, roomGroupName);
|
||||
await Clients.Group(roomGroupName).SendAsync("notifyRoom", NotificationTypes.Kick, roomName, $"{userName}: {reason}");
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
public void Ban(string roomName, string userName, string reason)
|
||||
{
|
||||
if (!InputValidator.ValidateRoomName(roomName)) return ;
|
||||
if (!InputValidator.ValidateUserName(userName)) return ;
|
||||
if (!InputValidator.ValidateReason(reason)) return;
|
||||
var cxIds = _cxManager.GetConnexionIds(userName);
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
public void Gline(string userName, string reason)
|
||||
{
|
||||
if (!InputValidator.ValidateUserName(userName)) return ;
|
||||
if (!InputValidator.ValidateReason(reason)) return;
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Part(string roomName, string reason)
|
||||
{
|
||||
if (!InputValidator.ValidateRoomName(roomName)) return ;
|
||||
if (!InputValidator.ValidateReason(reason)) return;
|
||||
if (_cxManager.Part(Context.ConnectionId, roomName, reason))
|
||||
{
|
||||
var roomGroupName = ChatHubConstants.HubGroupRomsPrefix + roomName;
|
||||
var group = Clients.Group(roomGroupName);
|
||||
var userName = _cxManager.GetUserName(Context.ConnectionId);
|
||||
group.SendAsync("notifyRoom", NotificationTypes.UserPart, roomName, $"{userName}: {reason}");
|
||||
Groups.RemoveFromGroupAsync(Context.ConnectionId, roomGroupName);
|
||||
}
|
||||
else {
|
||||
_logger.LogError("Could not part");
|
||||
}
|
||||
}
|
||||
|
||||
void NotifyErrorToCallerInRoom(string room, string reason)
|
||||
{
|
||||
NotifyUserInRoom(NotificationTypes.Error, room, reason);
|
||||
_logger.LogError($"NotifyErrorToCallerInRoom: {room}, {reason}");
|
||||
}
|
||||
|
||||
public async Task Send(string roomName, string message)
|
||||
{
|
||||
_logger.LogInformation($"Send {roomName} {message}");
|
||||
if (!InputValidator.ValidateRoomName(roomName)) {
|
||||
_logger.LogError($"Invalid roomName : {roomName}");
|
||||
return ;
|
||||
}
|
||||
if (!InputValidator.ValidateMessage(message)) {
|
||||
_logger.LogError($"Invalid message : {message}");
|
||||
return ;
|
||||
}
|
||||
var groupname = ChatHubConstants.HubGroupRomsPrefix + roomName;
|
||||
ChatRoomInfo chanInfo ;
|
||||
if (!_cxManager.TryGetChanInfo(roomName, out chanInfo))
|
||||
{
|
||||
_logger.LogError($"No such room : {roomName}");
|
||||
var noChanMsg = _localizer.GetString(ChatHubConstants.LabNoSuchChan).ToString();
|
||||
NotifyUserInRoom(NotificationTypes.Error, roomName, noChanMsg);
|
||||
return;
|
||||
}
|
||||
var userName = _cxManager.GetUserName(Context.ConnectionId);
|
||||
if (!_cxManager.IsPresent(roomName, userName))
|
||||
{
|
||||
_logger.LogError($"{userName} Not present in room : {roomName}");
|
||||
var notSentMsg = _localizer.GetString(ChatHubConstants.LabnoJoinNoSend).ToString();
|
||||
NotifyUserInRoom(NotificationTypes.Error, roomName, notSentMsg);
|
||||
return;
|
||||
}
|
||||
var group = Clients.Group(groupname);
|
||||
var msg = new { Name = userName, Room = roomName, Message = message};
|
||||
await group.SendAsync("ReceiveMessage", msg);
|
||||
}
|
||||
|
||||
async Task NotifyUser(string type, string targetId, string message)
|
||||
{
|
||||
_logger.LogInformation($"notifying user {type} {targetId} : {message}");
|
||||
await Clients.Caller.SendAsync("notifyUser", type, targetId, message);
|
||||
}
|
||||
|
||||
async Task NotifyUserInRoom(string type, string room, string message)
|
||||
{
|
||||
await Clients.Caller.SendAsync("notifyUserInRoom", type, room, message);
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
public async Task SendPV(string userName, string message)
|
||||
{
|
||||
// Authorized code
|
||||
Debug.Assert(Context.User != null);
|
||||
_logger.LogInformation($"Sending pv to {userName}");
|
||||
|
||||
if (!InputValidator.ValidateUserName(userName))
|
||||
{
|
||||
_logger.LogError($"Invalid username : {userName}");
|
||||
return ;
|
||||
}
|
||||
if (!InputValidator.ValidateMessage(message))
|
||||
{
|
||||
_logger.LogError($"Invalid message : {message}");
|
||||
return ;
|
||||
}
|
||||
_logger.LogInformation($"Message form is validated.");
|
||||
var identityUserName = Context.User.GetUserName();
|
||||
|
||||
if (userName[0] != '?' && Context.User!=null)
|
||||
if (!Context.User.IsInMsRole(Constants.AdminGroupName))
|
||||
{
|
||||
|
||||
var bl = _dbContext.BlackListed
|
||||
.Include(r => r.User)
|
||||
.Include(r => r.Owner)
|
||||
.Where(r => r.User.UserName == identityUserName && r.Owner.UserName == userName)
|
||||
.Select(r => r.OwnerId);
|
||||
|
||||
if (bl.Count() > 0)
|
||||
{
|
||||
_logger.LogError($"Black listed : {identityUserName}");
|
||||
await NotifyUser(NotificationTypes.PrivateMessageDenied, userName, "you are black listed.");
|
||||
return;
|
||||
}
|
||||
_logger.LogInformation("Sender is no black listed");
|
||||
}
|
||||
|
||||
_logger.LogInformation("getting cx id´s");
|
||||
var cxIds = _cxManager.GetConnexionIds(userName);
|
||||
if (cxIds==null || cxIds.Count()==0)
|
||||
_logger.LogError($"No such connected user : {userName}");
|
||||
else foreach (var connectionId in cxIds)
|
||||
{
|
||||
_logger.LogInformation($"cx: {connectionId}");
|
||||
var cli = Clients.Client(connectionId);
|
||||
_logger.LogInformation($"cli: {cli.ToString()}");
|
||||
await cli.SendAsync("addPV", identityUserName, message);
|
||||
_logger.LogInformation($"Sent pv to cx {connectionId}");
|
||||
}
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
public async Task SendStream(string connectionId, long streamId, string message)
|
||||
{
|
||||
// Authorized code
|
||||
Debug.Assert(Context.User != null);
|
||||
Debug.Assert(Context.User.Identity != null);
|
||||
if (!InputValidator.ValidateMessage(message)) return;
|
||||
var sender = Context.User.Identity.Name;
|
||||
var cli = Clients.Client(connectionId);
|
||||
await cli.SendAsync("addStreamInfo", sender, streamId, message);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
43
src/Server/Interfaces/ICalendarManager.cs
Normal file
43
src/Server/Interfaces/ICalendarManager.cs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// ICalendarManager.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paul@pschneider.fr>
|
||||
//
|
||||
// Copyright (c) 2015 GNU GPL
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using Google.Apis.Calendar.v3.Data;
|
||||
|
||||
namespace Yavsc.Services
|
||||
{
|
||||
using System.Threading.Tasks;
|
||||
using Yavsc.ViewModels.Calendar;
|
||||
|
||||
/// <summary>
|
||||
/// I calendar manager.
|
||||
/// </summary>
|
||||
public interface ICalendarManager {
|
||||
Task<CalendarList> GetCalendarsAsync (string pageToken);
|
||||
Task<Events> GetCalendarAsync (string calid, DateTime minDate, DateTime maxDate, string pageToken);
|
||||
Task<DateTimeChooserViewModel> CreateViewModelAsync(
|
||||
string inputId,
|
||||
string calid, DateTime mindate, DateTime maxdate);
|
||||
Task<Event> CreateEventAsync(string userId, string calid,
|
||||
DateTime startDate, int lengthInSeconds, string summary,
|
||||
string description, string location, bool available);
|
||||
}
|
||||
}
|
||||
35
src/Server/Interfaces/IConnexionManager.cs
Normal file
35
src/Server/Interfaces/IConnexionManager.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Yavsc.ViewModels.Chat;
|
||||
|
||||
namespace Yavsc.Services
|
||||
{
|
||||
public interface IConnexionManager {
|
||||
void SetUserName(string cxId, string userName);
|
||||
|
||||
string GetUserName (string cxId);
|
||||
void OnConnected(string cxId, bool isCop);
|
||||
bool IsConnected(string candidate);
|
||||
|
||||
void OnDisctonnected (string cxId);
|
||||
bool IsPresent(string roomName, string userName);
|
||||
|
||||
ChatRoomInfo Join(string roomName, string cxId);
|
||||
|
||||
bool Part(string cxId, string roomName, string reason);
|
||||
|
||||
bool Kick(string cxId, string userName, string roomName, string reason);
|
||||
|
||||
bool Op(string roomName, string userName);
|
||||
bool Deop(string roomName, string userName);
|
||||
bool Hop(string roomName, string userName);
|
||||
bool Dehop(string roomName, string userName);
|
||||
bool TryGetChanInfo(string room, out ChatRoomInfo chanInfo);
|
||||
|
||||
IEnumerable<string> GetConnexionIds(string userName);
|
||||
|
||||
void SetErrorHandler(Action<string,string> errorHandler);
|
||||
IEnumerable<ChannelShortInfo> ListChannels(string pattern);
|
||||
|
||||
}
|
||||
}
|
||||
12
src/Server/Interfaces/IDiskUsageTracker.cs
Normal file
12
src/Server/Interfaces/IDiskUsageTracker.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
using System;
|
||||
|
||||
namespace Yavsc.Services
|
||||
{
|
||||
|
||||
public interface IDiskUsageTracker
|
||||
{
|
||||
bool GetSpace(string userName, long space);
|
||||
void Release(string userName, long space);
|
||||
}
|
||||
}
|
||||
54
src/Server/Interfaces/IFreeDateSet.cs
Normal file
54
src/Server/Interfaces/IFreeDateSet.cs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
// FreeDate.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Yavsc.Server.Models.Calendar;
|
||||
|
||||
namespace Yavsc.Models.Calendar
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Free date.
|
||||
/// </summary>
|
||||
public interface IFreeDateSet
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the reference.
|
||||
/// </summary>
|
||||
/// <value>The reference.</value>
|
||||
IEnumerable<Period> Values { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the duration.
|
||||
/// </summary>
|
||||
/// <value>The duration.</value>
|
||||
TimeSpan Duration { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the attendees.
|
||||
/// </summary>
|
||||
/// <value>The attendees.</value>
|
||||
string UserName { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the location.
|
||||
/// </summary>
|
||||
/// <value>The location.</value>
|
||||
string Location { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
26
src/Server/Interfaces/ILiveProcessor.cs
Normal file
26
src/Server/Interfaces/ILiveProcessor.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
using System.Collections.Concurrent;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.ViewModels.Streaming;
|
||||
|
||||
namespace Yavsc.Services
|
||||
{
|
||||
public interface ILiveProcessor {
|
||||
/// <summary>
|
||||
/// instance keeping reference on
|
||||
/// all collections of casting and listenning websockets
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
ConcurrentDictionary<string, LiveCastHandler> Casters { get; }
|
||||
/// <summary>
|
||||
/// Try and accept websocket from aspnet http context
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <returns></returns>
|
||||
Task<bool> AcceptStream (HttpContext context, ApplicationUser user, string destDir, string fileName);
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
36
src/Server/Interfaces/IScheduledEvent.cs
Normal file
36
src/Server/Interfaces/IScheduledEvent.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// IScheduledEvent.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 - 2017 Paul Schneider
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using Yavsc.Server.Models.Calendar;
|
||||
|
||||
namespace Yavsc.Models.Calendar
|
||||
{
|
||||
public interface IScheduledEvent
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the period.
|
||||
/// </summary>
|
||||
/// <value>The period.</value>
|
||||
Periodicity Reccurence { get; set; }
|
||||
Period Period { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
10
src/Server/Interfaces/ISmsSender.cs
Normal file
10
src/Server/Interfaces/ISmsSender.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yavsc.Services
|
||||
{
|
||||
public interface ISmsSender
|
||||
{
|
||||
Task SendSmsAsync(TwilioSettings settings, string number, string message);
|
||||
}
|
||||
}
|
||||
7
src/Server/Interfaces/ITranslator.cs
Normal file
7
src/Server/Interfaces/ITranslator.cs
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
namespace Yavsc.Server
|
||||
{
|
||||
public interface ITranslator
|
||||
{
|
||||
string[] Translate (string slang, string dlang, string[] text);
|
||||
}
|
||||
}
|
||||
15
src/Server/Interfaces/ITrueEmailSender.cs
Normal file
15
src/Server/Interfaces/ITrueEmailSender.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
namespace Yavsc.Interface
|
||||
{
|
||||
public interface ITrueEmailSender
|
||||
{
|
||||
//
|
||||
// Résumé :
|
||||
// This API supports the ASP.NET Core Identity default UI infrastructure and is
|
||||
// not intended to be used directly from your code. This API may change or be removed
|
||||
// in future releases.
|
||||
Task<string> SendEmailAsync(string name, string email, string subject, string htmlMessage);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
28
src/Server/Interfaces/IYavscMessageSender.cs
Normal file
28
src/Server/Interfaces/IYavscMessageSender.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Yavsc.Interfaces.Workflow;
|
||||
using Yavsc.Models.Google.Messaging;
|
||||
using Yavsc.Models.Haircut;
|
||||
using Yavsc.Models.Messaging;
|
||||
|
||||
namespace Yavsc.Services
|
||||
{
|
||||
public interface IYavscMessageSender
|
||||
{
|
||||
Task<MessageWithPayloadResponse> NotifyBookQueryAsync(
|
||||
IEnumerable<string> connectionIds,
|
||||
RdvQueryEvent ev);
|
||||
|
||||
Task<MessageWithPayloadResponse> NotifyEstimateAsync(
|
||||
IEnumerable<string> connectionIds,
|
||||
EstimationEvent ev);
|
||||
|
||||
Task<MessageWithPayloadResponse> NotifyHairCutQueryAsync(
|
||||
IEnumerable<string> connectionIds,
|
||||
HairCutQueryEvent ev);
|
||||
Task<MessageWithPayloadResponse> NotifyAsync(
|
||||
IEnumerable<string> connectionIds,
|
||||
IEvent yaev);
|
||||
}
|
||||
}
|
||||
2
src/Server/Makefile
Normal file
2
src/Server/Makefile
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
listConnections:
|
||||
dotnet ef migrations list --connection "$(YAVSC_CONNECTION_STRING)"
|
||||
17
src/Server/Models/Access/AccountOptions.cs
Normal file
17
src/Server/Models/Access/AccountOptions.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
public class AccountOptions
|
||||
{
|
||||
public static bool AllowLocalLogin = true;
|
||||
public static bool AllowRememberLogin = true;
|
||||
public static TimeSpan RememberMeLoginDuration = TimeSpan.FromDays(30);
|
||||
|
||||
public static bool ShowLogoutPrompt = true;
|
||||
public static bool AutomaticRedirectAfterSignOut = false;
|
||||
|
||||
public static string InvalidCredentialsErrorMessage = "Invalid username or password";
|
||||
}
|
||||
}
|
||||
48
src/Server/Models/Access/Ban.cs
Normal file
48
src/Server/Models/Access/Ban.cs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
using Yavsc;
|
||||
public class Ban : ITrackedEntity
|
||||
{
|
||||
public DateTime DateCreated
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public DateTime DateModified
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long Id { get; set; }
|
||||
|
||||
public string UserCreated
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public string UserModified
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
[Required]
|
||||
public string TargetId
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
[ForeignKey("TargetId")]
|
||||
public virtual ApplicationUser TargetUser {
|
||||
get; set;
|
||||
}
|
||||
|
||||
[Required]
|
||||
public string Reason { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
18
src/Server/Models/Access/BanByEmail.cs
Normal file
18
src/Server/Models/Access/BanByEmail.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
public class BanByEmail
|
||||
{
|
||||
[Required]
|
||||
public long BanId { get; set; }
|
||||
|
||||
[ForeignKey("BanId")]
|
||||
public virtual Ban UserBan { get; set; }
|
||||
|
||||
[Required]
|
||||
public string email { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
25
src/Server/Models/Access/BlackList.cs
Normal file
25
src/Server/Models/Access/BlackList.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
public class BlackListed: IBlackListed
|
||||
{
|
||||
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Required]
|
||||
public string UserId { get; set; }
|
||||
|
||||
[Required]
|
||||
public string OwnerId { get; set; }
|
||||
|
||||
[ForeignKey("OwnerId"), JsonIgnore]
|
||||
public virtual ApplicationUser Owner { get; set; }
|
||||
|
||||
[ForeignKey("UserId"), JsonIgnore]
|
||||
public virtual ApplicationUser User { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
26
src/Server/Models/Access/CircleAuthorizationToBlogPost.cs
Normal file
26
src/Server/Models/Access/CircleAuthorizationToBlogPost.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
namespace Yavsc.Models.Access
|
||||
{
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Models.Relationship;
|
||||
using Newtonsoft.Json;
|
||||
using Blog;
|
||||
using Yavsc.Abstract.Identity.Security;
|
||||
|
||||
public class CircleAuthorizationToBlogPost : ICircleAuthorization
|
||||
{
|
||||
public long CircleId { get; set; }
|
||||
public long BlogPostId { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[ForeignKey("BlogPostId")]
|
||||
public virtual BlogPost Target { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[ForeignKey("CircleId")]
|
||||
public virtual Circle Allowed { get; set; }
|
||||
|
||||
public bool Comment { get; set; }
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
17
src/Server/Models/Access/ConsentInputModel.cs
Normal file
17
src/Server/Models/Access/ConsentInputModel.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
public class ConsentInputModel
|
||||
{
|
||||
public string Button { get; set; }
|
||||
public IEnumerable<string> ScopesConsented { get; set; }
|
||||
public bool RememberConsent { get; set; }
|
||||
public string ReturnUrl { get; set; }
|
||||
public string Description { get; set; }
|
||||
}
|
||||
}
|
||||
19
src/Server/Models/Access/ConsentViewModel.cs
Normal file
19
src/Server/Models/Access/ConsentViewModel.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
public class ConsentViewModel : ConsentInputModel
|
||||
{
|
||||
public string ClientName { get; set; }
|
||||
public string ClientUrl { get; set; }
|
||||
public string ClientLogoUrl { get; set; }
|
||||
public bool AllowRememberConsent { get; set; }
|
||||
|
||||
public IEnumerable<ScopeViewModel> IdentityScopes { get; set; }
|
||||
public IEnumerable<ScopeViewModel> ApiScopes { get; set; }
|
||||
}
|
||||
}
|
||||
11
src/Server/Models/Access/DeviceAuthorizationInputModel.cs
Normal file
11
src/Server/Models/Access/DeviceAuthorizationInputModel.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
public class DeviceAuthorizationInputModel : ConsentInputModel
|
||||
{
|
||||
public string UserCode { get; set; }
|
||||
}
|
||||
}
|
||||
13
src/Server/Models/Access/DeviceAuthorizationViewModel.cs
Normal file
13
src/Server/Models/Access/DeviceAuthorizationViewModel.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
|
||||
public class DeviceAuthorizationViewModel : ConsentViewModel
|
||||
{
|
||||
public string UserCode { get; set; }
|
||||
public bool ConfirmUserCode { get; set; }
|
||||
}
|
||||
}
|
||||
19
src/Server/Models/Access/GrantViewModel.cs
Normal file
19
src/Server/Models/Access/GrantViewModel.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
public class GrantViewModel
|
||||
{
|
||||
public string ClientId { get; set; }
|
||||
public string ClientName { get; set; }
|
||||
public string ClientUrl { get; set; }
|
||||
public string ClientLogoUrl { get; set; }
|
||||
public string Description { get; set; }
|
||||
public DateTime Created { get; set; }
|
||||
public DateTime? Expires { get; set; }
|
||||
public IEnumerable<string> IdentityGrantNames { get; set; }
|
||||
public IEnumerable<string> ApiGrantNames { get; set; }
|
||||
}
|
||||
}
|
||||
11
src/Server/Models/Access/GrantsViewModel.cs
Normal file
11
src/Server/Models/Access/GrantsViewModel.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
public class GrantsViewModel
|
||||
{
|
||||
public IEnumerable<GrantViewModel> Grants { get; set; }
|
||||
}
|
||||
}
|
||||
19
src/Server/Models/Access/LoggedOutViewModel.cs
Normal file
19
src/Server/Models/Access/LoggedOutViewModel.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
public class LoggedOutViewModel
|
||||
{
|
||||
public string PostLogoutRedirectUri { get; set; }
|
||||
public string ClientName { get; set; }
|
||||
public string SignOutIframeUrl { get; set; }
|
||||
|
||||
public bool AutomaticRedirectAfterSignOut { get; set; }
|
||||
|
||||
public string LogoutId { get; set; }
|
||||
public bool TriggerExternalSignout => ExternalAuthenticationScheme != null;
|
||||
public string ExternalAuthenticationScheme { get; set; }
|
||||
}
|
||||
}
|
||||
11
src/Server/Models/Access/LogoutInputModel.cs
Normal file
11
src/Server/Models/Access/LogoutInputModel.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
public class LogoutInputModel
|
||||
{
|
||||
public string LogoutId { get; set; }
|
||||
}
|
||||
}
|
||||
21
src/Server/Models/Access/ProcessConsentResult.cs
Normal file
21
src/Server/Models/Access/ProcessConsentResult.cs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
using IdentityServer8.Models;
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
public class ProcessConsentResult
|
||||
{
|
||||
public bool IsRedirect => RedirectUri != null;
|
||||
public string RedirectUri { get; set; }
|
||||
public Client Client { get; set; }
|
||||
|
||||
public bool ShowView => ViewModel != null;
|
||||
public ConsentViewModel ViewModel { get; set; }
|
||||
|
||||
public bool HasValidationError => ValidationError != null;
|
||||
public string ValidationError { get; set; }
|
||||
}
|
||||
}
|
||||
50
src/Server/Models/Access/Publishing.cs
Normal file
50
src/Server/Models/Access/Publishing.cs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
//
|
||||
// Publishing.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Publishing.
|
||||
/// </summary>
|
||||
public enum Publishing {
|
||||
/// <summary>
|
||||
/// In the context of immediate use, with no related stored content.
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// In the context of private use of an uploaded content.
|
||||
/// </summary>
|
||||
Private,
|
||||
/// <summary>
|
||||
/// In the context of restricted access areas, like circle members views.
|
||||
/// </summary>
|
||||
Restricted,
|
||||
/// <summary>
|
||||
/// Publishing a content in a public access area.
|
||||
/// </summary>
|
||||
Public
|
||||
}
|
||||
|
||||
}
|
||||
10
src/Server/Models/Access/RedirectViewModel.cs
Normal file
10
src/Server/Models/Access/RedirectViewModel.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
public class RedirectViewModel
|
||||
{
|
||||
public string RedirectUrl { get; set; }
|
||||
}
|
||||
}
|
||||
14
src/Server/Models/Access/Rule.cs
Normal file
14
src/Server/Models/Access/Rule.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
public abstract class Rule<TResource,TRequirement>
|
||||
{
|
||||
public Rule()
|
||||
{
|
||||
|
||||
}
|
||||
// Abstract method to compute any authorization on a resource
|
||||
public abstract bool Allow(string userId, TResource resource, TRequirement requirement);
|
||||
}
|
||||
}
|
||||
10
src/Server/Models/Access/RuleSet.cs
Normal file
10
src/Server/Models/Access/RuleSet.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using System.Collections.Generic;
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
public abstract class RuleSet <TResource,TRequirement>:List<Rule<TResource,TRequirement>> {
|
||||
|
||||
public abstract bool Allow(string userId, TResource resource, TRequirement requirement);
|
||||
|
||||
}
|
||||
}
|
||||
16
src/Server/Models/Access/ScopeViewModel.cs
Normal file
16
src/Server/Models/Access/ScopeViewModel.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
public class ScopeViewModel
|
||||
{
|
||||
public string Value { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public string Description { get; set; }
|
||||
public bool Emphasize { get; set; }
|
||||
public bool Required { get; set; }
|
||||
public bool Checked { get; set; }
|
||||
}
|
||||
}
|
||||
8
src/Server/Models/Access/WhiteCard.cs
Normal file
8
src/Server/Models/Access/WhiteCard.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
|
||||
public class WhiteCard {
|
||||
|
||||
}
|
||||
}
|
||||
294
src/Server/Models/ApplicationDbContext.cs
Normal file
294
src/Server/Models/ApplicationDbContext.cs
Normal file
|
|
@ -0,0 +1,294 @@
|
|||
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
using Yavsc.Abstract.Models.Messaging;
|
||||
using Yavsc.Server.Models.EMailing;
|
||||
using Yavsc.Server.Models.IT.SourceCode;
|
||||
using Yavsc.Server.Models.IT;
|
||||
using Yavsc.Abstract.Identity;
|
||||
using Yavsc.Server.Models.Calendar;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
using Haircut;
|
||||
using IT.Evolution;
|
||||
using IT.Fixing;
|
||||
using Streaming;
|
||||
using Relationship;
|
||||
using Forms;
|
||||
using Auth;
|
||||
using Billing;
|
||||
using Musical;
|
||||
using Workflow;
|
||||
using Identity;
|
||||
using Market;
|
||||
using Chat;
|
||||
using Messaging;
|
||||
using Access;
|
||||
using Musical.Profiles;
|
||||
using Workflow.Profiles;
|
||||
using Drawing;
|
||||
using Attributes;
|
||||
using Bank;
|
||||
using Payment;
|
||||
using Blog;
|
||||
using IdentityServer8.Models;
|
||||
using IdentityServer8.EntityFramework.Entities;
|
||||
|
||||
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>, IdentityServer8.EntityFramework.Interfaces.IConfigurationDbContext
|
||||
{
|
||||
public ApplicationDbContext()
|
||||
{
|
||||
|
||||
}
|
||||
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
base.OnModelCreating(builder);
|
||||
// Customize the ASP.NET Identity model and override the defaults if needed.
|
||||
// For example, you can rename the ASP.NET Identity table names and more.
|
||||
// Add your customizations after calling base.OnModelCreating(builder);
|
||||
builder.Entity<Contact>().HasKey(x => new { x.OwnerId, x.UserId });
|
||||
builder.Entity<DeviceDeclaration>().Property(x => x.DeclarationDate).HasDefaultValueSql("LOCALTIMESTAMP");
|
||||
builder.Entity<BlogTag>().HasKey(x => new { x.PostId, x.TagId });
|
||||
|
||||
builder.Entity<ApplicationUser>().Property(u => u.FullName).IsRequired(false);
|
||||
builder.Entity<ApplicationUser>().Property(u => u.DedicatedGoogleCalendar).IsRequired(false);
|
||||
builder.Entity<ApplicationUser>().HasMany<ChatConnection>(c => c.Connections);
|
||||
builder.Entity<ApplicationUser>().Property(u => u.Avatar).HasDefaultValue(Constants.DefaultAvatar);
|
||||
builder.Entity<ApplicationUser>().Property(u => u.DiskQuota).HasDefaultValue(Constants.DefaultFSQ);
|
||||
builder.Entity<ApplicationUser>().HasAlternateKey(u => u.Email);
|
||||
builder.Entity<BlackListed>().HasOne<ApplicationUser>(bl => bl.User);
|
||||
builder.Entity<BlackListed>().HasOne<ApplicationUser>(bl => bl.Owner);
|
||||
builder.Entity<UserActivity>().HasKey(u => new { u.DoesCode, u.UserId });
|
||||
builder.Entity<Instrumentation>().HasKey(u => new { u.InstrumentId, u.UserId });
|
||||
builder.Entity<CircleAuthorizationToBlogPost>().HasKey(a => new { a.CircleId, a.BlogPostId });
|
||||
builder.Entity<CircleMember>().HasKey(c => new { c.MemberId, c.CircleId });
|
||||
builder.Entity<DismissClicked>().HasKey(c => new { uid = c.UserId, notid = c.NotificationId });
|
||||
builder.Entity<HairTaintInstance>().HasKey(ti => new { ti.TaintId, ti.PrestationId });
|
||||
builder.Entity<HyperLink>().HasKey(l => new { l.HRef, l.Method });
|
||||
builder.Entity<Period>().HasKey(l => new { l.Start, l.End });
|
||||
builder.Entity<Cratie.Option>().HasKey(o => new { o.Code, o.CodeScrutin });
|
||||
builder.Entity<Notification>().Property(n => n.icon).HasDefaultValue("exclam");
|
||||
builder.Entity<ChatRoomAccess>().HasKey(p => new { room = p.ChannelName, user = p.UserId });
|
||||
builder.Entity<InstrumentRating>().HasAlternateKey(i => new { Instrument = i.InstrumentId, owner = i.OwnerId });
|
||||
|
||||
foreach (var et in builder.Model.GetEntityTypes())
|
||||
{
|
||||
if (et.ClrType.GetInterface("IBaseTrackedEntity") != null)
|
||||
et.FindProperty("DateCreated").SetAfterSaveBehavior(Microsoft.EntityFrameworkCore.Metadata.PropertySaveBehavior.Ignore);
|
||||
}
|
||||
|
||||
builder.Entity<Activity>().Property(a => a.ParentCode).IsRequired(false);
|
||||
// builder.Entity<IdentityUserLogin<String>>().HasKey(i=> new { i.LoginProvider, i.UserId, i.ProviderKey });
|
||||
}
|
||||
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
|
||||
{
|
||||
string? envCxStr = Environment.GetEnvironmentVariable(Constants.YavscConnectionStringEnvName);
|
||||
if (envCxStr != null)
|
||||
optionsBuilder.UseNpgsql(envCxStr);
|
||||
base.OnConfiguring(optionsBuilder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Activities referenced on this site
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public DbSet<Activity> Activities { get; set; }
|
||||
|
||||
public DbSet<UserActivity> UserActivities { get; set; }
|
||||
/// <summary>
|
||||
/// Users posts
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public DbSet<BlogPost> BlogSpot { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Skills powered by this site
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public DbSet<Skill> SiteSkills { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Circle members
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public DbSet<CircleMember> CircleMembers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Special commands, talking about
|
||||
/// a given place and date.
|
||||
/// </summary>
|
||||
public DbSet<RdvQuery> RdvQueries { get; set; }
|
||||
|
||||
public DbSet<HairCutQuery> HairCutQueries { get; set; }
|
||||
public DbSet<HairPrestation> HairPrestation { get; set; }
|
||||
|
||||
public DbSet<HairMultiCutQuery> HairMultiCutQueries { get; set; }
|
||||
public DbSet<PerformerProfile> Performers { get; set; }
|
||||
|
||||
public DbSet<Estimate> Estimates { get; set; }
|
||||
public DbSet<AccountBalance> BankStatus { get; set; }
|
||||
public DbSet<BalanceImpact> BalanceImpact { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// References all declared external NativeConfidential devices
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public DbSet<DeviceDeclaration> DeviceDeclaration { get; set; }
|
||||
|
||||
public DbSet<Service> Services { get; set; }
|
||||
public DbSet<Product> Products { get; set; }
|
||||
|
||||
public DbSet<ExceptionSIREN> ExceptionsSIREN { get; set; }
|
||||
|
||||
public DbSet<Location> Locations { get; set; }
|
||||
|
||||
public DbSet<Tag> Tags { get; set; }
|
||||
|
||||
public DbSet<BlogTag> TagsDomain { get; set; }
|
||||
|
||||
public DbSet<EstimateTemplate> EstimateTemplates { get; set; }
|
||||
|
||||
public DbSet<Contact> Contact { get; set; }
|
||||
|
||||
public DbSet<ClientProviderInfo> ClientProviderInfo { get; set; }
|
||||
|
||||
public DbSet<BlackListed> BlackListed { get; set; }
|
||||
|
||||
public DbSet<MusicalPreference> MusicalPreference { get; set; }
|
||||
|
||||
public DbSet<MusicalTendency> MusicalTendency { get; set; }
|
||||
|
||||
public DbSet<Instrument> Instrument { get; set; }
|
||||
|
||||
[ActivitySettings]
|
||||
public DbSet<DjSettings> DjSettings { get; set; }
|
||||
|
||||
[ActivitySettings]
|
||||
public DbSet<Instrumentation> Instrumentation { get; set; }
|
||||
|
||||
[ActivitySettings]
|
||||
public DbSet<FormationSettings> FormationSettings { get; set; }
|
||||
|
||||
[ActivitySettings]
|
||||
public DbSet<GeneralSettings> GeneralSettings { get; set; }
|
||||
public DbSet<CoWorking> CoWorking { get; set; }
|
||||
|
||||
private void AddTimestamps(string userId)
|
||||
{
|
||||
var entities =
|
||||
ChangeTracker.Entries()
|
||||
.Where(x => x.Entity.GetType().GetInterface(nameof(ITrackedEntity)) != null
|
||||
&& (x.State == EntityState.Added || x.State == EntityState.Modified));
|
||||
|
||||
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
if (entity.State == EntityState.Added)
|
||||
{
|
||||
((ITrackedEntity)entity.Entity).DateCreated = DateTime.Now;
|
||||
((ITrackedEntity)entity.Entity).UserCreated = userId;
|
||||
}
|
||||
|
||||
((ITrackedEntity)entity.Entity).DateModified = DateTime.Now;
|
||||
((ITrackedEntity)entity.Entity).UserModified = userId;
|
||||
}
|
||||
}
|
||||
|
||||
public int SaveChanges(string userId)
|
||||
{
|
||||
AddTimestamps(userId);
|
||||
return base.SaveChanges();
|
||||
}
|
||||
|
||||
public async Task<int> SaveChangesAsync(string userId, CancellationToken ctoken = default(CancellationToken))
|
||||
{
|
||||
AddTimestamps(userId);
|
||||
return await base.SaveChangesAsync(ctoken);
|
||||
}
|
||||
|
||||
public DbSet<Circle> Circle { get; set; }
|
||||
|
||||
public DbSet<CircleAuthorizationToBlogPost> CircleAuthorizationToBlogPost { get; set; }
|
||||
|
||||
public DbSet<CommandForm> CommandForm { get; set; }
|
||||
|
||||
public DbSet<Form> Form { get; set; }
|
||||
|
||||
public DbSet<Ban> Ban { get; set; }
|
||||
|
||||
public DbSet<HairTaint> HairTaint { get; set; }
|
||||
|
||||
public DbSet<Color> Color { get; set; }
|
||||
|
||||
public DbSet<Notification> Notification { get; set; }
|
||||
|
||||
public DbSet<DismissClicked> DismissClicked { get; set; }
|
||||
|
||||
|
||||
[ActivitySettings]
|
||||
public DbSet<BrusherProfile> BrusherProfile { get; set; }
|
||||
|
||||
public DbSet<BankIdentity> BankIdentity { get; set; }
|
||||
|
||||
public DbSet<PayPalPayment> PayPalPayment { get; set; }
|
||||
|
||||
public DbSet<HyperLink> HyperLink { get; set; }
|
||||
|
||||
public DbSet<Period> Period { get; set; }
|
||||
|
||||
public DbSet<BlogTag> BlogTag { get; set; }
|
||||
|
||||
public DbSet<ApplicationUser> ApplicationUser { get; set; }
|
||||
|
||||
public DbSet<Feature> Feature { get; set; }
|
||||
|
||||
public DbSet<Bug> Bug { get; set; }
|
||||
|
||||
public DbSet<Comment> Comment { get; set; }
|
||||
|
||||
public DbSet<Announce> Announce { get; set; }
|
||||
|
||||
// TODO remove and opt for for memory only storing,
|
||||
// as long as it must be set empty each time the service is restarted,
|
||||
// and that chatting should be kept as must as possible independent from db context
|
||||
public DbSet<ChatConnection> ChatConnection { get; set; }
|
||||
|
||||
public DbSet<ChatRoom> ChatRoom { get; set; }
|
||||
|
||||
public DbSet<MailingTemplate> MailingTemplate { get; set; }
|
||||
|
||||
public DbSet<GitRepositoryReference> GitRepositoryReference { get; set; }
|
||||
|
||||
public DbSet<Project> Project { get; set; }
|
||||
|
||||
[Obsolete("use signaled flows")]
|
||||
public DbSet<LiveFlow> LiveFlow { get; set; }
|
||||
|
||||
public DbSet<ChatRoomAccess> ChatRoomAccess { get; set; }
|
||||
|
||||
public DbSet<InstrumentRating> InstrumentRating { get; set; }
|
||||
|
||||
public DbSet<Scope> Scopes { get; set; }
|
||||
|
||||
public DbSet<BlogSpotPublication> blogSpotPublications { get; set; }
|
||||
public DbSet<IdentityServer8.EntityFramework.Entities.Client> Clients { get; set; }
|
||||
public DbSet<ClientCorsOrigin> ClientCorsOrigins { get; set; }
|
||||
public DbSet<IdentityServer8.EntityFramework.Entities.IdentityResource> IdentityResources { get; set; }
|
||||
public DbSet<IdentityServer8.EntityFramework.Entities.ApiResource> ApiResources { get; set; }
|
||||
public DbSet<IdentityServer8.EntityFramework.Entities.ApiScope> ApiScopes { get; set; }
|
||||
public DbSet<IdentityResourceClaim> IdentityResourceClaims { get; set; }
|
||||
public DbSet<IdentityResourceProperty> IdentityResourceProperties { get; set; }
|
||||
public DbSet<ApiResourceSecret> ApiResourceSecrets { get; set; }
|
||||
public DbSet<ApiResourceScope> ApiResourceScopes { get; set; }
|
||||
public DbSet<ApiResourceClaim> ApiResourceClaims { get; set; }
|
||||
public DbSet<ApiResourceProperty> ApiResourceProperties { get; set; }
|
||||
public DbSet<ApiScopeClaim> ApiScopeClaims { get; set; }
|
||||
public DbSet<ApiScopeProperty> ApiScopeProperties { get; set; }
|
||||
}
|
||||
}
|
||||
121
src/Server/Models/ApplicationUser.cs
Normal file
121
src/Server/Models/ApplicationUser.cs
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Newtonsoft.Json;
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Yavsc.Models.Relationship;
|
||||
using Yavsc.Models.Identity;
|
||||
using Yavsc.Models.Chat;
|
||||
using Yavsc.Models.Bank;
|
||||
using Yavsc.Models.Access;
|
||||
using Yavsc.Abstract.Identity;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
[Table("AspNetUsers")]
|
||||
public class ApplicationUser : IdentityUser, IApplicationUser
|
||||
{
|
||||
/// <summary>
|
||||
/// Another me, as a byte array.TG7@Eu%80rufzkhbb
|
||||
/// This value points a picture that may be used
|
||||
/// to present the user
|
||||
/// </summary>
|
||||
/// <returns>the path to an user's image, relative to it's user dir<summary>
|
||||
/// <see>Startup.UserFilesOptions</see>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[MaxLength(512)]
|
||||
public string? Avatar { get; set; }
|
||||
|
||||
[MaxLength(512)]
|
||||
public string? FullName { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// WIP Paypal
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Display(Name = "Account balance")]
|
||||
public virtual AccountBalance? AccountBalance { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// User's posts
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[InverseProperty("Author"), JsonIgnore]
|
||||
public virtual List<Blog.BlogPost>? Posts { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// User's contact list
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[InverseProperty("Owner"), JsonIgnore]
|
||||
public virtual List<Contact>? Book { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// External devices using the API
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[InverseProperty("DeviceOwner"), JsonIgnore]
|
||||
public virtual List<DeviceDeclaration>? DeviceDeclaration { get; set; }
|
||||
|
||||
[InverseProperty("Owner"), JsonIgnore]
|
||||
public virtual List<ChatConnection>? Connections { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// User's circles
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[InverseProperty("Owner"), JsonIgnore]
|
||||
|
||||
public virtual List<Circle>? Circles { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Billing postal address
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[ForeignKey("PostalAddressId")]
|
||||
public virtual Location? PostalAddress { get; set; }
|
||||
public long? PostalAddressId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// User's Google calendar
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[MaxLength(512)]
|
||||
public string? DedicatedGoogleCalendar { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return this.Id + " " + this.AccountBalance?.Credits.ToString() + this.Email + " " + this.UserName + " $" + this.AccountBalance?.Credits.ToString();
|
||||
}
|
||||
|
||||
public virtual List<BankIdentity>? BankInfo { get; set; }
|
||||
|
||||
public long DiskQuota { get; set; } = 512 * 1024 * 1024;
|
||||
public long DiskUsage { get; set; } = 0;
|
||||
|
||||
public long MaxFileSize { get; set; } = 512 * 1024 * 1024;
|
||||
|
||||
[JsonIgnore]
|
||||
[InverseProperty("Owner")]
|
||||
public virtual List<BlackListed>? BlackList { get; set; }
|
||||
|
||||
public bool AllowMonthlyEmail { get; set; } = false;
|
||||
|
||||
[JsonIgnore]
|
||||
[InverseProperty("Owner")]
|
||||
public virtual List<ChatRoom>? Rooms { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[InverseProperty("User")]
|
||||
public virtual List<ChatRoomAccess>? RoomAccess { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
[InverseProperty("Member")]
|
||||
public virtual List<CircleMember>? Membership { get; set; }
|
||||
|
||||
IAccountBalance? IApplicationUser.AccountBalance => AccountBalance;
|
||||
|
||||
ILocation? IApplicationUser.PostalAddress { get => PostalAddress; }
|
||||
}
|
||||
}
|
||||
10
src/Server/Models/Auth/ApplicationTypes.cs
Normal file
10
src/Server/Models/Auth/ApplicationTypes.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
|
||||
namespace Yavsc.Models.Auth
|
||||
{
|
||||
public enum ApplicationTypes: int
|
||||
{
|
||||
JavaScript = 0,
|
||||
NativeConfidential = 1
|
||||
};
|
||||
}
|
||||
42
src/Server/Models/Auth/DeviceDeclaration.cs
Normal file
42
src/Server/Models/Auth/DeviceDeclaration.cs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Yavsc.Models.Identity
|
||||
{
|
||||
[JsonObject]
|
||||
|
||||
public class DeviceDeclaration : IMobileDeviceDeclaration {
|
||||
|
||||
|
||||
[Key,Required]
|
||||
public string DeviceId { get; set; }
|
||||
|
||||
public string Model { get; set; }
|
||||
public string Platform { get; set; }
|
||||
public string Version { get; set; }
|
||||
public string DeviceOwnerId { get; set; }
|
||||
public DateTime DeclarationDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Latest Activity Update
|
||||
///
|
||||
/// Let's says,
|
||||
/// the latest time this device downloaded functional info from server
|
||||
/// activity list, let's say, promoted ones, those thar are at index, and
|
||||
/// all others, that are not listed as unsupported ones (not any more, after
|
||||
/// has been annonced as obsolete a decent laps of time).
|
||||
///
|
||||
/// In order to say, is any activity has changed here.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public DateTime ? LatestActivityUpdate { get; set; }
|
||||
|
||||
[JsonIgnore,ForeignKey("DeviceOwnerId")]
|
||||
public virtual ApplicationUser DeviceOwner { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
33
src/Server/Models/Auth/ExternalViewModel.cs
Normal file
33
src/Server/Models/Auth/ExternalViewModel.cs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Yavsc.Models.Auth {
|
||||
|
||||
public class ExternalLoginViewModel
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Url { get; set; }
|
||||
|
||||
public string State { get; set; }
|
||||
}
|
||||
|
||||
public class RegisterExternalBindingModel
|
||||
{
|
||||
[Required]
|
||||
public string UserName { get; set; }
|
||||
|
||||
[Required]
|
||||
public string Provider { get; set; }
|
||||
|
||||
[Required]
|
||||
public string ExternalAccessToken { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class ParsedExternalAccessToken
|
||||
{
|
||||
public string user_id { get; set; }
|
||||
public string app_id { get; set; }
|
||||
}
|
||||
}
|
||||
48
src/Server/Models/Auth/OAuth2Tokens.cs
Normal file
48
src/Server/Models/Auth/OAuth2Tokens.cs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Yavsc.Models.Auth
|
||||
{
|
||||
/// <summary>
|
||||
/// OffLine OAuth2 Token
|
||||
/// To use against a third party Api
|
||||
/// </summary>
|
||||
public partial class OAuth2Tokens
|
||||
{
|
||||
/// <summary>
|
||||
/// Unique identifier, equals the user email from OAuth provider
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Key]
|
||||
public string UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Expiration date & time
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public DateTime Expiration { get; set; }
|
||||
/// <summary>
|
||||
/// Expiration time span in seconds
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string ExpiresIn { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Should always be <c>Bearer</c> ...
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string TokenType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The Access Token!
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string AccessToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The refresh token
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string RefreshToken { get; set; }
|
||||
}
|
||||
}
|
||||
23
src/Server/Models/Auth/RefreshToken.cs
Normal file
23
src/Server/Models/Auth/RefreshToken.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Yavsc.Models.Auth
|
||||
{
|
||||
|
||||
|
||||
public class RefreshToken
|
||||
{
|
||||
[Key]
|
||||
public string Id { get; set; }
|
||||
[Required]
|
||||
[MaxLength(50)]
|
||||
public string Subject { get; set; }
|
||||
[Required]
|
||||
[MaxLength(50)]
|
||||
public string ClientId { get; set; }
|
||||
public DateTime IssuedUtc { get; set; }
|
||||
public DateTime ExpiresUtc { get; set; }
|
||||
[Required]
|
||||
public string ProtectedTicket { get; set; }
|
||||
}
|
||||
}
|
||||
20
src/Server/Models/Auth/UserCredentials.cs
Normal file
20
src/Server/Models/Auth/UserCredentials.cs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
namespace Yavsc.Models.Auth {
|
||||
|
||||
public class UserCredential {
|
||||
public string UserId { get; set; }
|
||||
|
||||
public OAuth2Tokens Tokens { get; set; }
|
||||
public UserCredential(string userId, OAuth2Tokens tokens)
|
||||
{
|
||||
UserId = userId;
|
||||
Tokens = tokens;
|
||||
}
|
||||
|
||||
public string GetHeader()
|
||||
{
|
||||
return Tokens.TokenType+" "+Tokens.AccessToken;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
22
src/Server/Models/Bank/AccountBalance.cs
Normal file
22
src/Server/Models/Bank/AccountBalance.cs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
using Yavsc;
|
||||
|
||||
public partial class AccountBalance: IAccountBalance {
|
||||
|
||||
[Key]
|
||||
public string UserId { get; set; }
|
||||
|
||||
[ForeignKey("UserId")]
|
||||
public virtual ApplicationUser Owner { get; set; }
|
||||
|
||||
[Required,Display(Name="Credits en €")]
|
||||
public decimal Credits { get; set; }
|
||||
|
||||
public long ContactCredits { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
26
src/Server/Models/Bank/BalanceImpact.cs
Normal file
26
src/Server/Models/Bank/BalanceImpact.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
public partial class BalanceImpact {
|
||||
[Required,Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Required,Display(Name="Impact")]
|
||||
public decimal Impact { get; set; }
|
||||
|
||||
[Required,Display(Name="Execution date")]
|
||||
public DateTime ExecDate { get; set; }
|
||||
|
||||
[Required,Display(Name="Reason")]
|
||||
public string Reason { get; set; }
|
||||
[Required]
|
||||
public string BalanceId { get; set; }
|
||||
|
||||
[ForeignKey("BalanceId")]
|
||||
public virtual AccountBalance Balance { get; set; }
|
||||
}
|
||||
}
|
||||
79
src/Server/Models/Bank/BankIdentity.cs
Normal file
79
src/Server/Models/Bank/BankIdentity.cs
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
using System.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Yavsc.Attributes.Validation;
|
||||
|
||||
namespace Yavsc.Models.Bank
|
||||
{
|
||||
public class BankIdentity
|
||||
{
|
||||
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the BI.
|
||||
/// </summary>
|
||||
/// <value>The BI.</value>
|
||||
[DisplayName("Code BIC")]
|
||||
[YaStringLength(15)]
|
||||
public string BIC { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the IBA.
|
||||
/// </summary>
|
||||
/// <value>The IBA.</value>
|
||||
[DisplayName("Code IBAN")]
|
||||
[YaStringLength(33)]
|
||||
public string IBAN { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the bank code.
|
||||
/// </summary>
|
||||
/// <value>The bank code.</value>
|
||||
[DisplayName("Code Banque")]
|
||||
[YaStringLength(5)]
|
||||
public string BankCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the wicket code.
|
||||
/// </summary>
|
||||
/// <value>The wicket code.</value>
|
||||
[DisplayName("Code Guichet")]
|
||||
[YaStringLength(5)]
|
||||
public string WicketCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the account number.
|
||||
/// </summary>
|
||||
/// <value>The account number.</value>
|
||||
[DisplayName("Numéro de compte")]
|
||||
[YaStringLength(15)]
|
||||
public string AccountNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the banked key.
|
||||
/// </summary>
|
||||
/// <value>The banked key.</value>
|
||||
[DisplayName("Clé RIB")]
|
||||
public int BankedKey { get; set; }
|
||||
|
||||
public virtual ApplicationUser User { get; set; }
|
||||
|
||||
public string UserId { get; set; }
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
if (obj==null) return false;
|
||||
if (! typeof(BankIdentity).IsAssignableFrom(obj.GetType())) return false;
|
||||
BankIdentity tobj = (BankIdentity)obj;
|
||||
return tobj.IBAN == IBAN &&
|
||||
tobj.BIC == BIC &&
|
||||
tobj.AccountNumber == AccountNumber &&
|
||||
tobj.BankedKey == BankedKey;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
48
src/Server/Models/Billing/CommandLine.cs
Normal file
48
src/Server/Models/Billing/CommandLine.cs
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Yavsc.Models.Billing
|
||||
{
|
||||
using Yavsc.Billing;
|
||||
|
||||
public class CommandLine : ICommandLine {
|
||||
|
||||
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Required,MaxLength(256)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Required,MaxLength(512)]
|
||||
public string Description { get; set; }
|
||||
|
||||
[Display(Name="Nombre")]
|
||||
public int Count { get; set; } = 1;
|
||||
|
||||
[DisplayFormat(DataFormatString="{0:C}")]
|
||||
public decimal UnitaryCost { get; set; }
|
||||
|
||||
public long EstimateId { get; set; }
|
||||
|
||||
[JsonIgnore,NotMapped,ForeignKey("EstimateId")]
|
||||
virtual public Estimate Estimate { get; set; }
|
||||
|
||||
public string Currency
|
||||
{
|
||||
get;
|
||||
|
||||
set;
|
||||
} = "EUR";
|
||||
|
||||
[NotMapped]
|
||||
public string Reference {
|
||||
get {
|
||||
return "CL/"+this.Id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
10
src/Server/Models/Billing/Contract.cs
Normal file
10
src/Server/Models/Billing/Contract.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using Yavsc.Models.Market;
|
||||
|
||||
namespace Yavsc.Models.Billing
|
||||
{
|
||||
public class ServiceContract<P> where P : Service
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
81
src/Server/Models/Billing/Estimate.cs
Normal file
81
src/Server/Models/Billing/Estimate.cs
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
|
||||
namespace Yavsc.Models.Billing
|
||||
{
|
||||
using Models.Workflow;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
public partial class Estimate : IEstimate
|
||||
{
|
||||
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long Id { get; set; }
|
||||
|
||||
public long? CommandId { get; set; }
|
||||
/// <summary>
|
||||
/// A command is not required to create
|
||||
/// an estimate,
|
||||
/// it will result in a new estimate template
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[ForeignKey("CommandId"),JsonIgnore]
|
||||
public RdvQuery Query { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Title { get; set; }
|
||||
|
||||
[InverseProperty("Estimate")]
|
||||
public virtual List<CommandLine> Bill { get; set; }
|
||||
/// <summary>
|
||||
/// List of attached graphic files
|
||||
/// to this estimate, as relative pathes to
|
||||
/// the command performer's root path.
|
||||
/// In db, they are separated by <c>:</c>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[NotMapped]
|
||||
public List<string> AttachedGraphics { get; set; }
|
||||
|
||||
public string AttachedGraphicsString
|
||||
{
|
||||
get { return string.Join(":", AttachedGraphics); }
|
||||
set { AttachedGraphics = value.Split(':').ToList(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// List of attached files
|
||||
/// to this estimate, as relative pathes to
|
||||
/// the command performer's root path.
|
||||
/// In db, they are separated by <c>:</c>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[NotMapped]
|
||||
public List<string> AttachedFiles { get; set; }
|
||||
public string AttachedFilesString
|
||||
{
|
||||
get { return string.Join(":", AttachedFiles); }
|
||||
set { AttachedFiles = value.Split(':').ToList(); }
|
||||
}
|
||||
|
||||
public string OwnerId { get; set; }
|
||||
|
||||
[ForeignKey("OwnerId"),JsonIgnore]
|
||||
public virtual PerformerProfile Owner { get; set; }
|
||||
|
||||
[Required]
|
||||
public string ClientId { get; set; }
|
||||
[ForeignKey("ClientId"),JsonIgnore]
|
||||
public virtual ApplicationUser Client { get; set; }
|
||||
|
||||
[Required]
|
||||
public string CommandType
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
public DateTime ProviderValidationDate { get; set; }
|
||||
public DateTime ClientValidationDate { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
20
src/Server/Models/Billing/EstimateTemplate.cs
Normal file
20
src/Server/Models/Billing/EstimateTemplate.cs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models.Billing
|
||||
{
|
||||
public partial class EstimateTemplate
|
||||
{
|
||||
|
||||
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long Id { get; set; }
|
||||
public string Description { get; set; }
|
||||
public string Title { get; set; }
|
||||
public List<CommandLine> Bill { get; set; }
|
||||
|
||||
[Required]
|
||||
public string OwnerId { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
11
src/Server/Models/Billing/ExceptionSIREN.cs
Normal file
11
src/Server/Models/Billing/ExceptionSIREN.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using Yavsc.Attributes.Validation;
|
||||
|
||||
namespace Yavsc.Models.Billing
|
||||
{
|
||||
public class ExceptionSIREN {
|
||||
|
||||
[Key, YaStringLength(9, 9)]
|
||||
public string SIREN { get; set; }
|
||||
}
|
||||
}
|
||||
16
src/Server/Models/Billing/FixedImpacter.cs
Normal file
16
src/Server/Models/Billing/FixedImpacter.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
using Yavsc.Billing;
|
||||
|
||||
namespace Yavsc.Models.Billing {
|
||||
public class FixedImpacter : IBillingImpacter
|
||||
{
|
||||
public decimal ImpactedValue { get; set; }
|
||||
public FixedImpacter (decimal impact)
|
||||
{
|
||||
ImpactedValue = impact;
|
||||
}
|
||||
public decimal Impact(decimal orgValue)
|
||||
{
|
||||
return orgValue + ImpactedValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
107
src/Server/Models/Billing/NominativeServiceCommand.cs
Normal file
107
src/Server/Models/Billing/NominativeServiceCommand.cs
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models.Billing
|
||||
{
|
||||
using Newtonsoft.Json;
|
||||
using Workflow;
|
||||
using Yavsc.Models.Payment;
|
||||
using Yavsc;
|
||||
using Yavsc.Billing;
|
||||
using Yavsc.Abstract.Workflow;
|
||||
using Yavsc.Services;
|
||||
|
||||
public abstract class NominativeServiceCommand : IDecidableQuery, IIdentified<long>, IBillable
|
||||
{
|
||||
public string GetInvoiceId() { return GetType().Name + "/" + Id; }
|
||||
|
||||
public abstract long Id { get; set; }
|
||||
public abstract string Description { get; set; }
|
||||
|
||||
[Required()]
|
||||
public bool Consent { get; set; }
|
||||
public DateTime DateCreated
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public DateTime DateModified
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public string UserCreated
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public string UserModified
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
[DisplayAttribute(Name="Status de la requête")]
|
||||
public QueryStatus Status { get; set; }
|
||||
|
||||
[Required]
|
||||
public string ClientId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The client
|
||||
/// </summary>
|
||||
[ForeignKey("ClientId"),Display(Name="Client")]
|
||||
public ApplicationUser Client { get; set; }
|
||||
|
||||
[Required]
|
||||
public string PerformerId { get; set; }
|
||||
/// <summary>
|
||||
/// The performer identifier
|
||||
/// </summary>
|
||||
[ForeignKey("PerformerId"),Display(Name="Préstataire")]
|
||||
public PerformerProfile PerformerProfile { get; set; }
|
||||
|
||||
public DateTime? ValidationDate {get; set;}
|
||||
|
||||
|
||||
[Display(Name="Previsional")]
|
||||
public decimal? Previsional { get; set; }
|
||||
/// <summary>
|
||||
/// The bill
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
|
||||
[Required]
|
||||
public string ActivityCode { get; set; }
|
||||
|
||||
[ForeignKey("ActivityCode"),JsonIgnore,Display(Name="Domaine d'activité")]
|
||||
public virtual Activity Context { get; set ; }
|
||||
|
||||
public bool Decided { get; set; }
|
||||
|
||||
|
||||
public abstract System.Collections.Generic.List<IBillItem> GetBillItems();
|
||||
|
||||
public bool GetIsAcquitted()
|
||||
{
|
||||
return Regularisation?.IsOk() ?? false;
|
||||
}
|
||||
|
||||
public string GetFileBaseName(IBillingService billingService)
|
||||
{
|
||||
string type = GetType().Name;
|
||||
string ack = GetIsAcquitted() ? "-ack" : null;
|
||||
var bcode = billingService.BillingMap[type];
|
||||
return $"facture-{bcode}-{Id}{ack}";
|
||||
}
|
||||
|
||||
[ForeignKey("Regularisation")]
|
||||
|
||||
public string? PaymentId { get; set; }
|
||||
|
||||
[Display(Name = "Acquittement de la facture")]
|
||||
public virtual PayPalPayment Regularisation { get; set; }
|
||||
public bool Accepted { get; set; }
|
||||
}
|
||||
}
|
||||
13
src/Server/Models/Billing/ProportionalImpacter.cs
Normal file
13
src/Server/Models/Billing/ProportionalImpacter.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
using Yavsc.Billing;
|
||||
|
||||
namespace Yavsc.Models.Billing {
|
||||
public class ProportionalImpacter : IBillingImpacter
|
||||
{
|
||||
public decimal K { get; set; }
|
||||
public decimal Impact(decimal orgValue)
|
||||
{
|
||||
return orgValue * K;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
33
src/Server/Models/Billing/ReductionCode.cs
Normal file
33
src/Server/Models/Billing/ReductionCode.cs
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Yavsc.Billing;
|
||||
|
||||
namespace Yavsc.Models.Billing {
|
||||
|
||||
public class ReductionCode : IBillingClause
|
||||
{
|
||||
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long Id { get; set; }
|
||||
public ReductionCode(string descr, decimal impact) {
|
||||
Description = descr;
|
||||
impacter = new FixedImpacter(impact);
|
||||
}
|
||||
public string Description
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
IBillingImpacter impacter;
|
||||
public IBillingImpacter Impacter
|
||||
{
|
||||
get
|
||||
{
|
||||
return impacter ;
|
||||
}
|
||||
private set {
|
||||
impacter = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
5
src/Server/Models/Billing/Service/ChatBilling.cs
Normal file
5
src/Server/Models/Billing/Service/ChatBilling.cs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
|
||||
class ChatBilling {
|
||||
|
||||
}
|
||||
14
src/Server/Models/Billing/histoestim.cs
Normal file
14
src/Server/Models/Billing/histoestim.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
|
||||
namespace Yavsc.Models.Billing
|
||||
{
|
||||
public partial class histoestim
|
||||
{
|
||||
public long _id { get; set; }
|
||||
public string applicationname { get; set; }
|
||||
public DateTime datechange { get; set; }
|
||||
public long estid { get; set; }
|
||||
public int? status { get; set; }
|
||||
public string username { get; set; }
|
||||
}
|
||||
}
|
||||
93
src/Server/Models/Blog/BlogPost.cs
Normal file
93
src/Server/Models/Blog/BlogPost.cs
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Newtonsoft.Json;
|
||||
using Yavsc;
|
||||
using Yavsc.Abstract.Identity;
|
||||
using Yavsc.Abstract.Identity.Security;
|
||||
using Yavsc.Attributes.Validation;
|
||||
using Yavsc.Interfaces;
|
||||
using Yavsc.Models.Access;
|
||||
using Yavsc.Models.Relationship;
|
||||
using Yavsc.ViewModels.Blog;
|
||||
|
||||
namespace Yavsc.Models.Blog
|
||||
{
|
||||
public class BlogPost : BlogPostBase,
|
||||
IBlogPost, ICircleAuthorized, ITaggable<long>
|
||||
{
|
||||
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
[Display(Name="Identifiant du post")]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Display(Name="Identifiant de l'auteur")]
|
||||
[ForeignKey("Author")]
|
||||
public string? AuthorId { get; set; }
|
||||
|
||||
[Display(Name="Auteur")]
|
||||
public virtual ApplicationUser? Author { set; get; }
|
||||
|
||||
|
||||
[Display(Name="Date de création")]
|
||||
public DateTime DateCreated
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
[Display(Name="Créateur")]
|
||||
public string? UserCreated
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
[Display(Name="Dernière modification")]
|
||||
public DateTime DateModified
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
[Display(Name="Utilisateur ayant modifé le dernier")]
|
||||
public string? UserModified
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public bool AuthorizeCircle(long circleId)
|
||||
{
|
||||
return ACL?.Any( i=>i.CircleId == circleId) ?? true;
|
||||
}
|
||||
|
||||
public ICircleAuthorization[] GetACL()
|
||||
{
|
||||
return ACL.ToArray();
|
||||
}
|
||||
|
||||
public void Tag(Tag tag)
|
||||
{
|
||||
var existent = Tags.SingleOrDefault(t => t.PostId == Id && t.TagId == tag.Id);
|
||||
if (existent==null) Tags.Add(new BlogTag { PostId = Id, Tag = tag } );
|
||||
}
|
||||
|
||||
public void DeTag(Tag tag)
|
||||
{
|
||||
var existent = Tags.SingleOrDefault(t => (( t.TagId == tag.Id) && t.PostId == Id));
|
||||
if (existent!=null) Tags.Remove(existent);
|
||||
}
|
||||
|
||||
public string[] GetTags()
|
||||
{
|
||||
return Tags.Select(t=>t.Tag.Name).ToArray();
|
||||
}
|
||||
|
||||
[InverseProperty("Post")]
|
||||
public virtual List<BlogTag> Tags { get; set; }
|
||||
|
||||
[InverseProperty("Post")]
|
||||
public virtual List<Comment> Comments { get; set; }
|
||||
|
||||
IApplicationUser IBlogPost.Author { get => this.Author; }
|
||||
}
|
||||
}
|
||||
16
src/Server/Models/Blog/BlogTag.cs
Normal file
16
src/Server/Models/Blog/BlogTag.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Yavsc.Models.Relationship;
|
||||
|
||||
namespace Yavsc.Models.Blog
|
||||
{
|
||||
public partial class BlogTag
|
||||
{
|
||||
[ForeignKey("PostId")]
|
||||
public virtual BlogPost Post { get; set; }
|
||||
public long PostId { get; set; }
|
||||
|
||||
[ForeignKey("TagId")]
|
||||
public virtual Tag Tag{ get; set; }
|
||||
public long TagId { get; set; }
|
||||
}
|
||||
}
|
||||
15
src/Server/Models/Blog/BlogspotPublication.cs
Normal file
15
src/Server/Models/Blog/BlogspotPublication.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Yavsc.Models.Blog;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
public class BlogSpotPublication
|
||||
{
|
||||
[Key]
|
||||
public long BlogpostId { get; set; }
|
||||
|
||||
[ForeignKey("BlogpostId")]
|
||||
public virtual BlogPost BlogPost{ get; set; }
|
||||
}
|
||||
}
|
||||
63
src/Server/Models/Blog/Comment.cs
Normal file
63
src/Server/Models/Blog/Comment.cs
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Newtonsoft.Json;
|
||||
using Yavsc.Attributes.Validation;
|
||||
using Yavsc.Interfaces;
|
||||
|
||||
namespace Yavsc.Models.Blog
|
||||
{
|
||||
public class Comment : IComment<long>, ITrackedEntity
|
||||
{
|
||||
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long Id { get; set; }
|
||||
|
||||
[YaStringLength(1024)]
|
||||
public string Content { get; set; }
|
||||
|
||||
[ForeignKeyAttribute(nameof(ReceiverId))][JsonIgnore]
|
||||
public virtual BlogPost Post { get; set; }
|
||||
|
||||
[Required]
|
||||
public long ReceiverId { get; set; }
|
||||
public bool Visible { get; set; }
|
||||
|
||||
[ForeignKeyAttribute("AuthorId")][JsonIgnore]
|
||||
public virtual ApplicationUser Author {
|
||||
get; set;
|
||||
}
|
||||
|
||||
[Required]
|
||||
public string AuthorId
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public string UserCreated { get => AuthorId; set => AuthorId=value; }
|
||||
|
||||
public DateTime DateModified
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public string UserModified
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public DateTime DateCreated
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public long? ParentId { get; set; }
|
||||
|
||||
[ForeignKeyAttribute("ParentId")]
|
||||
public virtual Comment? Parent { get; set; }
|
||||
|
||||
[InversePropertyAttribute("Parent")]
|
||||
|
||||
public virtual List<Comment> Children { get; set; }
|
||||
}
|
||||
}
|
||||
9
src/Server/Models/Calendar/Availabliity.cs
Normal file
9
src/Server/Models/Calendar/Availabliity.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
using Yavsc.Models.Calendar;
|
||||
|
||||
namespace Yavsc.Server.Models.Calendar
|
||||
{
|
||||
public class Availability : List<Period>
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
52
src/Server/Models/Calendar/Period.cs
Normal file
52
src/Server/Models/Calendar/Period.cs
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
//
|
||||
// Period.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Yavsc.Server.Models.Calendar
|
||||
{
|
||||
/// <summary>
|
||||
/// Hollydays.
|
||||
/// </summary>
|
||||
public class Period {
|
||||
/// <summary>
|
||||
/// Gets or sets the start.
|
||||
/// </summary>
|
||||
/// <value>The start.</value>
|
||||
[Required,Display(Name="Début")]
|
||||
public DateTime Start { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the end.
|
||||
/// </summary>
|
||||
/// <value>The end.</value>
|
||||
[Required,Display(Name="Fin")]
|
||||
public DateTime End { get; set; }
|
||||
|
||||
public static Period operator ^ (Period foo, Period bar) {
|
||||
var min = ( DateTime.Compare(foo.Start, bar.Start) > 0 ) ? foo.Start : bar.Start;
|
||||
var max = ( DateTime.Compare(bar.End, foo.End) > 0 ) ? foo.End : bar.End;
|
||||
if (DateTime.Compare(max, min)>0) return new Period { Start = min, End = max };
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
59
src/Server/Models/Calendar/Periodicity.cs
Normal file
59
src/Server/Models/Calendar/Periodicity.cs
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
//
|
||||
// Periodicity.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 - 2017 Paul Schneider
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace Yavsc.Server.Models.Calendar
|
||||
{
|
||||
/// <summary>
|
||||
/// Periodicity.
|
||||
/// </summary>
|
||||
public enum Periodicity {
|
||||
|
||||
/// <summary>
|
||||
/// On Demand.
|
||||
/// </summary>
|
||||
OnDemand=-1,
|
||||
/// <summary>
|
||||
/// The daily.
|
||||
/// </summary>
|
||||
Daily,
|
||||
/// <summary>
|
||||
/// The weekly.
|
||||
/// </summary>
|
||||
Weekly,
|
||||
/// <summary>
|
||||
/// The monthly.
|
||||
/// </summary>
|
||||
Monthly,
|
||||
/// <summary>
|
||||
/// The three m.
|
||||
/// </summary>
|
||||
ThreeM,
|
||||
/// <summary>
|
||||
/// The six m.
|
||||
/// </summary>
|
||||
SixM,
|
||||
/// <summary>
|
||||
/// The yearly.
|
||||
/// </summary>
|
||||
Yearly
|
||||
}
|
||||
|
||||
}
|
||||
42
src/Server/Models/Calendar/PositionAndKeyphrase.cs
Normal file
42
src/Server/Models/Calendar/PositionAndKeyphrase.cs
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
//
|
||||
// PositionAndKeyphrase.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 - 2017 Paul Schneider
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
|
||||
using Yavsc.Models.Relationship;
|
||||
|
||||
namespace Yavsc.Server.Models.Calendar
|
||||
{
|
||||
/// <summary>
|
||||
/// Position and keyphrase.
|
||||
/// </summary>
|
||||
public class PositionAndKeyphrase {
|
||||
/// <summary>
|
||||
/// The phrase.
|
||||
/// </summary>
|
||||
public string phrase;
|
||||
/// <summary>
|
||||
/// The position.
|
||||
/// </summary>
|
||||
public Position pos;
|
||||
}
|
||||
|
||||
}
|
||||
45
src/Server/Models/Calendar/ProvidedEvent.cs
Normal file
45
src/Server/Models/Calendar/ProvidedEvent.cs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// ProvidedEvent.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Yavsc.Models.Messaging;
|
||||
using Yavsc.Models.Access;
|
||||
|
||||
namespace Yavsc.Models.Calendar
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Provided event.
|
||||
/// </summary>
|
||||
public class ProvidedEvent : BaseEvent {
|
||||
/// <summary>
|
||||
/// The privacy.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Publishing Privacy;
|
||||
|
||||
public override string CreateBody()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
64
src/Server/Models/Calendar/Schedule.cs
Normal file
64
src/Server/Models/Calendar/Schedule.cs
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
//
|
||||
// Schedule.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//
|
||||
// Calendar.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 - 2017 Paul Schneider
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models.Calendar
|
||||
{
|
||||
/// <summary>
|
||||
/// Le calendrier, l'emploi du temps.
|
||||
/// </summary>
|
||||
public class Schedule {
|
||||
|
||||
[Key,Required]
|
||||
public string OwnerId { get; set; }
|
||||
|
||||
[ForeignKey("OwnerId")]
|
||||
[Display(Name="Professionnel")]
|
||||
public virtual ApplicationUser Owner { get ; set; }
|
||||
|
||||
public ScheduledEvent [] Events { get ; set; }
|
||||
}
|
||||
|
||||
}
|
||||
46
src/Server/Models/Calendar/ScheduledEvent.cs
Normal file
46
src/Server/Models/Calendar/ScheduledEvent.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// ScheduledEvent.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 - 2017 Paul Schneider
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Yavsc.Server.Models.Calendar;
|
||||
|
||||
namespace Yavsc.Models.Calendar
|
||||
{
|
||||
public class ScheduledEvent : IScheduledEvent
|
||||
{
|
||||
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long Id { get; set; }
|
||||
public Period Period
|
||||
{
|
||||
get;
|
||||
|
||||
set;
|
||||
}
|
||||
|
||||
public Periodicity Reccurence
|
||||
{
|
||||
get;
|
||||
|
||||
set;
|
||||
}
|
||||
}
|
||||
}
|
||||
58
src/Server/Models/Calendar/WeekDay.cs
Normal file
58
src/Server/Models/Calendar/WeekDay.cs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
//
|
||||
// WeekDay.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
namespace Yavsc.Models.Calendar
|
||||
{
|
||||
/// <summary>
|
||||
/// Week day.
|
||||
/// </summary>
|
||||
public enum WeekDay:int {
|
||||
/// <summary>
|
||||
/// The monday (0).
|
||||
/// </summary>
|
||||
Monday=0,
|
||||
/// <summary>
|
||||
/// The tuesday.
|
||||
/// </summary>
|
||||
Tuesday,
|
||||
/// <summary>
|
||||
/// The wednesday.
|
||||
/// </summary>
|
||||
Wednesday,
|
||||
/// <summary>
|
||||
/// The thursday.
|
||||
/// </summary>
|
||||
Thursday,
|
||||
/// <summary>
|
||||
/// The friday.
|
||||
/// </summary>
|
||||
Friday,
|
||||
/// <summary>
|
||||
/// The saturday.
|
||||
/// </summary>
|
||||
Saturday,
|
||||
/// <summary>
|
||||
/// The sunday.
|
||||
/// </summary>
|
||||
Sunday
|
||||
}
|
||||
|
||||
}
|
||||
46
src/Server/Models/Chat/ChatConnection.cs
Normal file
46
src/Server/Models/Chat/ChatConnection.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// Connection.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 - 2017 Paul Schneider
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models.Chat
|
||||
{
|
||||
public class ChatConnection
|
||||
{
|
||||
[Required]
|
||||
public string ApplicationUserId { get; set; }
|
||||
|
||||
[ForeignKey("ApplicationUserId"),JsonIgnore]
|
||||
public virtual ApplicationUser Owner { get; set; }
|
||||
|
||||
[Key]
|
||||
public string ConnectionId { get; set; }
|
||||
|
||||
public string UserAgent { get; set; }
|
||||
|
||||
public bool Connected { get; set; }
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
35
src/Server/Models/Chat/ChatRoom.cs
Normal file
35
src/Server/Models/Chat/ChatRoom.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Newtonsoft.Json;
|
||||
using Yavsc.Abstract.Chat;
|
||||
using Yavsc.Attributes.Validation;
|
||||
|
||||
namespace Yavsc.Models.Chat
|
||||
{
|
||||
public class ChatRoom: IChatRoom<ChatRoomAccess>, ITrackedEntity
|
||||
{
|
||||
public string Topic { get; set; }
|
||||
|
||||
[Key]
|
||||
[YaStringLength(ChatHubConstants.MaxChanelName, MinimumLength=3)]
|
||||
public string Name { get; set;}
|
||||
|
||||
public string OwnerId { get; set; }
|
||||
|
||||
[ForeignKey("OwnerId")][JsonIgnore]
|
||||
public virtual ApplicationUser Owner { get; set; }
|
||||
|
||||
[InverseProperty("Room")][JsonIgnore]
|
||||
public virtual List<ChatRoomAccess> Moderation { get; set; }
|
||||
public DateTime LatestJoinPart { get; set;}
|
||||
|
||||
public DateTime DateCreated { get; set; }
|
||||
|
||||
public string UserCreated { get; set; }
|
||||
public DateTime DateModified { get; set;}
|
||||
public string UserModified { get; set; }
|
||||
}
|
||||
}
|
||||
31
src/Server/Models/Chat/ChatRoomAccess.cs
Normal file
31
src/Server/Models/Chat/ChatRoomAccess.cs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using Yavsc.Abstract.Chat;
|
||||
|
||||
namespace Yavsc.Models.Chat
|
||||
{
|
||||
public class ChatRoomAccess: IChatRoomAccess
|
||||
{
|
||||
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long Id
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
public string ChannelName { get; set; }
|
||||
[ForeignKey("ChannelName")]
|
||||
public virtual ChatRoom Room { get; set; }
|
||||
|
||||
[Required]
|
||||
public string UserId { get; set; }
|
||||
|
||||
public ChatRoomAccessLevel Level
|
||||
{
|
||||
get; set;
|
||||
}
|
||||
|
||||
[ForeignKey("UserId")]
|
||||
public virtual ApplicationUser User { get; set; }
|
||||
}
|
||||
}
|
||||
16
src/Server/Models/ConsentOptions.cs
Normal file
16
src/Server/Models/ConsentOptions.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
// Copyright (c) Brock Allen & Dominick Baier. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See LICENSE in the project root for license information.
|
||||
|
||||
|
||||
namespace Yavsc
|
||||
{
|
||||
public class ConsentOptions
|
||||
{
|
||||
public static bool EnableOfflineAccess = true;
|
||||
public static string OfflineAccessDisplayName = "Offline Access";
|
||||
public static string OfflineAccessDescription = "Access to your applications and resources, even when you are offline";
|
||||
|
||||
public static readonly string MustChooseOneErrorMessage = "You must pick at least one permission";
|
||||
public static readonly string InvalidSelectionErrorMessage = "Invalid selection";
|
||||
}
|
||||
}
|
||||
15
src/Server/Models/Cratie/AName/NameSubmission.cs
Normal file
15
src/Server/Models/Cratie/AName/NameSubmission.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Yavsc.Models.Cratie.AName
|
||||
{
|
||||
public class NameSubmission : Submission
|
||||
{
|
||||
[RegularExpression(@"[a-zA-Z]+", ErrorMessage = "Nom invalide (seules les lettres de l'alphabet sont autorisées).", ErrorMessageResourceName = "EInvalidName")]
|
||||
|
||||
public string FirstChoice {get; set;}
|
||||
[RegularExpression(@"[a-zA-Z]+", ErrorMessage = "Nom invalide (seules les lettres de l'alphabet sont autorisées).", ErrorMessageResourceName = "EInvalidName")]
|
||||
public string SecondChoice {get; set;}
|
||||
[RegularExpression(@"[a-zA-Z]+", ErrorMessage = "Nom invalide (seules les lettres de l'alphabet sont autorisées).", ErrorMessageResourceName = "EInvalidName")]
|
||||
public string ThirdChoice {get; set;}
|
||||
}
|
||||
}
|
||||
15
src/Server/Models/Cratie/Option.cs
Normal file
15
src/Server/Models/Cratie/Option.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
using System;
|
||||
|
||||
namespace Yavsc.Models.Cratie
|
||||
{
|
||||
public class Option: ITrackedEntity
|
||||
{
|
||||
public string CodeScrutin { get; set; }
|
||||
public string Code { get; set ; }
|
||||
public string Description { get; set; }
|
||||
public DateTime DateCreated { get ; set ; }
|
||||
public string UserCreated { get ; set ; }
|
||||
public DateTime DateModified { get ; set ; }
|
||||
public string UserModified { get ; set ; }
|
||||
}
|
||||
}
|
||||
16
src/Server/Models/Cratie/Scrutin.cs
Normal file
16
src/Server/Models/Cratie/Scrutin.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Yavsc.Models.Cratie
|
||||
{
|
||||
public class Scrutin : ITrackedEntity
|
||||
{
|
||||
[Key]
|
||||
public string Code { get; set ; }
|
||||
public string Description { get ; set ; }
|
||||
public DateTime DateCreated { get; set; }
|
||||
public string UserCreated { get; set; }
|
||||
public DateTime DateModified { get; set; }
|
||||
public string UserModified { get; set; }
|
||||
}
|
||||
}
|
||||
19
src/Server/Models/Cratie/Submission.cs
Normal file
19
src/Server/Models/Cratie/Submission.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models.Cratie
|
||||
{
|
||||
public class Submission
|
||||
{
|
||||
[ForeignKey("CodeScrutin")]
|
||||
public virtual Scrutin Context { get; set; }
|
||||
public string CodeScrutin { get; set ; }
|
||||
|
||||
[ForeignKey("CodeOption")]
|
||||
public virtual Option Choice { get; set; }
|
||||
public string CodeOption { get; set; }
|
||||
|
||||
[ForeignKey("AuthorId")]
|
||||
public virtual ApplicationUser Author { get; set; }
|
||||
public string AuthorId { get ; set ;}
|
||||
}
|
||||
}
|
||||
46
src/Server/Models/Drawing/Color.cs
Normal file
46
src/Server/Models/Drawing/Color.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// Color.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 - 2017 Paul Schneider
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models.Drawing
|
||||
{
|
||||
public class Color
|
||||
{
|
||||
[Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long Id { get; set; }
|
||||
public Color(){
|
||||
|
||||
}
|
||||
public Color(Color c)
|
||||
{
|
||||
Red=c.Red;
|
||||
Green=c.Green;
|
||||
Blue=c.Blue;
|
||||
Name=c.Name;
|
||||
}
|
||||
public byte Red {get;set;}
|
||||
public byte Green {get;set;}
|
||||
public byte Blue {get;set;}
|
||||
public string Name { get; set; }
|
||||
}
|
||||
}
|
||||
67
src/Server/Models/EMailing/MailingTemplate.cs
Normal file
67
src/Server/Models/EMailing/MailingTemplate.cs
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using RazorEngine.Templating;
|
||||
using Yavsc.Attributes.Validation;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Calendar;
|
||||
using Yavsc.Server.Models.Calendar;
|
||||
|
||||
namespace Yavsc.Server.Models.EMailing
|
||||
{
|
||||
public class MailingTemplate : ITrackedEntity, ITemplateSource
|
||||
{
|
||||
/// <summary>
|
||||
/// Date Created
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public DateTime DateCreated
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
public DateTime DateModified
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
[Key][YaStringLength(3, 256)]
|
||||
public string Id { get; set; }
|
||||
|
||||
[YaStringLength(3, 256)]
|
||||
public string Topic { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Markdown template to process
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[MaxLength(64*1024)]
|
||||
public string Body { get; set; }
|
||||
|
||||
[EmailAddress()]
|
||||
public string ReplyToAddress { get; set; }
|
||||
|
||||
public Periodicity ToSend { get; set; }
|
||||
|
||||
public string UserCreated
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string UserModified
|
||||
{
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public string Template => Body;
|
||||
public string TemplateFile { get => Id; }
|
||||
|
||||
public TextReader GetTemplateReader()
|
||||
{
|
||||
return new StringReader(Body);
|
||||
}
|
||||
}
|
||||
}
|
||||
37
src/Server/Models/Edition/IDocument.cs
Normal file
37
src/Server/Models/Edition/IDocument.cs
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
//
|
||||
// IDocument.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 - 2017 Paul Schneider
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
using System;
|
||||
|
||||
namespace Yavsc.Models {
|
||||
|
||||
public class Parameter {
|
||||
public string Name { get; set; }
|
||||
public string Value { get; set; }
|
||||
}
|
||||
|
||||
[Obsolete("Templates are ala Razor")]
|
||||
public interface IDocument {
|
||||
string Template { get; set; }
|
||||
Parameter [] Parameters { get; set; }
|
||||
}
|
||||
}
|
||||
10
src/Server/Models/ErrorViewModel.cs
Normal file
10
src/Server/Models/ErrorViewModel.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
namespace Yavsc.Models;
|
||||
|
||||
public class ErrorViewModel
|
||||
{
|
||||
public string? RequestId { get; set; }
|
||||
public string? Description { get; set; }
|
||||
|
||||
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
|
||||
|
||||
}
|
||||
54
src/Server/Models/FileSystem/FileReceivedInfo.cs
Normal file
54
src/Server/Models/FileSystem/FileReceivedInfo.cs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
|
||||
//
|
||||
// FileRecievedInfo.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 - 2017 Paul Schneider
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Lesser General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
using Yavsc.Abstract.FileSystem;
|
||||
|
||||
namespace Yavsc.Models.FileSystem
|
||||
{
|
||||
public class FileReceivedInfo : IFileReceivedInfo
|
||||
{
|
||||
public FileReceivedInfo(string destDir, string fileName, bool quotaOffense=false)
|
||||
{
|
||||
this.DestDir = destDir;
|
||||
this.FileName = fileName;
|
||||
this.QuotaOffense = quotaOffense;
|
||||
}
|
||||
public static FileReceivedInfo FromPath(string filePath)
|
||||
{
|
||||
FileInfo fi = new FileInfo(filePath);
|
||||
return new FileReceivedInfo(
|
||||
fi.Directory.FullName,
|
||||
fi.Name
|
||||
);
|
||||
}
|
||||
|
||||
public string DestDir { get; set; }
|
||||
|
||||
public string FileName { get; set; }
|
||||
public bool Overridden { get; set; }
|
||||
|
||||
public bool QuotaOffense { get; set; }
|
||||
public string FullName { get => Path.Combine(DestDir, FileName); }
|
||||
|
||||
}
|
||||
}
|
||||
26
src/Server/Models/FormFile.cs
Normal file
26
src/Server/Models/FormFile.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
using System.IO;
|
||||
using System.Net.Mime;
|
||||
|
||||
namespace Yavsc.Server.Model
|
||||
{
|
||||
public class FormFile
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
string contentDispositionString;
|
||||
public string ContentDisposition { get {
|
||||
return contentDispositionString;
|
||||
} set {
|
||||
ContentDisposition contentDisposition = new ContentDisposition(value);
|
||||
Name = contentDisposition.FileName;
|
||||
contentDispositionString = value;
|
||||
} }
|
||||
|
||||
public string ContentType { get; set; }
|
||||
|
||||
public string FilePath { get; set; }
|
||||
|
||||
public Stream Stream { get; set; }
|
||||
}
|
||||
}
|
||||
12
src/Server/Models/Forms/Form.cs
Normal file
12
src/Server/Models/Forms/Form.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Yavsc.Models.Forms
|
||||
{
|
||||
|
||||
public class Form
|
||||
{
|
||||
[Key]
|
||||
public string Id {get; set;}
|
||||
public string Summary { get; set; }
|
||||
}
|
||||
}
|
||||
17
src/Server/Models/Forms/Validation/Method.cs
Normal file
17
src/Server/Models/Forms/Validation/Method.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Yavsc.Models.Forms.Validation
|
||||
{
|
||||
public class Method
|
||||
{
|
||||
[Key]
|
||||
public string Name {get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// TODO localisation ...
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Required]
|
||||
public string ErrorMessage { get; set; }
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue