Esempio n. 1
0
 public ArchiveController(ICacheClient cacheClient, IBlogService blogService,
                          IOptions <BlogOptions> blogOption)
 {
     _cacheClient = cacheClient;
     _blogService = blogService;
     _blogOptions = blogOption.Value;
 }
Esempio n. 2
0
        public Startup(IConfiguration configuration, IHostEnvironment hostEnvironment)
        {
            Configuration   = configuration;
            HostEnvironment = hostEnvironment;

            BlogOptions = new BlogOptions();
        }
Esempio n. 3
0
        public static async Task <SyndicationFeed> BuildSyndication(this IBlogService service, string baseAddress)
        {
            ClientUrlGenerator generator = new ClientUrlGenerator
            {
                BaseAddress = baseAddress
            };
            BlogOptions blogOptions = await service.GetOptions();

            SyndicationFeed   feed   = new SyndicationFeed(blogOptions.Name, blogOptions.Description, new Uri(baseAddress));
            SyndicationPerson author = new SyndicationPerson("", blogOptions.Onwer, baseAddress);

            feed.Authors.Add(author);
            Dictionary <string, SyndicationCategory> categoryMap = new Dictionary <string, SyndicationCategory>();

            {
                /*var cates = await BlogService.CategoryService.GetCategories(await BlogService.CategoryService.All());
                 * foreach (var p in cates)
                 * {
                 *  var cate = new SyndicationCategory(p.Name);
                 *  categoryMap.Add(p.Id, cate);
                 *  feed.Categories.Add(cate);
                 * }*/
            }
            {
                var posts = await service.PostService.GetPosts(await service.PostService.All());

                List <SyndicationItem> items = new List <SyndicationItem>();
                foreach (var p in posts)
                {
                    if (p is null)
                    {
                        continue;
                    }
                    var s = new SyndicationItem(p.Title,
                                                SyndicationContent.CreateHtmlContent(Markdown.ToHtml(p.Content.Raw, Pipeline)),
                                                new Uri(generator.Post(p.Id)), p.Id, p.ModificationTime);
                    s.Authors.Add(author);

                    string summary;
                    if (await service.PostService.Protector.IsProtected(p.Content))
                    {
                        summary = "Protected Post";
                    }
                    else
                    {
                        summary = Markdown.ToPlainText(p.Content.Raw, Pipeline);
                    }
                    s.Summary = SyndicationContent.CreatePlaintextContent(summary.Length <= 100 ? summary : summary.Substring(0, 100));
                    s.Categories.Add(new SyndicationCategory(p.Category.ToString()));

                    /*if (categoryMap.TryGetValue(p.CategoryId, out var cate))
                     *  s.Categories.Add(cate);*/
                    s.PublishDate = p.CreationTime;
                    items.Add(s);
                }
                feed.Items = items.AsEnumerable();
            }

            return(feed);
        }
Esempio n. 4
0
        public BlogBuilder(BlogOptions options, string rootPath)
        {
            RootPath = rootPath;

            Options = options;

            FsBuilder = new FSBuilder(rootPath);
        }
Esempio n. 5
0
 public IndexModel(
     IBlogService blogManager,
     BlogOptions blogOptions
     )
 {
     _blogManager = blogManager;
     _blogOptions = blogOptions;
 }
Esempio n. 6
0
 public HomeController(
     IBlogService blogService,
     IOptions <BlogOptions> config,
     ICacheClient cacheClient)
 {
     _cacheClient = cacheClient;
     _blogService = blogService;
     _blogOptions = config.Value;
 }
        public AccountController(ILogger <AccountController> logger, BlogUserManager blogUserManager, BlogSignInManager signInManager, IEmailSender emailSender, IOptionsSnapshot <BlogOptions> blogOptions, AdvancedSettings advancedSettings)
        {
            _logger        = logger;
            _userManager   = blogUserManager;
            _signInManager = signInManager;
            _emailSender   = emailSender;

            _blogOptions      = blogOptions.Value;
            _advancedSettings = advancedSettings;
        }
Esempio n. 8
0
        public BlogController(IOptions <BlogOptions> blogOptions,
                              IAuthorizationService authorizationService,
                              ICategoriesCache categoriesCache,
                              OperationKeysContainer operationKeysContainer,
                              IBlogPresenter blogPresenter,
                              IServiceProvider serviceProvider) : base(serviceProvider)
        {
            OperationKeys = operationKeysContainer;

            this.blogOptions          = blogOptions.Value;
            this.authorizationService = authorizationService;
            this.categoriesCache      = categoriesCache;
            this.blogPresenter        = blogPresenter;
        }
Esempio n. 9
0
 public BlogService(
     IPostRepository postRepository,
     ICommentRepository commentRepository,
     IPostBuilder postBuilder,
     ICommentBuilder commentBuilder,
     IEmailService emailService,
     INotificationBuilder notificationBuilder,
     BlogOptions options,
     ILogger <BlogService> logger)
 {
     _postRepository      = postRepository;
     _commentRepository   = commentRepository;
     _postBuilder         = postBuilder;
     _commentBuilder      = commentBuilder;
     _emailService        = emailService;
     _notificationBuilder = notificationBuilder;
     _options             = options;
     _logger = logger;
 }
