public async Task ShouldProcess(string cdnBaseUrl, string text, string expected)
        {
            var fileStore = new DefaultMediaFileStore(
                Mock.Of <IFileStore>(),
                "/media",
                cdnBaseUrl,
                Enumerable.Empty <IMediaEventHandler>(),
                Enumerable.Empty <IMediaCreatingEventHandler>(),
                Mock.Of <ILogger <DefaultMediaFileStore> >());

            var sanitizer = new HtmlSanitizerService(Options.Create(new HtmlSanitizerOptions()));

            var defaultHttpContext = new DefaultHttpContext();

            defaultHttpContext.Request.PathBase = new PathString("/tenant");
            var httpContextAccessor = Mock.Of <IHttpContextAccessor>(hca => hca.HttpContext == defaultHttpContext);

            var options = Options.Create(new ResourceManagementOptions {
                CdnBaseUrl = cdnBaseUrl
            });

            var assetUrlProvider = new AssetUrlShortcodeProvider(fileStore, httpContextAccessor, options);

            var processor = new ShortcodeService(new IShortcodeProvider[] { assetUrlProvider }, Enumerable.Empty <IShortcodeContextProvider>());

            var processed = await processor.ProcessAsync(text);

            // The markdown part sanitizes after processing.
            var sanitized = sanitizer.Sanitize(processed);

            Assert.Equal(expected, sanitized);
        }
Esempio n. 2
0
        public async Task ShouldProcess(string cdnBaseUrl, string text, string expected)
        {
            var sanitizerOptions = new HtmlSanitizerOptions();

            sanitizerOptions.Configure.Add(opt => opt.AllowedAttributes.Add("class"));

            var fileStore = new DefaultMediaFileStore(
                Mock.Of <IFileStore>(),
                "/media",
                cdnBaseUrl,
                Enumerable.Empty <IMediaEventHandler>(),
                Enumerable.Empty <IMediaCreatingEventHandler>(),
                Mock.Of <ILogger <DefaultMediaFileStore> >());

            var sanitizer = new HtmlSanitizerService(Options.Create(sanitizerOptions));

            var defaultHttpContext = new DefaultHttpContext();

            defaultHttpContext.Request.PathBase = new PathString("/tenant");
            var httpContextAccessor = Mock.Of <IHttpContextAccessor>(hca => hca.HttpContext == defaultHttpContext);

            var options = Options.Create(new ResourceManagementOptions {
                CdnBaseUrl = cdnBaseUrl
            });

            var imageProvider = new ImageShortcodeProvider(fileStore, sanitizer, httpContextAccessor, options);

            var processor = new ShortcodeService(new IShortcodeProvider[] { imageProvider }, Enumerable.Empty <IShortcodeContextProvider>());

            var processed = await processor.ProcessAsync(text);

            Assert.Equal(expected, processed);
        }
Esempio n. 3
0
 public ReplyController(
     IOptions <AppSettingsModel> appSettings,
     BlogContext db,
     UsersContext udb,
     AdminUtil adminUtil,
     BlogUtil blogUtil,
     ExpUtil expUtil,
     MessageUtil msgUtil,
     RatingUtil ratingUtil,
     IWebHostEnvironment env,
     IMemoryCache cache,
     ICompositeViewEngine viewEngine,
     IActionContextAccessor actionAccessor,
     HtmlSanitizerService sanitizerService)
 {
     _appSettings      = appSettings.Value;
     _db               = db;
     _udb              = udb;
     _adminUtil        = adminUtil;
     _blogUtil         = blogUtil;
     _cache            = cache;
     _env              = env;
     _expUtil          = expUtil;
     _ratingUtil       = ratingUtil;
     _msgUtil          = msgUtil;
     _viewEngine       = viewEngine;
     _actionAccessor   = actionAccessor;
     _sanitizerService = sanitizerService;
 }
        public void ShouldSanitizeUnprocessed(string text, string expected)
        {
            // The html parts santize on save, so do not process the shortcode first.
            var sanitizer = new HtmlSanitizerService(Options.Create(new HtmlSanitizerOptions()));
            var sanitized = sanitizer.Sanitize(text);

            Assert.Equal(expected, sanitized);
        }
        public void IsValid_ShouldValidateHtml(string value, bool isValid)
        {
            var htmlSanitizer = new HtmlSanitizerService(new Mock <ILogger <HtmlSanitizerService> >().Object);

            var actual = htmlSanitizer.IsValid(value);

            Assert.Equal(isValid, actual);
        }
        public void Sanitize_ShouldSanitizeHtml(string unsanitized, string sanitized)
        {
            var htmlSanitizer = new HtmlSanitizerService(new Mock <ILogger <HtmlSanitizerService> >().Object);

            var actual = htmlSanitizer.Sanitize(unsanitized);

            Assert.Equal(sanitized, actual);
        }
 public PrivateMessageController(IFolkeConnection session,
                                 IForumUserService <TUser, TUserView> accountService,
                                 ForumsDataMapping <TUser, TUserView> forumsDataMapping,
                                 HtmlSanitizerService <TUser> htmlSanitizerService)
 {
     this.session              = session;
     this.accountService       = accountService;
     this.forumsDataMapping    = forumsDataMapping;
     this.htmlSanitizerService = htmlSanitizerService;
 }
