예제 #1
0
            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;
            }
예제 #2
0
        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);
        }
예제 #3
0
 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());
 }
예제 #4
0
        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);
        }
예제 #6
0
        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());
        }
예제 #7
0
 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());
 }
예제 #8
0
        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);
        }
예제 #9
0
        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);
        }
예제 #10
0
 protected ApiControllerBase(MainContext context, PluginDependency dependency)
 {
     Context          = context;
     PluginDependency = dependency;
     CurrentUser      = null;
 }
예제 #11
0
        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);
        }
예제 #12
0
 public BoardsController(MainContext context, PluginDependency dependency) : base(context, dependency)
 {
 }
예제 #13
0
 public SiteSettingController(MainContext context, PluginDependency dependency) : base(context, dependency)
 {
 }
예제 #14
0
        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);
        }
예제 #15
0
 public PluginController(MainContext context, PluginDependency plugin) : base(context, plugin)
 {
 }
예제 #16
0
 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);
        }
예제 #18
0
 public LegacyBbsCgiController(MainContext context, PluginDependency plugin)
 {
     _pluginDependency = plugin;
     _context          = context;
 }