Esempio n. 10
0
        public async Task <bool> SetOptions(BlogOptions options, CancellationToken cancellationToken = default)
        {
            var entry = await DataContext.BlogEntries.FindAsync(new object[] { BlogOptionsEntry }, cancellationToken).ConfigureAwait(false);

            if (entry is null)
            {
                DataContext.BlogEntries.Add(new RawEntry
                {
                    Id    = BlogOptionsEntry,
                    Value = JsonSerializer.Serialize(options)
                });
            }
            else
            {
                entry.Value = JsonSerializer.Serialize(options);
            }
            await DataContext.SaveChangesAsync(cancellationToken).ConfigureAwait(false);

            return(true);
        }
Esempio n. 11
0
        public LocalFileService(IOptions <BlogOptions> blogOptions, IHttpContextAccessor httpContextAccessor, IWebHostEnvironment webHostEnvironment)
        {
            _blogOptions         = blogOptions.Value;
            _webHostEnvironment  = webHostEnvironment;
            _httpContextAccessor = httpContextAccessor;

            if (_blogOptions.Upload.Provider != BlogUploadProvider.Local && _blogOptions.Upload.Provider != BlogUploadProvider.Unknow)
            {
                throw new Exception("The blog upload option provider is not 'local'.");
            }

            var folder = _blogOptions.Upload.Value ?? "uploads";

            _serverBaseFolder = _webHostEnvironment.WebRootPath;
            var fullFolder = Path.Combine(_serverBaseFolder, folder, DateTime.Now.ToString("yyyyMMdd"));

            if (!Directory.Exists(fullFolder))
            {
                Directory.CreateDirectory(fullFolder);
            }

            _serverFullFolder = fullFolder;
        }
Esempio n. 12
0
        public async Task Setup()
        {
            RootPath = Path.Join(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "fstest");
            FSStaticBuilder.EnsureDirectoryExists(RootPath);

            PostData        = Enumerable.Range(0, 100).Select(x => Generator.GetPost()).ToArray();
            LayoutData      = Enumerable.Range(0, 100).Select(x => Generator.GetLayout()).ToArray();
            PageData        = Enumerable.Range(0, 100).Select(x => Generator.GetPage()).ToArray();
            FileData        = Enumerable.Range(0, 100).Select(x => Generator.GetFile()).ToArray();
            BlogOptionsData = new BlogOptions();

            BlogBuilder builder = new BlogBuilder(BlogOptionsData, RootPath);
            await builder.Build();

            await builder.BuildPosts(PostData);

            await builder.BuildLayouts(LayoutData);

            await builder.BuildPages(PageData);

            await builder.BuildFiles(FileData);

            BlogService = new FileSystemBlogService(new PhysicalFileProvider(RootPath).AsFileProvider());
        }
Esempio n. 13
0
        public BlogDbContext CreateDbContext(string[] args)
        {
            var configuration = BuildConfiguration();

            var blogOptions      = new BlogOptions();
            var connectionString = configuration.GetConnectionString("Blog");

            configuration.GetSection("Blog").Bind(blogOptions);
            var builder = blogOptions.DbType switch
            {
                DbType.SqlServer => new DbContextOptionsBuilder <BlogDbContext>()
                .UseSqlServer(connectionString),
                DbType.MySQL => new DbContextOptionsBuilder <BlogDbContext>()
                .UseMySql(connectionString, ServerVersion.Parse(blogOptions.ServerVersion)),
                DbType.PostgreSql => new DbContextOptionsBuilder <BlogDbContext>()
                .UseNpgsql(connectionString),
                DbType.Oracle => new DbContextOptionsBuilder <BlogDbContext>()
                .UseOracle(connectionString),
                _ => new DbContextOptionsBuilder <BlogDbContext>()
                .UseSqlite(connectionString),
            };

            return(new BlogDbContext(builder.Options));
        }
Esempio n. 14
0
 public BlogController(IPostService postService, IOptions <BlogOptions> blogSettings, IOptions <SocialMedia> socialMediaSettings)
 {
     _postService         = postService;
     _blogSettings        = blogSettings.Value;
     _socialMediaSettings = socialMediaSettings.Value;
 }