Esempio n. 8
0
 public ThreadController(IFolkeConnection session,
                         IForumUserService <TUser, TUserView> accountService,
                         ForumsDataMapping <TUser, TUserView> forumsDataMapping,
                         HtmlSanitizerService <TUser> htmlSanitizerService,
                         CommentService <Thread <TUser>, CommentInThread <TUser>, TUser, TUserView> commentService)
 {
     this.session              = session;
     this.accountService       = accountService;
     this.forumsDataMapping    = forumsDataMapping;
     this.htmlSanitizerService = htmlSanitizerService;
     this.commentService       = commentService;
 }
Esempio n. 9
0
 public ReplyController(
     BlogContext db,
     AdminUtil adminUtil,
     BlogUtil blogUtil,
     RatingUtil ratingUtil,
     HtmlSanitizerService sanitizerService)
 {
     _db               = db;
     _adminUtil        = adminUtil;
     _blogUtil         = blogUtil;
     _ratingUtil       = ratingUtil;
     _sanitizerService = sanitizerService;
 }
Esempio n. 10
0
 public ReplyController(
     IOptions <AppSettingsModel> appSettings,
     BlogContext db,
     UsersContext udb,
     AdminUtil adminUtil,
     BlogUtil blogUtil,
     ExpUtil expUtil,
     MessageUtil msgUtil,
     RatingUtil ratingUtil,
     HtmlSanitizerService sanitizerService)
 {
     _appSettings      = appSettings.Value;
     _db               = db;
     _udb              = udb;
     _adminUtil        = adminUtil;
     _blogUtil         = blogUtil;
     _expUtil          = expUtil;
     _ratingUtil       = ratingUtil;
     _msgUtil          = msgUtil;
     _sanitizerService = sanitizerService;
 }
