public BbsCgiRequest( string rawText, MainContext context, ConnectionInfo connectionInfo, IHeaderDictionary headers, PluginDependency plugin, SessionManager manager) { _sessionManager = manager; _dependency = plugin; var splittedKeys = rawText.Split('&'); var sjis = Encoding.GetEncoding("Shift-JIS"); foreach (var item in splittedKeys) { if (!item.Contains("=")) { throw new ArgumentException(); } var keyValues = item.Split('=').ToList(); var key = keyValues[0]; switch (key) { case "bbs": BoardKey = keyValues[1]; break; case "key": DatKey = keyValues[1]; break; case "FROM": Name = HttpUtility.UrlDecode(keyValues[1], sjis); break; case "mail": Mail = HttpUtility.UrlDecode(keyValues[1], sjis); break; case "MESSAGE": Body = HttpUtility.UrlDecode(keyValues[1], sjis); break; case "subject": Title = HttpUtility.UrlDecode(keyValues[1], sjis); break; case "submit": if (keyValues[1] == "%90V%8BK%83X%83%8C%83b%83h%8D%EC%90%AC") { IsThread = true; } else if (keyValues[1] == "%8F%91%82%AB%8D%9E%82%DE") { IsThread = false; } break; } } _headers = headers; _context = context; _connectionInfo = connectionInfo; }
public async Task <Thread> CreateThreadAsync(string boardKey, string hostAddress, MainContext context, PluginDependency pluginDependency, Session session) { var board = await context.Boards.FirstOrDefaultAsync(x => x.BoardKey == boardKey); if (board == null) { throw new BBSErrorException(BBSErrorType.BBSNotFoundBoardError); } await board.InitializeForValidation(context); if (board.IsRestricted(hostAddress.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()))) { throw new BBSErrorException(BBSErrorType.BBSRestrictedUserError); } if (board.HasProhibitedWords(Response.Body)) { throw new BBSErrorException(BBSErrorType.BBSProhibitedWordError); } var thread = new Thread() { BoardKey = boardKey, Title = Title }; thread.Initialize(hostAddress); if (Startup.IsUsingLegacyMode && context.Threads.Any(x => x.BoardKey == boardKey && x.DatKey == thread.DatKey)) { throw new BBSErrorException(BBSErrorType.BBSSameDatKeyError); } if (string.IsNullOrWhiteSpace(Response.Body)) { throw new BBSErrorException(BBSErrorType.BBSNoContentError); } if (string.IsNullOrWhiteSpace(Title)) { throw new BBSErrorException(BBSErrorType.BBSNoTitleError); } var result = await context.Threads.AddAsync(thread); await context.SaveChangesAsync(); var response = new Response() { Body = Response.Body, Name = Response.Name, Mail = Response.Mail }; response.Initialize(result.Entity.ThreadId, hostAddress, boardKey); await pluginDependency.RunPlugin(PluginTypes.Thread, response, thread, board, session, context); await context.Responses.AddAsync(response); await context.SaveChangesAsync(); thread.Responses = new List <Response>() { response }; return(thread); }
public async Task <IActionResult> GetBoardPluginSettings([FromRoute] string plugin, [FromRoute] string boardKey) { if (await HasSystemAuthority(SystemAuthority.BoardSetting, boardKey)) { return(Ok(await PluginDependency.GetBoardPluginSetting(boardKey, plugin))); } return(Unauthorized()); }
public async Task <IActionResult> PostBoardPluginSettings([FromRoute] string plugin, [FromRoute] string boardKey, [FromBody] JObject settings) { if (await HasSystemAuthority(SystemAuthority.BoardSetting, boardKey)) { await PluginDependency.SaveBoardPluginSetting(boardKey, plugin, settings); return(Ok()); } return(Unauthorized()); }
public async Task LoadFromDependencyContext_FromPluginDependency_Returns_Assembly() { var testContext = await SetupLoadedPluginTextContext(); var loadContext = testContext.Sut(); var fileSystemUtility = testContext.GetMock <IFileSystemUtilities>(); var runtimeDefaultAssemblyLoadContext = testContext.GetMock <IRuntimeDefaultAssemblyContext>(); var initialPluginLoadDirectory = testContext.InitialPluginLoadDirectory; var pluginLoadContext = testContext.PluginLoadContext; var newtonsoftAssemblyName = testContext.NewtonsoftAssemblyName; var newtonsoftAssembly = testContext.NewtonsoftAssembly; var newtonsoftAssemblyPath = testContext.NewtonsoftAssemblyPath; var resolver = testContext.GetMock <IAssemblyDependencyResolver>(); var pluginDependencyContext = testContext.GetMock <IPluginDependencyContext>(); var pluginDependencyResolver = testContext.GetMock <IPluginDependencyResolver>(); var newtonsoftAssemblyStream = File.OpenRead(newtonsoftAssemblyPath); // Skip the resolver resolver.Setup(r => r.ResolveAssemblyToPath(newtonsoftAssemblyName)).Returns(String.Empty); // Skip resources assembly // newtonsoftAssemblyName does not contain a culture var pluginDependency = new PluginDependency { DependencyNameWithoutExtension = newtonsoftAssemblyName.Name }; var additionalProbingPaths = Enumerable.Empty <string>(); pluginDependencyContext.SetupGet(p => p.AdditionalProbingPaths).Returns(additionalProbingPaths); pluginDependencyContext.SetupGet(p => p.PluginDependencies).Returns(new[] { new PluginDependency { DependencyNameWithoutExtension = "not-the-droid-im-looking-for" }, pluginDependency }); pluginDependencyResolver.Setup(r => r.ResolvePluginDependencyToPath(initialPluginLoadDirectory, pluginDependency, additionalProbingPaths)).Returns(newtonsoftAssemblyStream); var result = InvokeProtectedMethodOnLoadContextAndGetResult <ValueOrProceed <AssemblyFromStrategy> >( loadContext, "LoadFromDependencyContext", new object[] { initialPluginLoadDirectory, newtonsoftAssemblyName }); Assert.IsNotNull(result); Assert.AreEqual(newtonsoftAssemblyName.Name, result.Value.Assembly.GetName().Name); }
public async Task <IActionResult> AddPlugin([FromForm] PluginFormData body) { if (!await HasSystemAuthority(SystemAuthority.Admin | SystemAuthority.Owner)) { return(Unauthorized()); } var stream = body.File.OpenReadStream(); using var archive = new ZipArchive(stream); var entries = archive.Entries; await PluginDependency.AddPlugin(entries.ToList()); return(Ok()); }
public async Task <IActionResult> PatchPluginConfig([FromRoute] string plugin, [FromBody] PluginConfig conf) { if (!await HasSystemAuthority(SystemAuthority.Admin)) { return(Unauthorized()); } if (conf.Priority != null) { await PluginDependency.PatchPluginSetting(plugin, conf.Priority, PluginDependency.PluginSettingType.Priority); } if (conf.IsEnable != null) { await PluginDependency.PatchPluginSetting(plugin, conf.IsEnable, PluginDependency.PluginSettingType.IsEnable); } if (conf.ActivatedBoards != null) { await PluginDependency.PatchPluginSetting(plugin, conf.ActivatedBoards ?? new string[0], PluginDependency.PluginSettingType.ActivatedBoards); } return(Ok()); }
public IList <PluginDependency> GetMissingPlugins(ICorePlugin plugin) { IList <PluginDependency> missingDependencies = new List <PluginDependency>(); var installedPlugins = GetInstalledPlugins(); if (plugin.PluginSetting.PluginDependencies != null) { foreach (var pluginDependency in plugin.PluginSetting.PluginDependencies) { PluginDependency dependency = pluginDependency; if ( !installedPlugins.Where( installedPlugin => installedPlugin.Identifier.Equals(dependency.Identifier) && IsAppropriateVersion(installedPlugin.Version, dependency.MinVersion, dependency.MaxVersion)).Any()) { missingDependencies.Add(pluginDependency); } } } return(missingDependencies); }
protected virtual PluginManifest LoadPluginManifest(FileInfo pluginManifestFile) { if (pluginManifestFile != null && pluginManifestFile.Exists) { if (PluginManifestDeserializer != null) { return(PluginManifestDeserializer(pluginManifestFile)); } var m = new PluginManifest(); var xe = XElement.Load(pluginManifestFile.FullName, LoadOptions.PreserveWhitespace); foreach (var xec in xe.Elements()) { FsManifestPropertyNames prop; if (!Enum.TryParse(xec.Name.LocalName, true, out prop)) { // if the element is not recognized, add it as a setting if (!m.PluginDefaultSettings.ContainsKey(xec.Name.LocalName)) { m.PluginDefaultSettings.Add(xec.Name.LocalName, xec.Value); } continue; } switch (prop) { case FsManifestPropertyNames.PluginId: m.PluginId = xec.Value; break; case FsManifestPropertyNames.PluginTypeName: m.PluginTypeName = xec.Value; break; case FsManifestPropertyNames.PluginAssemblyFileName: m.PluginAssemblyFileName = xec.Value; break; case FsManifestPropertyNames.PluginTitle: m.PluginTitle = xec.Value; break;; case FsManifestPropertyNames.PluginDescription: m.PluginDescription = xec.Value; break;; case FsManifestPropertyNames.PluginUrl: m.PluginUrl = xec.Value; break;; case FsManifestPropertyNames.PluginVersion: Version v; if (Version.TryParse(xec.Value, out v)) { m.PluginVersion = v; } break; case FsManifestPropertyNames.PluginDefaultSettings: foreach (var setting in xec.Elements()) { if (setting.HasAttributes) { var key = setting.Attributes().First().Value; if (!string.IsNullOrWhiteSpace(key)) { m.PluginDefaultSettings[key] = setting.Value; } } } break; case FsManifestPropertyNames.PluginCategory: m.PluginCategory = xec.Value; break; case FsManifestPropertyNames.PluginTags: foreach (var tag in xec.Elements()) { var t = tag.Value; if (!string.IsNullOrWhiteSpace(t) && !m.PluginTags.Contains(t)) { m.PluginTags.Add(t); } } break; case FsManifestPropertyNames.Author: m.Author = xec.Value; break; case FsManifestPropertyNames.AuthorUrl: m.AuthorUrl = xec.Value; break; case FsManifestPropertyNames.License: m.License = xec.Value; break; case FsManifestPropertyNames.LicenseUrl: m.LicenseUrl = xec.Value; break; case FsManifestPropertyNames.PluginDependencies: foreach (var dependency in xec.Elements()) { if (dependency.HasAttributes) { var attDict = dependency.Attributes() .ToDictionary(k => k.Name.LocalName.ToLowerInvariant(), dv => dv.Value); if (attDict.ContainsKey("pluginid")) { var d = new PluginDependency { PluginId = attDict["pluginid"], IsOptional = attDict.GetValueOrDefault("optional", bool.FalseString) .Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase) }; Version mv; if (attDict.ContainsKey("minversion") && Version.TryParse(attDict["minversion"], out mv)) { d.MinVersion = mv; } Version xv; if (attDict.ContainsKey("maxversion") && Version.TryParse(attDict["maxversion"], out xv)) { d.MaxVersion = xv; } m.PluginDependencies.Add(d); } } } break; } } return(m); } return(null); }
protected ApiControllerBase(MainContext context, PluginDependency dependency) { Context = context; PluginDependency = dependency; CurrentUser = null; }
public async Task <Response> CreateResponseAsync(string boardKey, long threadId, string hostAddress, MainContext context, PluginDependency pluginDependency, Session session, bool isLegacy = false) { if (context is null) { throw new ArgumentNullException(nameof(context)); } var board = await context.Boards.FirstOrDefaultAsync(x => x.BoardKey == boardKey); if (board == null) { throw new BBSErrorException(BBSErrorType.BBSNotFoundBoardError); } await board.InitializeForValidation(context); if (board.IsRestricted(hostAddress.Split(',', StringSplitOptions.RemoveEmptyEntries).Select(x => x.Trim()))) { throw new BBSErrorException(BBSErrorType.BBSRestrictedUserError); } if (board.HasProhibitedWords(Body)) { throw new BBSErrorException(BBSErrorType.BBSProhibitedWordError); } var thread = await context.Threads.FirstOrDefaultAsync(x => isLegacy?x.DatKey == threadId : x.ThreadId == threadId); if (thread == null) { throw new BBSErrorException(BBSErrorType.BBSNotFoundThreadError); } else if (string.IsNullOrWhiteSpace(Body)) { throw new BBSErrorException(BBSErrorType.BBSNoContentError); } else if (thread.Stopped) { throw new BBSErrorException(BBSErrorType.BBSThreadStoppedError); } //await using var transaction = await context.Database.BeginTransactionAsync(); var response = new Response() { Body = Body, Mail = Mail, Name = Name }; lock (LockObject) { response.Initialize(thread.ThreadId, hostAddress, board.BoardKey); // ReSharper disable once MethodHasAsyncOverload context.Responses.Add(response); thread.ResponseCount++; thread.Modified = response.Created; } await pluginDependency.RunPlugin(PluginTypes.Response, response, thread, board, session, context); if (!Mail.StartsWith("sage")) { thread.SageModified = thread.Modified; } await context.SaveChangesAsync(); //await transaction.CommitAsync(); return(response); }
public BoardsController(MainContext context, PluginDependency dependency) : base(context, dependency) { }
public SiteSettingController(MainContext context, PluginDependency dependency) : base(context, dependency) { }
public virtual Stream ResolvePluginDependencyToPath(string dependencyPath, IEnumerable <string> probingPaths, PluginDependency dependency) { var localFile = Path.Combine(dependencyPath, dependency.DependencyPath); if (File.Exists(localFile)) { return(File.OpenRead(localFile)); } foreach (var probingPath in probingPaths) { var candidate = Path.Combine(probingPath, dependency.ProbingPath); if (File.Exists(candidate)) { return(File.OpenRead(candidate)); } } foreach (var candidate in runtimePlatformContext.GetPluginDependencyNames(dependency.DependencyNameWithoutExtension)) { var candidateLocation = Path.Combine(dependencyPath, candidate); if (File.Exists(candidateLocation)) { return(File.OpenRead(candidateLocation)); } } return(null); }
public PluginController(MainContext context, PluginDependency plugin) : base(context, plugin) { }
public CapGroupController(MainContext context, PluginDependency dependency) : base(context, dependency) { }
public override Stream ResolvePluginDependencyToPath(string dependencyPath, IEnumerable <string> probingPaths, PluginDependency dependency) { var networkFileLocation = $"{this.options.BaseUrl}/{dependency.DependencyPath}"; var networkFile = NetworkUtil.DownloadAsStream(this.httpClient, networkFileLocation); if (networkFile != null) { return(networkFile); } foreach (var probingPath in probingPaths) { networkFileLocation = $"{this.options.BaseUrl}/{Path.Combine(probingPath, dependency.ProbingPath)}"; networkFile = NetworkUtil.DownloadAsStream(this.httpClient, networkFileLocation); if (networkFile != null) { return(networkFile); } } foreach (var candidate in runtimePlatformContext.GetPluginDependencyNames(dependency.DependencyNameWithoutExtension)) { networkFileLocation = $"{this.options.BaseUrl}/{Path.Combine(dependencyPath, candidate)}"; networkFile = NetworkUtil.DownloadAsStream(this.httpClient, networkFileLocation); if (networkFile != null) { return(networkFile); } } return(null); }
public LegacyBbsCgiController(MainContext context, PluginDependency plugin) { _pluginDependency = plugin; _context = context; }