Esempio n. 15
0
        public override void PreConfigureServices(ServiceConfigurationContext context)
        {
            var configuration = context.Services.GetConfiguration();

            var https        = new HttpsOptions();
            var blog         = new BlogOptions();
            var notification = new NotificationOptions();
            var swagger      = new SwaggerOptions();
            var storage      = new StorageOptions();
            var cors         = new CorsOptions();
            var jwt          = new JwtOptions();
            var worker       = new WorkerOptions();
            var tencentCloud = new TencentCloudOptions();
            var authorize    = new AuthorizeOptions();

            PreConfigure <HttpsOptions>(options =>
            {
                var httpsOption = configuration.GetSection("https");
                Configure <HttpsOptions>(httpsOption);

                options.ListenAddress   = httpsOption.GetValue <string>(nameof(options.ListenAddress));
                options.ListenPort      = httpsOption.GetValue <int>(nameof(options.ListenPort));
                options.PublicCertFile  = httpsOption.GetValue <string>(nameof(options.PublicCertFile));
                options.PrivateCertFile = httpsOption.GetValue <string>(nameof(options.PrivateCertFile));

                https = options;
            });

            PreConfigure <BlogOptions>(options =>
            {
                var blogOption = configuration.GetSection("blog");
                Configure <BlogOptions>(blogOption);

                options.StaticUrl = blogOption.GetValue <string>(nameof(options.StaticUrl));
                options.ApiUrl    = blogOption.GetValue <string>(nameof(options.ApiUrl));
                options.WebUrl    = blogOption.GetValue <string>(nameof(options.WebUrl));
                options.AdminUrl  = blogOption.GetValue <string>(nameof(options.AdminUrl));

                blog = options;
            });

            PreConfigure <NotificationOptions>(options =>
            {
                var notificationOption = configuration.GetSection("notification");
                Configure <NotificationOptions>(notificationOption);

                options.FtqqUrl = notificationOption.GetValue <string>(nameof(options.FtqqUrl));

                notification = options;
            });

            PreConfigure <SwaggerOptions>(options =>
            {
                var swaggerOption = configuration.GetSection("swagger");
                Configure <SwaggerOptions>(swaggerOption);

                options.Version       = swaggerOption.GetValue <string>(nameof(options.Version));
                options.Name          = swaggerOption.GetValue <string>(nameof(options.Name));
                options.Title         = swaggerOption.GetValue <string>(nameof(options.Title));
                options.Description   = swaggerOption.GetValue <string>(nameof(options.Description));
                options.RoutePrefix   = swaggerOption.GetValue <string>(nameof(options.RoutePrefix));
                options.DocumentTitle = swaggerOption.GetValue <string>(nameof(options.DocumentTitle));

                swagger = options;
            });
            PreConfigure <StorageOptions>(options =>
            {
                var storageOption = configuration.GetSection("storage");
                Configure <StorageOptions>(storageOption);

                options.Mongodb        = storageOption.GetValue <string>(nameof(options.Mongodb));
                options.RedisIsEnabled = storageOption.GetValue <bool>(nameof(options.RedisIsEnabled));
                options.Redis          = storageOption.GetValue <string>(nameof(options.Redis));

                storage = options;
            });
            PreConfigure <CorsOptions>(options =>
            {
                var corsOption = configuration.GetSection("cors");
                Configure <CorsOptions>(corsOption);

                options.PolicyName = corsOption.GetValue <string>(nameof(options.PolicyName));
                options.Origins    = corsOption.GetValue <string>(nameof(options.Origins));

                cors = options;
            });
            PreConfigure <JwtOptions>(options =>
            {
                var jwtOption = configuration.GetSection("jwt");
                Configure <JwtOptions>(jwtOption);

                options.Issuer     = jwtOption.GetValue <string>(nameof(options.Issuer));
                options.Audience   = jwtOption.GetValue <string>(nameof(options.Audience));
                options.SigningKey = jwtOption.GetValue <string>(nameof(options.SigningKey));

                jwt = options;
            });
            PreConfigure <WorkerOptions>(options =>
            {
                var workerOption = configuration.GetSection("worker");
                Configure <WorkerOptions>(workerOption);

                options.IsEnabled = workerOption.GetValue <bool>(nameof(options.IsEnabled));
                options.Cron      = workerOption.GetValue <string>(nameof(options.Cron));

                worker = options;
            });
            PreConfigure <TencentCloudOptions>(options =>
            {
                var tencentCloudOption = configuration.GetSection("tencentCloud");
                Configure <TencentCloudOptions>(tencentCloudOption);

                options.SecretId  = tencentCloudOption.GetValue <string>(nameof(options.SecretId));
                options.SecretKey = tencentCloudOption.GetValue <string>(nameof(options.SecretKey));

                tencentCloud = options;
            });
            PreConfigure <AuthorizeOptions>(options =>
            {
                var authorizeOption = configuration.GetSection("authorize");
                var githubOption    = authorizeOption.GetSection("github");
                var giteeOption     = authorizeOption.GetSection("gitee");
                var alipayOption    = authorizeOption.GetSection("alipay");
                var dingtalkOption  = authorizeOption.GetSection("dingtalk");
                var microsoftOption = authorizeOption.GetSection("microsoft");
                var weiboOptions    = authorizeOption.GetSection("weibo");
                var qqOptions       = authorizeOption.GetSection("qq");

                Configure <AuthorizeOptions>(authorizeOption);
                Configure <GithubOptions>(githubOption);
                Configure <GiteeOptions>(giteeOption);
                Configure <AlipayOptions>(alipayOption);
                Configure <DingtalkOptions>(dingtalkOption);
                Configure <MicrosoftOptions>(microsoftOption);
                Configure <WeiboOptions>(weiboOptions);
                Configure <QQOptions>(qqOptions);

                options.Github = new GithubOptions
                {
                    ClientId     = githubOption.GetValue <string>(nameof(options.Github.ClientId)),
                    ClientSecret = githubOption.GetValue <string>(nameof(options.Github.ClientSecret)),
                    RedirectUrl  = githubOption.GetValue <string>(nameof(options.Github.RedirectUrl)),
                    Scope        = githubOption.GetValue <string>(nameof(options.Github.Scope))
                };
                options.Gitee = new GiteeOptions
                {
                    ClientId     = giteeOption.GetValue <string>(nameof(options.Gitee.ClientId)),
                    ClientSecret = giteeOption.GetValue <string>(nameof(options.Gitee.ClientSecret)),
                    RedirectUrl  = giteeOption.GetValue <string>(nameof(options.Gitee.RedirectUrl)),
                    Scope        = giteeOption.GetValue <string>(nameof(options.Gitee.Scope))
                };
                options.Alipay = new AlipayOptions
                {
                    AppId       = alipayOption.GetValue <string>(nameof(options.Alipay.AppId)),
                    RedirectUrl = alipayOption.GetValue <string>(nameof(options.Alipay.RedirectUrl)),
                    Scope       = alipayOption.GetValue <string>(nameof(options.Alipay.Scope)),
                    PrivateKey  = alipayOption.GetValue <string>(nameof(options.Alipay.PrivateKey)),
                    PublicKey   = alipayOption.GetValue <string>(nameof(options.Alipay.PublicKey))
                };
                options.Dingtalk = new DingtalkOptions
                {
                    AppId       = dingtalkOption.GetValue <string>(nameof(options.Dingtalk.AppId)),
                    AppSecret   = dingtalkOption.GetValue <string>(nameof(options.Dingtalk.AppSecret)),
                    RedirectUrl = dingtalkOption.GetValue <string>(nameof(options.Dingtalk.RedirectUrl)),
                    Scope       = dingtalkOption.GetValue <string>(nameof(options.Dingtalk.Scope))
                };
                options.Microsoft = new MicrosoftOptions
                {
                    ClientId     = microsoftOption.GetValue <string>(nameof(options.Microsoft.ClientId)),
                    ClientSecret = microsoftOption.GetValue <string>(nameof(options.Microsoft.ClientSecret)),
                    RedirectUrl  = microsoftOption.GetValue <string>(nameof(options.Microsoft.RedirectUrl)),
                    Scope        = microsoftOption.GetValue <string>(nameof(options.Microsoft.Scope))
                };
                options.Weibo = new WeiboOptions
                {
                    ClientId     = weiboOptions.GetValue <string>(nameof(options.Weibo.ClientId)),
                    ClientSecret = weiboOptions.GetValue <string>(nameof(options.Weibo.ClientSecret)),
                    RedirectUrl  = weiboOptions.GetValue <string>(nameof(options.Weibo.RedirectUrl)),
                    Scope        = weiboOptions.GetValue <string>(nameof(options.Weibo.Scope))
                };
                options.QQ = new QQOptions
                {
                    ClientId     = qqOptions.GetValue <string>(nameof(options.QQ.ClientId)),
                    ClientSecret = qqOptions.GetValue <string>(nameof(options.QQ.ClientSecret)),
                    RedirectUrl  = qqOptions.GetValue <string>(nameof(options.QQ.RedirectUrl)),
                    Scope        = qqOptions.GetValue <string>(nameof(options.QQ.Scope))
                };

                authorize = options;
            });
            PreConfigure <AppOptions>(options =>
            {
                options.Https        = https;
                options.Blog         = blog;
                options.Swagger      = swagger;
                options.Storage      = storage;
                options.Cors         = cors;
                options.Jwt          = jwt;
                options.Worker       = worker;
                options.TencentCloud = tencentCloud;
                options.Authorize    = authorize;

                Configure <AppOptions>(item =>
                {
                    item.Swagger      = swagger;
                    item.Storage      = storage;
                    item.Cors         = cors;
                    item.Jwt          = jwt;
                    item.Worker       = worker;
                    item.TencentCloud = tencentCloud;
                    item.Authorize    = authorize;
                });
            });
        }