Esempio n. 11
0
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc(option =>
            {
                option.EnableEndpointRouting = false;
                option.CacheProfiles.Add("Never", new CacheProfile
                {
                    Location = ResponseCacheLocation.None,
                    NoStore  = true
                });
                option.Filters.Add(typeof(GlobalExceptionFilter));
                var SslPort = Configuration.GetSection("ApplicationSettings").GetValue <string>("HttpsPort");
                if (!string.IsNullOrEmpty(SslPort))
                {
                    option.SslPort = int.Parse(SslPort);
                }
            })
            .SetCompatibilityVersion(CompatibilityVersion.Latest)
            .AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver();
            })
            .AddSessionStateTempDataProvider();

            services.Configure <MvcOptions>(o =>
            {
                var serviceProvider = services.BuildServiceProvider();
                var readerFactory   = serviceProvider.GetRequiredService <IHttpRequestStreamReaderFactory>();
                o.ModelBinderProviders.Insert(0, new DefaultHybridModelBinderProvider(o.InputFormatters, readerFactory));
            });

            services.AddOptions();

            services.AddSingleton(Configuration);
            services.Configure <AppSettingsModel>(Configuration.GetSection("ApplicationSettings"));
            services.Configure <EmailSender.EmailSettings>(Configuration.GetSection("EmailSettings"));
            services.Configure <ElasticSearchProvider.ElasticSearchSettings>(Configuration.GetSection("ElasticSearchSettings"));
            services.Configure <RegisterSettingsModel>(ConfigFromDataFile("App_Data/RegisterSettings.json"));
            services.Configure <DataSettingsModel>(ConfigFromDataFile("App_Data/DataSettings.json"));
            services.Configure <BackgroundSetting>(ConfigFromDataFile("App_Data/BackgroundSetting.json"));
            services.Configure <Models.App.AuditExamConfig>(ConfigFromDataFile("App_Data/AuditExam.json"));
            services.Configure <Models.App.RaffleConfig>(ConfigFromDataFile("App_Data/RaffleConfig.json"));
            services.Configure <Models.App.WheelConfig>(ConfigFromDataFile("App_Data/WheelConfig.json"));

            services.AddMemoryCache();
            services.AddSession();

            services.AddScoped(p => new BlogContext(_dataDbConnectionString, p.GetRequiredService <ILoggerFactory>()));
            services.AddScoped(p => new UsersContext(_userDbConnectionString, p.GetRequiredService <ILoggerFactory>()));

            services.AddIdentity <UserProfile, AspNetCore.Identity.EntityFramework6.IdentityRole>(options =>
            {
                options.Password.RequireDigit           = false;
                options.Password.RequireLowercase       = false;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase       = false;
                options.User.RequireUniqueEmail         = true;
                options.User.AllowedUserNameCharacters  = string.Empty;
            })
            .AddUserStore <UserStore <UserProfile, UsersContext> >()
            .AddRoleStore <RoleStore <UsersContext> >()
            .AddErrorDescriber <GmIdentityErrorDescriber>()
            .AddDefaultTokenProviders();

            services.ConfigureApplicationCookie(options =>
            {
                options.Cookie.SecurePolicy      = Microsoft.AspNetCore.Http.CookieSecurePolicy.None;
                options.AccessDeniedPath         = "/403.html";
                options.Events.OnRedirectToLogin = ctx =>
                {
                    if (ctx.Request.Path.StartsWithSegments("/api") &&
                        ctx.Response.StatusCode == (int)System.Net.HttpStatusCode.OK)
                    {
                        ctx.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
                    }
                    else
                    {
                        ctx.Response.Redirect(ctx.RedirectUri);
                    }
                    return(Task.CompletedTask);
                };
            });

            services.AddAuthorization(option =>
            {
                option.AddPolicy("Harmony", policy => policy.AddRequirements(new HarmonyRequirement()));
                option.AddPolicy("AdminAccess", policy => policy.AddRequirements(new AdminAccessRequirement()));
            });

            services.AddCors(option =>
            {
                option.AddPolicy("GmAppOrigin",
                                 builder => builder.WithOrigins(IsDev ? SiteConstant.DevAppHostOrigins : SiteConstant.AppHostOrigins)
                                 .AllowAnyHeader()
                                 .AllowCredentials()
                                 .AllowAnyMethod());
            });

            services.AddAntiforgery(a => a.HeaderName = "X-CSRF-TOKEN");

            services.AddSingleton <IAuthorizationHandler, HarmonyHandler>();
            services.AddSingleton <IAuthorizationHandler, AdminAccessHandler>();

            if (_env.IsProduction())
            {
                services.AddSingleton(provider =>
                {
                    var scheduler = new SchedulerService(
                        provider.GetRequiredService <IServiceScopeFactory>(),
                        provider.GetRequiredService <IWebHostEnvironment>(),
                        provider.GetRequiredService <IMemoryCache>(),
                        provider.GetRequiredService <IOptions <AppSettingsModel> >(),
                        provider.GetRequiredService <ILoggerFactory>());
                    JobManager.Initialize(scheduler);
                    return(scheduler);
                });
            }
            services.AddScoped <JobTaskRunner>();
            services.AddSingleton <BackgroundTaskQueue>();
            services.AddHostedService <BackgroundJobService>();
            services.AddSingleton <QuestService>();
            services.AddSingleton <IVisitCounter>(s =>
            {
                if (_env.IsStaging())
                {
                    return(new ReadonlyVisitCounter(s.GetRequiredService <IServiceScopeFactory>()));
                }
                else
                {
                    return(new VisitCounter(s.GetRequiredService <IServiceScopeFactory>()));
                }
            });
            services.AddSingleton <CacheService>();
            services.AddSingleton(_ => HtmlSanitizerService.CreateInstance());
            services.AddScoped <ContextlessBlogUtil>();
            services.AddScoped <BlogUtil>();
            services.AddScoped <AdminUtil>();
            services.AddScoped <CategoryUtil>();
            services.AddScoped <ConstantUtil>();
            services.AddScoped <ExpUtil>();
            services.AddScoped <ImageUtil>();
            services.AddScoped <IUpload, LinodeUtil>();
            services.AddScoped <MessageUtil>();
            services.AddScoped <RatingUtil>();
            services.AddScoped <TagUtil>();
            services.AddScoped <TopicUtil>();
            services.AddScoped <UploadUtil>();
            services.AddScoped <WidgetUtil>();
            services.AddScoped <IRecommendationProvider, ElasticSearchProvider>();
            bool enabelES = Configuration.GetSection("ApplicationSettings").GetValue <string>("SearchBackendType") == "ElasticSearch";

            if (enabelES)
            {
                services.AddScoped <ISearchProvider, ElasticSearchProvider>();
            }
            else
            {
                services.AddScoped <ISearchProvider, DbBlogSearchProvider>();
            }
            services.AddScoped <DbBlogSearchProvider>();
            services.AddTransient <HtmlUtil>();
            services.AddTransient <GachaBonusService>();
            services.AddTransient <INickNameProvider, TitleNickNameProvider>();

            services.AddSingleton(ElasticSearchProvider.CreateClient);
            if (enabelES && !Configuration.GetSection("ElasticSearchSettings").GetValue <bool>("Readonly"))
            {
                services.AddSingleton <ElasticSearchUpdateService>();
            }
            services.AddSingleton <EmailSender>();
            services.AddSingleton <IActionContextAccessor, ActionContextAccessor>();
            services.AddScoped(provider =>
            {
                var factory       = provider.GetService <IUrlHelperFactory>();
                var actionContext = provider.GetService <IActionContextAccessor>();
                return(factory.GetUrlHelper(actionContext.ActionContext));
            });

            services.Configure <WebEncoderOptions>(options =>
            {
                options.TextEncoderSettings = new TextEncoderSettings(System.Text.Unicode.UnicodeRanges.All);
            });

            services.AddLogging(builder => {
                if (IsDev)
                {
                    builder.AddConsole();
                    builder.AddDebug();
                    builder.AddEventSourceLogger();
                }
                builder.AddSerilog();
            });
        }
Esempio n. 12
0
        public async Task <ActionResult> Edit([FromServices] HtmlSanitizerService sanitizerService, int id, BlogEdit blog, IFormFile[] files, bool setmain = false)
        {
            ViewBag.CategoryList = _catUtil.GetCategoryDropdown(blog.CategoryID);
            ViewBag.id           = id;
            if (NolinkCategories == null || !NolinkCategories.Contains(blog.CategoryID))
            {
                if (blog.BlogLinks == null)
                {
                    ModelState.AddModelError("", "链接地址不能为空");
                    return(View(blog));
                }
                else
                {
                    blog.BlogLinks = blog.BlogLinks.Where(b => !string.IsNullOrWhiteSpace(b.url)).ToArray();
                    if (!BlogHelper.checkBlogLinks(blog.BlogLinks))
                    {
                        ModelState.AddModelError("", "链接地址不能为空,且不得包含javascript");
                        return(View(blog));
                    }
                }
            }
            if (blog.Content == null || string.IsNullOrWhiteSpace(BlogHelper.removeAllTags(blog.Content)))
            {
                ModelState.AddModelError("", "内容不能为空或纯图片");
                return(View(blog));
            }
            if (!_blogUtil.CheckAdmin())
            {
                blog.Content = sanitizerService.Sanitize(blog.Content);
            }
            if (ModelState.IsValid)
            {
                Blog          originalblog    = _db.Blogs.Find(id);
                bool          hasupload       = false;
                List <string> dellist         = null;
                List <string> newlist         = null;
                string        thumb           = null;
                string        newthumb        = null;
                string[]      originalImglist = originalblog.ImagePath?.Split(';') ?? new string[] { };
                string[]      currentImglist  = blog.ImagePath?.Split(';') ?? new string[] { };
                int           imgcount        = currentImglist.Length;
                bool[]        uploadpos       = null;
                if (originalblog.option != null)
                {
                    originalblog.option.MergeWith(_blogUtil, blog.Option);
                }
                else if (!blog.Option.OverrideOption(_blogUtil).IsDefault())
                {
                    originalblog.option = blog.Option;
                }
                if (originalblog.IsLocalImg)
                {
                    dellist = originalImglist.ToList();
                    thumb   = dellist.First();
                }
                if (currentImglist.Length != 0) //item has local image & might or might not changed
                {
                    // foreach name in current imglist, if orignal imglist does not contain the name,it is not valid
                    if (!currentImglist.All(n => originalImglist.Contains(n)))
                    {
                        ModelState.AddModelError("", "内部参数错误,请刷新重试");
                        return(View(blog));
                    }
                    // foreach name in orignial imglist, if current imglist does not contain the name,delete it
                    dellist = originalImglist.Except(currentImglist).ToList();
                    originalblog.ImagePath = blog.ImagePath;
                }
                if (files != null)
                {
                    uploadpos = new bool[files.Length];
                    imgcount += files.Where(f => f != null).Count();
                    for (int i = 0; i < files.Length; i++)
                    {
                        var data = files[i];
                        if (data != null)
                        {
                            if (data.Length > 1048576 * 4 || !data.ContentType.Contains("image"))
                            {
                                ModelState.AddModelError("", "单个文件不得超过4MB,且必须是图片");
                                return(View(blog));
                            }
                            hasupload    = true;
                            uploadpos[i] = true;
                        }
                        else
                        {
                            uploadpos[i] = false;
                        }
                    }
                }
                if (hasupload) // has upload file
                {
                    try
                    {
                        newlist = await _uploadUtil.SaveImagesAsync(files, false);
                    }
                    catch (Exception e)
                    {
                        ModelState.AddModelError("", "保存图片时发生异常:(" + e.Message + ")。如多次出错,请汇报给管理员。");
                        return(View(blog));
                    }
                    if (newlist.Count < 1)
                    {
                        ModelState.AddModelError("", "图片服务器上传出错,请稍后再试。如多次出错,请汇报给管理员。");
                        return(View(blog));
                    }
                    int i = 0;
                    if (originalblog.IsLocalImg && setmain && files[0] != null && currentImglist.Length > 0)
                    {
                        List <string> updatedImgList = new List <string>(currentImglist);
                        updatedImgList.Insert(0, newlist[0]);
                        updatedImgList.AddRange(newlist.Skip(1));
                        originalblog.ImagePath = string.Join(";", updatedImgList);
                        blog.Content           = BlogHelper.InsertImgPlaceholder(blog.Content);
                        i++;
                    }
                    else if (!originalblog.IsLocalImg)
                    {
                        originalblog.ImagePath = string.Join(";", newlist);
                    }
                    else
                    {
                        originalblog.ImagePath = string.Join(";", currentImglist.Concat(newlist));
                    }
                    blog.Content            = BlogHelper.ReplaceNewImgPlaceholder(blog.Content, i, currentImglist.Length, uploadpos);
                    originalblog.IsLocalImg = true;
                }
                if (!originalblog.IsLocalImg || imgcount == 0) //no img no upload
                {
                    string imgname = BlogHelper.getFirstImg(blog.Content);
                    if (imgname == null || imgname.Length < 5)
                    {
                        ModelState.AddModelError("", "请添加预览图!(上传或外链图片)");
                        blog.ImagePath = originalblog.ImagePath;
                        return(View(blog));
                    }
                    originalblog.ImagePath  = imgname;
                    originalblog.IsLocalImg = false;
                }
                else
                {
                    newthumb = originalblog.ImagePath.Split(';').ToList().First();
                }

                var mention = new MentionHandler(_udb);
                blog.Content = mention.ParseMentions(blog.Content);
                mention.SendMentionMsg(_msgUtil, originalblog.Author, originalblog.BlogTitle, Url.Action("Details", new { id = originalblog.BlogID }));
                if (blog.Option != null && (originalblog.option != null || !blog.Option.IsDefault()))
                {
                    originalblog.option = blog.Option;
                }
                // else image uploaded before and did not changed
                string[]   tags        = TagUtil.SplitTags(blog.BlogTags);
                List <Tag> updatedTags = null;
                try
                {
                    // Replace 【】() with []()
                    originalblog.BlogTitle  = blog.BlogTitle.ToSingleByteCharacterString();
                    originalblog.Content    = BlogHelper.RemoveComments(blog.Content);
                    originalblog.CategoryID = blog.CategoryID;
                    originalblog.Links      = Newtonsoft.Json.JsonConvert.SerializeObject(blog.BlogLinks);
                    if (blog.Option.NoApprove)
                    {
                        originalblog.isApproved = false;
                    }
                    else if (originalblog.isApproved == false)
                    {
                        originalblog.isApproved = null;
                    }
                    else if (originalblog.isApproved == null)
                    {
                        // Remove pending votes since the blog has changed.
                        var audits       = _db.BlogAudits.Where(b => b.BlogID == originalblog.BlogID).ToList();
                        var lastDecision = audits.Where(ba => ba.AuditAction == BlogAudit.Action.Approve || ba.AuditAction == BlogAudit.Action.Deny).OrderByDescending(ba => ba.BlogVersion).FirstOrDefault();
                        int lastVersion  = lastDecision == null ? 0 : lastDecision.BlogVersion;
                        _db.BlogAudits.RemoveRange(audits.Where(ba => ba.BlogVersion > lastVersion && (ba.AuditAction == BlogAudit.Action.VoteApprove || ba.AuditAction == BlogAudit.Action.VoteDeny)));
                    }
                    updatedTags            = _tagUtil.SetTagsForBlog(originalblog.BlogID, tags, originalblog.Author);
                    originalblog.isHarmony = BlogHelper.BlogIsHarmony(_db, originalblog, HarmonySettings);
                    _db.SaveChanges();
                }
                catch
                {
                    if (originalblog.IsLocalImg && newlist != null)
                    {
                        await _uploadUtil.DeleteFilesAsync(newlist);
                    }
                    throw;
                }
                if (dellist != null && dellist.Count > 0)
                {
                    await _uploadUtil.DeleteFilesAsync(dellist);
                }
                if (thumb != null && thumb != newthumb && blog.IsLocalImg)
                {
                    await _uploadUtil.DeleteFileAsync(thumb.Replace("/upload/", "/thumbs/"));
                }
                if (originalblog.IsLocalImg && thumb != newthumb)
                {
                    await _uploadUtil.SaveThumbAsync(originalblog.ImagePath);
                }
                if (originalblog.Author != User.Identity.Name)
                {
                    _adminUtil.log(User.Identity.Name, "editblog", originalblog.BlogID.ToString());
                }
                TriggerEditBlog(originalblog, updatedTags);
                return(RedirectToAction("Details", new { id }));
            }
            return(View(blog));
        }