Esempio n. 16
0
 public Task <bool> SetOptions(BlogOptions options, CancellationToken cancellationToken = default) => throw new NotImplementedException();
Esempio n. 17
0
 public BlogPresenter(
     DataBaseConnection db,
     IOptions <BlogOptions> blogOptions) : base(db)
 {
     this.blogOptions = blogOptions.Value;
 }
Esempio n. 18
0
 public UpdateBlogOptionsModel(BlogOptions options)
 {
     NumberOfPostsToShowOnHomePage = options.NumberOfPostsToShowOnHomePage;
 }
Esempio n. 19
0
        public static IServiceCollection ConfigureIdenittyService(this IServiceCollection services, IConfiguration configuration, BlogOptions blogOptions)
        {
            services.AddIdentity <User, Role>(options =>
            {
                options.Password.RequireDigit           = false;
                options.Password.RequireLowercase       = true;
                options.Password.RequireUppercase       = false;
                options.Password.RequireNonAlphanumeric = false;

                options.SignIn.RequireConfirmedAccount = blogOptions.Account.RequireConfirmedAccount;
            })
            .AddUserManager <BlogUserManager>()
            .AddRoleManager <BlogRoleManager>()
            .AddSignInManager <BlogSignInManager>()
            .AddDefaultTokenProviders()
            .AddEntityFrameworkStores <BlogDbContext>();

            services.AddScoped <CustomCookieAuthenticationEvents>();
            services.ConfigureApplicationCookie(options =>
            {
                options.EventsType = typeof(CustomCookieAuthenticationEvents);
            });

            // default add by identity
            // services.AddAuthentication();

            var authenticationBuilder = services.AddAuthentication();

            services.Configure <AuthenticationOptions>(options =>
            {
                // options.DefaultScheme = "Cookies";
            });

            if (configuration.GetValue <bool>("Authentication:Microsoft:Enabled"))
            {
                // test ok
                authenticationBuilder.AddMicrosoftAccount(options =>
                {
                    options.ClientId         = configuration["Authentication:Microsoft:ClientId"];
                    options.ClientSecret     = configuration["Authentication:Microsoft:ClientSecret"];
                    options.CallbackPath     = new PathString("/signin-microsoft");
                    options.AccessDeniedPath = new PathString("/account/accessdenied");
                });
            }
            if (configuration.GetValue <bool>("Authentication:GitHub:Enabled"))
            {
                // test ok
                authenticationBuilder.AddGitHub(options =>
                {
                    options.ClientId         = configuration["Authentication:GitHub:ClientId"];
                    options.ClientSecret     = configuration["Authentication:GitHub:ClientSecret"];
                    options.CallbackPath     = new PathString("/signin-github");
                    options.AccessDeniedPath = new PathString("/account/accessdenied");
                });
            }
            if (configuration.GetValue <bool>("Authentication:Google:Enabled"))
            {
                // test ok
                authenticationBuilder.AddGoogle(options =>
                {
                    options.ClientId         = configuration["Authentication:Google:ClientId"];
                    options.ClientSecret     = configuration["Authentication:Google:ClientSecret"];
                    options.CallbackPath     = new PathString("/signin-google");
                    options.AccessDeniedPath = new PathString("/account/accessdenied");
                });
            }
            if (configuration.GetValue <bool>("Authentication:AzureAD:Enabled"))
            {
                // test ok
                authenticationBuilder.AddAzureAD(options =>
                {
                    options.TenantId              = configuration["Authentication:AzureAD:TenantId"];
                    options.ClientId              = configuration["Authentication:AzureAD:ClientId"];
                    options.Instance              = configuration["Authentication:AzureAD:Instance"];
                    options.Domain                = configuration["Authentication:AzureAD:Domain"];
                    options.ClientSecret          = configuration["Authentication:AzureAD:ClientSecret"];
                    options.CallbackPath          = new PathString("/signin-azuread");
                    options.SignedOutCallbackPath = new PathString("/signout-callback-oidc");
                    options.CookieSchemeName      = "Identity.External";                // import
                });
                services.Configure <OpenIdConnectOptions>(AzureADDefaults.OpenIdScheme, options =>
                {
                    options.Authority = options.Authority + "/v2.0/";

                    // Per the code below, this application signs in users in any Work and School
                    // accounts and any Microsoft Personal Accounts.
                    // If you want to direct Azure AD to restrict the users that can sign-in, change
                    // the tenant value of the appsettings.json file in the following way:
                    // - only Work and School accounts => 'organizations'
                    // - only Microsoft Personal accounts => 'consumers'
                    // - Work and School and Personal accounts => 'common'

                    // If you want to restrict the users that can sign-in to only one tenant
                    // set the tenant value in the appsettings.json file to the tenant ID of this
                    // organization, and set ValidateIssuer below to true.

                    // If you want to restrict the users that can sign-in to several organizations
                    // Set the tenant value in the appsettings.json file to 'organizations', set
                    // ValidateIssuer, above to 'true', and add the issuers you want to accept to the
                    // options.TokenValidationParameters.ValidIssuers collection
                    options.TokenValidationParameters.ValidateIssuer = false;
                });
            }


            if (configuration.GetValue <bool>("Authentication:OpenIdConnect:Enabled"))
            {
                authenticationBuilder.AddOpenIdConnect(options =>
                {
                    options.CallbackPath         = new PathString("/signin-oidc");
                    options.AccessDeniedPath     = new PathString("/account/accessdenied");
                    options.ClientId             = configuration["Authentication:OpenIdConnect:ClientId"];
                    options.ClientSecret         = configuration["Authentication:OpenIdConnect:ClientSecret"];
                    options.Authority            = configuration["Authentication:OpenIdConnect:Authority"];
                    options.ResponseType         = configuration["Authentication:OpenIdConnect:ResponseType"];
                    options.RequireHttpsMetadata = false;
                    options.Scope.Add("openid");
                    options.Scope.Add("email");
                });
            }


            services.AddAuthorization(options =>
            {
            });

            return(services);
        }
Esempio n. 20
0
 public Task <bool> SetOptions(BlogOptions options, CancellationToken cancellationToken = default) => Main.SetOptions(options, cancellationToken);
Esempio n. 21
0
 public async Task <bool> SetOptions([FromBody] BlogOptions options)
 {
     return(await BlogService.SetOptions(options));
 }
 public async Task OnGetAsync()
 {
     BlogOptions = await Service.GetOptions();
 }
Esempio n. 23
0
        // full: delete diff post for api remote
        public async Task Push(string name = "", bool full = false)
        {
            if (string.IsNullOrEmpty(name))
            {
                name = Option.CurrentRemote;
            }

            Logger.LogInformation($"Push to remote {name}.");

            if (Option.Remotes.TryGetValue(name, out var remote))
            {
                Logger.LogInformation($"Detect remote {remote.Name} ({Enum.GetName(typeof(RemoteType), remote.Type)}).");
                switch (remote.Type)
                {
                case RemoteType.LocalFS:
                {
                    await toLocalFS(remote);
                }
                break;

                case RemoteType.RemoteFS:
                {
                    throw new NotSupportedException("Not support pushing to remote file system, please push to local file system and sync to remote.");
                }

                case RemoteType.Api:
                {
                    await Connect(name);

                    Logger.LogInformation($"Fetch remote posts.");

                    await Remote.SetOptions(await Local.GetOptions());

                    await SyncRecordRepository(Local.PostService, Remote.PostService, full);

                    await SyncRecordRepository(Local.PageService, Remote.PageService, full);

                    await SyncRecordRepository(Local.LayoutService, Remote.LayoutService, full);
                }
                break;

                case RemoteType.Git:
                {
                    await Connect(name);

                    string tempDist = Path.Join(Environment.CurrentDirectory, "temp/dist");

                    Logger.LogInformation("Generate data.");

                    await toLocalFS(new RemoteOption
                        {
                            Uri  = tempDist,
                            Type = RemoteType.LocalFS,
                            Name = remote.Name
                        });

                    FSExtensions.CopyDirectory(tempDist, GitTempFolder);

                    Logger.LogInformation("Load git config.");

                    string userName = Option.Properties[$"remote.{remote.Name}.git.username"],
                           password = Option.Properties[$"remote.{remote.Name}.git.password"];

                    {
                        if (string.IsNullOrEmpty(userName))
                        {
                            userName = ConsoleExtensions.Input("Input username: "******"Input password: "******"Commit to git.");

                        LibGit2Sharp.Commands.Stage(repo, "*");

                        var signature = new LibGit2Sharp.Signature(
                            new Identity("AcBlog.Tools.Sdk", "tools.sdk@acblog"), DateTimeOffset.Now);
                        repo.Commit(DateTimeOffset.Now.ToString(), signature, signature, new CommitOptions
                            {
                                AllowEmptyCommit = true
                            });

                        Logger.LogInformation($"Push to {repo.Head.RemoteName}.");

                        PushOptions options = new PushOptions
                        {
                            CredentialsProvider = new CredentialsHandler(
                                (url, usernameFromUrl, types) =>
                                new UsernamePasswordCredentials()
                                {
                                    Username = string.IsNullOrEmpty(userName) ? usernameFromUrl : userName,
                                    Password = password
                                })
                        };
                        repo.Network.Push(repo.Head, options);
                    }
                }
                break;
                }
            }
            else
            {
                throw new Exception("No remote");
            }

            async Task toLocalFS(RemoteOption remote)
            {
                FSBuilder fsBuilder = new FSBuilder(remote.Uri);

                fsBuilder.EnsureDirectoryEmpty();

                List <Post> posts = new List <Post>();

                await foreach (var item in Local.PostService.GetAllItems().IgnoreNull())
                {
                    Logger.LogInformation($"Loaded Post {item.Id}: {item.Title}");
                    posts.Add(item);
                }

                List <Layout> layouts = new List <Layout>();

                await foreach (var item in Local.LayoutService.GetAllItems().IgnoreNull())
                {
                    Logger.LogInformation($"Loaded Layout {item.Id}");
                    layouts.Add(item);
                }

                List <Page> pages = new List <Page>();

                await foreach (var item in Local.PageService.GetAllItems().IgnoreNull())
                {
                    Logger.LogInformation($"Loaded Page {item.Id}: {item.Title}");
                    pages.Add(item);
                }

                var baseAddress = Option.Properties[$"remote.{remote.Name}.generator.baseAddress"];

                List <Data.Models.File> files = new List <Data.Models.File>();

                {
                    string path = Path.Join(Environment.CurrentDirectory, AssetsPath);
                    if (Directory.Exists(path))
                    {
                        foreach (var file in Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories))
                        {
                            var id             = Path.GetRelativePath(Environment.CurrentDirectory, file).Replace('\\', '/');
                            Data.Models.File f = new Data.Models.File
                            {
                                Id  = id,
                                Uri = string.IsNullOrWhiteSpace(baseAddress) ? $"/{id}" : $"{baseAddress.TrimEnd('/')}/{id}"
                            };
                            files.Add(f);
                        }
                    }
                }

                Logger.LogInformation("Build data.");
                {
                    BlogOptions options = await Local.GetOptions();

                    BlogBuilder builder = new BlogBuilder(options, Path.Join(remote.Uri));
                    await builder.Build();

                    await builder.BuildPosts(posts);

                    await builder.BuildLayouts(layouts);

                    await builder.BuildPages(pages);

                    await builder.BuildFiles(files);
                }

                {
                    if (!string.IsNullOrEmpty(baseAddress))
                    {
                        Logger.LogInformation("Build sitemap.");
                        var sub = fsBuilder.CreateSubDirectoryBuilder("Site");
                        {
                            var siteMapBuilder = await Local.BuildSitemap(baseAddress);

                            await using var st     = sub.GetFileRewriteStream("sitemap.xml");
                            await using var writer = XmlWriter.Create(st, new XmlWriterSettings { Async = true });
                            siteMapBuilder.Build().WriteTo(writer);
                        }
                        Logger.LogInformation("Build feed.");
                        {
                            var feed = await Local.BuildSyndication(baseAddress);

                            await using (var st = sub.GetFileRewriteStream("atom.xml"))
                            {
                                await using var writer = XmlWriter.Create(st, new XmlWriterSettings { Async = true });
                                feed.GetAtom10Formatter().WriteTo(writer);
                            }
                            await using (var st = sub.GetFileRewriteStream("rss.xml"))
                            {
                                await using var writer = XmlWriter.Create(st, new XmlWriterSettings { Async = true });
                                feed.GetRss20Formatter().WriteTo(writer);
                            }
                        }
                    }
                }
                {
                    string assetsPath = Path.Join(Environment.CurrentDirectory, AssetsPath);
                    if (Directory.Exists(assetsPath))
                    {
                        Logger.LogInformation("Copy assets.");
                        FSExtensions.CopyDirectory(assetsPath, Path.Join(remote.Uri, AssetsPath));
                    }
                }
            }
        }