Esempio n. 13
0
        public async Task <ActionResult> Create(BlogEdit blog, [FromServices] HtmlSanitizerService sanitizerService)
        {
            ViewBag.CategoryList = _catUtil.GetCategoryDropdown();
            ViewBag.UserHanGroup = GetUserHanGroup();
            string        content    = blog.Content;
            bool          isLocalimg = false;
            Blog          newblog;
            List <string> imglist = null;

            try
            {
                if (!ModelState.IsValid)
                {
                    throw new BlogException();
                }
                if (content == null || string.IsNullOrWhiteSpace(BlogHelper.removeAllTags(content)))
                {
                    ModelState.AddModelError("", "内容不能为空或纯图片");
                    throw new BlogException();
                }
                if (NolinkCategories == null || !NolinkCategories.Contains(blog.CategoryID))
                {
                    if (blog.BlogLinks == null)
                    {
                        ModelState.AddModelError("", "链接地址不能为空");
                        throw new BlogException();
                    }
                    else
                    {
                        blog.BlogLinks = blog.BlogLinks.Where(b => !string.IsNullOrWhiteSpace(b.url)).ToArray();
                        if (!BlogHelper.checkBlogLinks(blog.BlogLinks))
                        {
                            ModelState.AddModelError("", "链接地址不能为空,且不得包含javascript");
                            throw new BlogException();
                        }
                    }
                }
                if (!_blogUtil.CheckAdmin())
                {
                    content = sanitizerService.Sanitize(content);
                }
                if (blog.HanGroupID.HasValue && !_db.HanGroupMembers.Any(h => h.Username == User.Identity.Name && h.HanGroupID == blog.HanGroupID))
                {
                    ModelState.AddModelError("", "汉化组ID无效,请刷新重试。");
                    throw new BlogException();
                }
                List <IFormFile> BlogImages = new List <IFormFile>();
                if (Request.Form.Files.Count > 0)
                {
                    for (int i = 0; i < Request.Form.Files.Count; i++)
                    {
                        var file = Request.Form.Files[i];
                        if (file.Length > 0)
                        {
                            if (!file.ContentType.Contains("image"))
                            {
                                ModelState.AddModelError("", "不接受的文件类型");
                                throw new BlogException();
                            }
                            else if (file.Length > 1048576 * 4)
                            {
                                ModelState.AddModelError("", "文件不得超过4MB");
                                throw new BlogException();
                            }
                            isLocalimg = true;
                            BlogImages.Add(file);
                        }
                        else
                        {
                            content = BlogHelper.removeImgPlaceholder(content, i);
                        }
                    }
                }
                if (!isLocalimg)
                {
                    var imgname = BlogHelper.getFirstImg(content);
                    if (imgname == null || imgname.Length < 5)
                    {
                        ModelState.AddModelError("", "请添加预览图!(上传或在文中外链图片)");
                        throw new BlogException();
                    }
                    imglist = new List <string>()
                    {
                        imgname
                    };
                }
                else
                {
                    try
                    {
                        imglist = await _uploadUtil.SaveImagesAsync(BlogImages);
                    }
                    catch (Exception e)
                    {
                        ModelState.AddModelError("", "保存图片时发生异常:(" + e.Message + ")。如多次出错,请汇报给管理员。");
                        throw new BlogException(e.Message, e);
                    }
                    if (imglist.Count < 1)
                    {
                        ModelState.AddModelError("", "图片服务器上传出错,请稍后再试。如多次出错,请汇报给管理员。");
                        throw new BlogException();
                    }
                }
                string imgpath = string.Empty;
                if (imglist != null)
                {
                    imgpath = string.Join(";", imglist);
                }
                bool approve = User.IsInRole("Administrator") || User.IsInRole("Writers") || User.IsInRole("Moderator");
                // Replace 【】() with []()
                blog.BlogTitle = blog.BlogTitle.ToSingleByteCharacterString();
                blog.ImagePath = imgpath;
                content        = BlogHelper.RemoveComments(content);
                newblog        = _blogUtil.AddBlog(blog.BlogTitle, content,
                                                   blog.CategoryID, imgpath, User.Identity.Name, approve, isLocalimg, blog.BlogLinks);
                var taglist = new List <Tag>();
                if (!string.IsNullOrEmpty(blog.BlogTags))
                {
                    string[] tags = TagUtil.SplitTags(blog.BlogTags);
                    taglist = _tagUtil.AddTagsForBlog(newblog.BlogID, tags, newblog.Author);
                }
                var save = false;
                if (BlogHelper.BlogIsHarmony(_db, newblog, HarmonySettings))
                {
                    newblog.isHarmony = true;
                    save = true;
                }
                if (blog.HanGroupID.HasValue)
                {
                    _db.HanGroupBlogs.Add(new HanGroupBlog {
                        BlogID = newblog.BlogID, HanGroupID = blog.HanGroupID.Value
                    });
                    save = true;
                }
                if (blog.Option != null && !blog.Option.IsDefault())
                {
                    newblog.option = blog.Option.OverrideOption(_blogUtil);
                    if (newblog.option.NoApprove)
                    {
                        newblog.isApproved = false;
                    }
                    save = true;
                }
                if (save)
                {
                    _db.SaveChanges();
                }
                TriggerNewBlog(newblog, taglist);
            }
            catch (BlogException e)
            {
                if (Request.IsAjaxRequest())
                {
                    return(Json(new
                    {
                        err = e.Message + string.Join(";", ModelState.Values.SelectMany(m => m.Errors)
                                                      .Select(err => err.ErrorMessage)
                                                      .ToList())
                    }));
                }
                return(View(blog));
            }
            catch
            {
                if (isLocalimg && imglist != null)
                {
                    await _uploadUtil.DeleteFilesAsync(imglist.Concat(new[] { blog.ImagePath.Split(';')[0].Replace("/upload/", "/thumbs/") }));
                }
                throw;
            }
            if (Request.IsAjaxRequest())
            {
                return(Json(new { id = newblog.BlogID, src = BlogHelper.firstImgPath(newblog, true) }));
            }
            return(RedirectToAction("Details", new { id = newblog.BlogID }));
        }