Esempio n. 24
0
        internal static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
        .ConfigureAppConfiguration((hostingContext, config) =>
        {
            config.AddYamlFile("appsettings.yml", optional: true, reloadOnChange: true);

            var configDictionary    = config.Build().SerializeToJson();
            Console.ForegroundColor = ConsoleColor.Blue;
            Console.WriteLine($"appsettings {@configDictionary}");
            Console.ResetColor();
        })
        .ConfigureWebHostDefaults(webBuilder =>
        {
            webBuilder.UseStartup <Startup>();
        })
        .ConfigureServices((hostingContext, services) =>
        {
            var https = new HttpsOptions();
            var blog  = new BlogOptions();

            var httpsOption       = hostingContext.Configuration.GetSection("https");
            https.ListenAddress   = httpsOption.GetValue <string>(nameof(https.ListenAddress));
            https.ListenPort      = httpsOption.GetValue <int>(nameof(https.ListenPort));
            https.PublicCertFile  = httpsOption.GetValue <string>(nameof(https.PublicCertFile));
            https.PrivateCertFile = httpsOption.GetValue <string>(nameof(https.PrivateCertFile));
            services.Configure <HttpsOptions>(httpsOption);

            var blogOption   = hostingContext.Configuration.GetSection("blog");
            blog.AdminUrl    = blogOption.GetValue <string>(nameof(BlogOptions.AdminUrl));
            blog.ApiUrl      = blogOption.GetValue <string>(nameof(BlogOptions.ApiUrl));
            blog.WebUrl      = blogOption.GetValue <string>(nameof(BlogOptions.WebUrl));
            blog.StaticUrl   = blogOption.GetValue <string>(nameof(BlogOptions.StaticUrl));
            blog.TelegramUrl = blogOption.GetValue <string>(nameof(BlogOptions.TelegramUrl));
            blog.GithubUrl   = blogOption.GetValue <string>(nameof(BlogOptions.GithubUrl));
            blog.Title       = blogOption.GetValue <string>(nameof(BlogOptions.Title));
            services.Configure <BlogOptions>(blogOption);

            services.Configure <KestrelServerOptions>(options =>
            {
                IPAddress address = null;
                try
                {
                    address = IPAddress.Parse(https.ListenAddress);
                }
                catch (FormatException)
                {
                    address = Dns.GetHostAddresses(https.ListenAddress).FirstOrDefault();
                }
                IPEndPoint SharpBlogEndpoint = new IPEndPoint(address, https.ListenPort);

                options.Listen(SharpBlogEndpoint, listenOptions =>
                {
                    listenOptions.UseHttps(httpsOptions =>
                    {
                        if (!File.Exists(https.PrivateCertFile) || !File.Exists(https.PublicCertFile))
                        {
                            X509Certificate2 certificate = SharpBlogEndpoint.Address.CreateSelfSignedCertificate("CN=SharpBlog");
                            File.WriteAllBytes(https.PrivateCertFile, certificate.Export(X509ContentType.Pfx));
                            File.WriteAllBytes(https.PublicCertFile, certificate.Export(X509ContentType.Cert));
                        }
                        try
                        {
                            httpsOptions.ServerCertificate = new X509Certificate2(https.PrivateCertFile);
                        }
                        catch (CryptographicException)
                        {
                            Console.Error.WriteLine("Error importing SharpBlog certificate.");
                        }
                        httpsOptions.SslProtocols = SslProtocols.Tls12;
                    });
                });
            });

            services.AddRazorPages();
            services.AddServerSideBlazor()
            .AddHubOptions(options =>
            {
                options.EnableDetailedErrors      = true;
                options.MaximumReceiveMessageSize = 10 * 1024 * 1024;
            });
            services.AddAntDesign();
            services.AddScoped <AuthenticationStateProvider, OAuthService>();
            services.Configure <ProSettings>(x =>
            {
                x.Title        = blog.Title;
                x.NavTheme     = "light";
                x.Layout       = "mix";
                x.PrimaryColor = "daybreak";
                x.ContentWidth = "Fluid";
                x.HeaderHeight = 50;
            });
            services.AddHttpClient("api", x =>
            {
                x.BaseAddress = new Uri(blog.ApiUrl);
            }).ConfigurePrimaryHttpMessageHandler(() => new HttpClientHandler {
                ServerCertificateCustomValidationCallback = (httpRequestMessage, cert, cetChain, policyErrors) => {
                    return(true);
                }
            });
        }).UseSerilog();
Esempio n. 25
0
        // full: delete diff post for api remote
        public async Task Push(string name = "", bool full = false)
        {
            if (string.IsNullOrEmpty(name))
            {
                name = Option.CurrentRemote;
            }

            Logger.LogInformation($"Push to remote {name}.");

            if (Option.Remotes.TryGetValue(name, out var remote))
            {
                Logger.LogInformation($"Detect remote {remote.Name} ({Enum.GetName(typeof(RemoteType), remote.Type)}).");
                switch (remote.Type)
                {
                case RemoteType.LocalFS:
                {
                    await toLocalFS(remote);
                }
                break;

                case RemoteType.RemoteFS:
                {
                    throw new NotSupportedException("Not support pushing to remote file system, please push to local file system and sync to remote.");
                }

                case RemoteType.Api:
                {
                    await Connect(name);

                    Logger.LogInformation($"Fetch remote posts.");
                    HashSet <string> remoteIds = (await Remote.PostService.All()).ToHashSet();
                    foreach (var item in await Local.PostService.GetAllPosts())
                    {
                        if (item is null)
                        {
                            continue;
                        }
                        Logger.LogInformation($"Loaded {item.Id}: {item.Title}");
                        if (remoteIds.Contains(item.Id))
                        {
                            var result = await Remote.PostService.Update(item);

                            if (result)
                            {
                                Logger.LogInformation($"Updated {item.Id}");
                            }
                            else
                            {
                                Logger.LogError($"Failed to update {item.Id}");
                            }
                        }
                        else
                        {
                            var result = await Remote.PostService.Create(item);

                            if (result is null)
                            {
                                Logger.LogError($"Failed to create {item.Id}");
                            }
                            else
                            {
                                Logger.LogInformation($"Created {item.Id}");
                            }
                        }
                        remoteIds.Remove(item.Id);
                    }
                    if (full)
                    {
                        foreach (var v in remoteIds)
                        {
                            var result = await Remote.PostService.Delete(v);

                            if (result)
                            {
                                Logger.LogInformation($"Deleted {v}.");
                            }
                            else
                            {
                                Logger.LogError($"Failed to deleted {v}.");
                            }
                        }
                    }
                }
                break;

                case RemoteType.Git:
                {
                    await Connect(name);

                    string tempDist = Path.Join(Environment.CurrentDirectory, "temp/dist");

                    Logger.LogInformation("Generate data.");

                    await toLocalFS(new RemoteOption
                        {
                            Uri  = tempDist,
                            Type = RemoteType.LocalFS,
                            Name = remote.Name
                        });

                    FSExtensions.CopyDirectory(tempDist, GitTempFolder);

                    Logger.LogInformation("Load git config.");

                    string userName = Option.Properties[$"remote.{remote.Name}.git.username"],
                           password = Option.Properties[$"remote.{remote.Name}.git.password"];

                    {
                        if (string.IsNullOrEmpty(userName))
                        {
                            userName = ConsoleExtensions.Input("Input username: "******"Input password: "******"Commit to git.");

                        LibGit2Sharp.Commands.Stage(repo, "*");

                        var signature = new LibGit2Sharp.Signature(
                            new Identity("AcBlog.Tools.Sdk", "tools.sdk@acblog"), DateTimeOffset.Now);
                        repo.Commit(DateTimeOffset.Now.ToString(), signature, signature, new CommitOptions
                            {
                                AllowEmptyCommit = true
                            });

                        Logger.LogInformation($"Push to {repo.Head.RemoteName}.");

                        PushOptions options = new LibGit2Sharp.PushOptions();
                        options.CredentialsProvider = new CredentialsHandler(
                            (url, usernameFromUrl, types) =>
                            new UsernamePasswordCredentials()
                            {
                                Username = string.IsNullOrEmpty(userName) ? usernameFromUrl : userName,
                                Password = password
                            });
                        repo.Network.Push(repo.Head, options);
                    }
                }
                break;
                }
            }
            else
            {
                throw new Exception("No remote");
            }

            async Task toLocalFS(RemoteOption remote)
            {
                FSBuilder fsBuilder = new FSBuilder(remote.Uri);

                fsBuilder.EnsureDirectoryEmpty();

                List <Post> posts = new List <Post>();

                foreach (var item in await Local.PostService.GetAllPosts())
                {
                    if (item is null)
                    {
                        continue;
                    }
                    Logger.LogInformation($"Loaded {item.Id}: {item.Title}");
                    posts.Add(item);
                }

                Logger.LogInformation("Build data.");
                {
                    BlogOptions options = await Local.GetOptions();

                    BlogBuilder builder = new BlogBuilder(options, Path.Join(remote.Uri));
                    await builder.Build();
                }

                {
                    PostRepositoryBuilder builder = new PostRepositoryBuilder(posts, Path.Join(remote.Uri, "posts"));
                    await builder.Build();
                }

                {
                    var baseAddress = Option.Properties[$"remote.{remote.Name}.generator.baseAddress"];
                    if (!string.IsNullOrEmpty(baseAddress))
                    {
                        Logger.LogInformation("Build sitemap.");
                        var sub = fsBuilder.CreateSubDirectoryBuilder("Site");
                        {
                            var siteMapBuilder = await Local.BuildSitemap(baseAddress);

                            using var st     = sub.GetFileRewriteStream("sitemap.xml");
                            using var writer = XmlWriter.Create(st);
                            siteMapBuilder.Build().WriteTo(writer);
                        }
                        Logger.LogInformation("Build feed.");
                        {
                            var feed = await Local.BuildSyndication(baseAddress);

                            using var st     = sub.GetFileRewriteStream("atom.xml");
                            using var writer = XmlWriter.Create(st);
                            feed.GetAtom10Formatter().WriteTo(writer);
                        }
                    }
                }
            }
        }