Esempio n. 14
0
        public async Task <ActionResult> Edit(int id, TopicEdit etopic, [FromServices] HtmlSanitizerService sanitizerService)
        {
            etopic.LoadBlog(_db);
            ViewBag.CategoryID = new SelectList(_catUtil.GetCategoryList(), "CategoryID", "CategoryName", etopic.CategoryID);
            int ret = TagUtil.CheckBlogTag(etopic.TagName, 1);

            if (ret != 0)
            {
                ModelState.AddModelError("", ret > 0 ? "专题标签只能有1个" : "标签不得超过20个字符");
            }
            else if (!_blogUtil.CheckAdmin())
            {
                etopic.Content = sanitizerService.Sanitize(etopic.Content);
            }
            else if (ModelState.IsValid)
            {
                var  topic       = _db.Topics.Find(id);
                bool uploadsaved = false;
                bool bannersaved = false;
                var  blogcurrent = _db.BlogsInTopics.Where(bi => bi.TopicID == id).ToList();
                foreach (var blog in blogcurrent)
                {
                    _db.BlogsInTopics.Remove(blog);
                }
                int i = 0;
                foreach (var bid in etopic.BlogIDs.Distinct())
                {
                    var b = etopic.Blogs.SingleOrDefault(bb => bb.BlogID == bid);
                    if (b == null)
                    {
                        ModelState.AddModelError("", "未找到ID编号为" + bid + "的资源");
                        return(View(topic));
                    }
                    var blogintopic = new BlogsInTopic {
                        blog = b, topic = topic, BlogOrder = i++
                    };
                    _db.BlogsInTopics.Add(blogintopic);
                }

                if (topic.tag.TagName != etopic.TagName)
                {
                    var tag = _db.Tags.SingleOrDefault(t => t.TagName == etopic.TagName);
                    if (tag == null)
                    {
                        tag = new Tag {
                            TagName = etopic.TagName
                        };
                    }
                    topic.tag = tag;
                }
                try
                {
                    var  originalImage         = topic.ImagePath;
                    var  originalBanner        = topic.BannerPath;
                    bool shouldDeleteOldImage  = false;
                    bool shouldDeleteOldBanner = string.IsNullOrWhiteSpace(etopic.BannerPath);

                    if (etopic.TopicImage != null)
                    {
                        shouldDeleteOldImage = topic.isLocalImg;
                        topic.isLocalImg     = true;
                        var imglist = await _uploadUtil.SaveImagesAsync(new IFormFile[] { etopic.TopicImage }, true);

                        if (imglist.Count < 1)
                        {
                            ModelState.AddModelError("", "保存图片时发生异常。请尝试转换图片格式后再次上传。如多次出错,请汇报给管理员。");
                            return(View(etopic));
                        }
                        topic.ImagePath = imglist[0];
                        uploadsaved     = true;
                    }
                    else if (!topic.isLocalImg || (topic.isLocalImg && !etopic.IsLocalImg))
                    {
                        string imgname = BlogHelper.getFirstImg(etopic.Content);
                        if (imgname == null || imgname.Length < 5)
                        {
                            ModelState.AddModelError("", "请添加预览图!(上传或在文中外链图片)");
                            return(View(etopic));
                        }
                        shouldDeleteOldImage = !etopic.IsLocalImg;
                        topic.isLocalImg     = false;
                        topic.ImagePath      = imgname;
                    }
                    if (etopic.TopicBanner != null)
                    {
                        var imglist = await _uploadUtil.SaveImagesAsync(new IFormFile[] { etopic.TopicBanner }, false);

                        if (imglist.Count < 1)
                        {
                            ModelState.AddModelError("", "图片服务器上传出错,请尝试转换图片格式后再次上传。如多次出错,请汇报给管理员。");
                            return(View(topic));
                        }
                        shouldDeleteOldBanner = true;
                        bannersaved           = true;
                        topic.BannerPath      = imglist[0];
                    }
                    else
                    {
                        topic.BannerPath = etopic.BannerPath;
                    }

                    if (shouldDeleteOldBanner && !string.IsNullOrWhiteSpace(originalBanner))
                    {
                        await _uploadUtil.DeleteFileAsync(originalBanner);
                    }
                    if (shouldDeleteOldImage && !string.IsNullOrWhiteSpace(originalImage))
                    {
                        await _uploadUtil.DeleteFilesAsync(new[] { originalImage, originalImage.Replace("/upload/", "/thumbs/") });
                    }
                    topic.UpdateDate = DateTime.Now;
                    topic.TopicTitle = etopic.TopicTitle;
                    topic.CategoryID = etopic.CategoryID;
                    var mention = new MentionHandler(_udb);
                    topic.Content = mention.ParseMentions(BlogHelper.RemoveComments(etopic.Content));
                    mention.SendMentionMsg(_msgUtil, User.Identity.Name, etopic.TopicTitle, Url.Action("Details", new { id = topic.TopicID }));
                    _db.Entry(topic).State = EntityState.Modified;
                    _db.SaveChanges();
                    TriggerEditTopic(topic);
                    if (User.Identity.Name != topic.Author)
                    {
                        _adminUtil.log(User.Identity.Name, "edittopic", topic.TopicID.ToString());
                    }
                }
                catch
                {
                    if (uploadsaved)
                    {
                        await _uploadUtil.DeleteFilesAsync(new[] { topic.ImagePath, topic.ImagePath.Replace("/upload/", "/thumbs/") });
                    }
                    if (bannersaved)
                    {
                        await _uploadUtil.DeleteFileAsync(topic.BannerPath);
                    }
                    throw;
                }
                return(RedirectToAction("Details", new { id }));
            }
            return(View(etopic));
        }
Esempio n. 15
0
        public async Task <ActionResult> Create(TopicEdit topic, [FromServices] HtmlSanitizerService sanitizerService)
        {
            ViewBag.CategoryID = sl;
            topic.LoadBlog(_db);
            if (ModelState.IsValid)
            {
                Topic ntopic = new Topic();
                if (!_blogUtil.CheckAdmin())
                {
                    topic.Content = sanitizerService.Sanitize(topic.Content);
                }
                int i = 0;
                foreach (var bid in topic.BlogIDs.Distinct())
                {
                    var b = topic.Blogs.SingleOrDefault(bb => bb.BlogID == bid);
                    if (b == null)
                    {
                        ModelState.AddModelError("", "未找到ID编号为" + bid + "的资源");
                        return(View(topic));
                    }
                    var blogintopic = new BlogsInTopic {
                        blog = b, topic = ntopic, BlogOrder = i++
                    };
                    _db.BlogsInTopics.Add(blogintopic);
                }

                ntopic.Author     = User.Identity.Name;
                ntopic.CategoryID = topic.CategoryID;
                ntopic.Content    = topic.Content;
                ntopic.CreateDate = DateTime.Now;
                ntopic.UpdateDate = DateTime.Now;
                ntopic.TopicVisit = 0;
                ntopic.TopicTitle = topic.TopicTitle;

                if (topic.TopicImage != null)
                {   //ValidateFileAttribute里已经检查过了
                    ntopic.isLocalImg = true;
                    var imglist = await _uploadUtil.SaveImagesAsync(new IFormFile[] { topic.TopicImage });

                    if (imglist.Count < 1)
                    {
                        ModelState.AddModelError("", "图片服务器上传出错,请稍后再试。如多次出错,请汇报给管理员。");
                        return(View(topic));
                    }
                    ntopic.ImagePath = imglist[0];
                }
                else
                {
                    string imgname = BlogHelper.getFirstImg(ntopic.Content);
                    if (imgname == null || imgname.Length < 5)
                    {
                        ModelState.AddModelError("", "请添加预览图!(上传或在文中外链图片)");
                        return(View(topic));
                    }
                    ntopic.ImagePath = imgname;
                }
                if (topic.TopicBanner != null)
                {
                    var imglist = await _uploadUtil.SaveImagesAsync(new IFormFile[] { topic.TopicBanner }, false);

                    if (imglist.Count < 1)
                    {
                        ModelState.AddModelError("", "图片服务器上传出错,请稍后再试。如多次出错,请汇报给管理员。");
                        return(View(topic));
                    }
                    ntopic.BannerPath = imglist[0];
                }

                var tag = _db.Tags.SingleOrDefault(t => t.TagName == topic.TagName);
                if (tag == null)
                {
                    tag = new Tag {
                        TagName = topic.TagName
                    };
                }
                ntopic.tag = tag;
                var mention = new MentionHandler(_udb);
                ntopic.Content = mention.ParseMentions(BlogHelper.RemoveComments(ntopic.Content));
                _db.Topics.Add(ntopic);
                _db.SaveChanges();
                mention.SendMentionMsg(_msgUtil, ntopic.Author, ntopic.TopicTitle, Url.Action("Details", new { id = ntopic.TopicID }));
                TriggerNewTopic(ntopic);
                return(RedirectToAction("Details", new { id = ntopic.TopicID }));
            }
            return(View(topic));
        }