|
@ -11,7 +11,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Bootstrap.Security.DataAccess" Version="2.2.21" />
|
||||
<PackageReference Include="Bootstrap.Security.Mvc" Version="2.2.16" />
|
||||
<PackageReference Include="Bootstrap.Security.Mvc" Version="2.2.17" />
|
||||
<PackageReference Include="Longbow.Configuration" Version="2.2.7" />
|
||||
<PackageReference Include="Longbow.Tasks" Version="2.2.23" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.App" />
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
using Bootstrap.Admin.Models;
|
||||
using Bootstrap.DataAccess;
|
||||
using Longbow.GiteeAuth;
|
||||
using Longbow.GitHubAuth;
|
||||
using Longbow.Web;
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.AspNetCore.Authentication.Cookies;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
|
@ -30,7 +33,6 @@ namespace Bootstrap.Admin.Controllers
|
|||
{
|
||||
if (!User.Identity.IsAuthenticated) return Login();
|
||||
|
||||
var user = UserHelper.RetrieveUserByUserName(User.Identity.Name);
|
||||
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
var urlReferrer = Request.Headers["Referer"].FirstOrDefault();
|
||||
return View(new LockModel(this)
|
||||
|
@ -107,10 +109,11 @@ namespace Bootstrap.Admin.Controllers
|
|||
/// Logout this instance.
|
||||
/// </summary>
|
||||
/// <returns>The logout.</returns>
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Logout()
|
||||
{
|
||||
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
return Redirect("~" + CookieAuthenticationDefaults.LoginPath);
|
||||
await HttpContext.SignOutAsync();
|
||||
return Redirect(Request.PathBase + CookieAuthenticationDefaults.LoginPath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -118,6 +121,29 @@ namespace Bootstrap.Admin.Controllers
|
|||
/// </summary>
|
||||
/// <returns>The denied.</returns>
|
||||
[ResponseCache(Duration = 600)]
|
||||
[HttpGet]
|
||||
public ActionResult AccessDenied() => View("Error", ErrorModel.CreateById(403));
|
||||
|
||||
/// <summary>
|
||||
/// Gitee 认证
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public IActionResult Gitee([FromServices]IConfiguration config)
|
||||
{
|
||||
var enabled = config.GetValue($"{nameof(GiteeOptions)}:Eanbeld", false);
|
||||
return Challenge(enabled ? GiteeDefaults.AuthenticationScheme : CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// GitHub 认证
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
public IActionResult GitHub([FromServices]IConfiguration config)
|
||||
{
|
||||
var enabled = config.GetValue($"{nameof(GitHubOptions)}:Eanbeld", false);
|
||||
return Challenge(enabled ? GitHubDefaults.AuthenticationScheme : CookieAuthenticationDefaults.AuthenticationScheme);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ using Bootstrap.Security;
|
|||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Principal;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers
|
||||
{
|
||||
|
@ -48,7 +49,7 @@ namespace Bootstrap.Admin.Controllers
|
|||
[HttpPost]
|
||||
public BootstrapUser RetrieveUserByUserName([FromBody]string userName)
|
||||
{
|
||||
return UserHelper.RetrieveUserByUserName(userName);
|
||||
return UserHelper.RetrieveUserByUserName(new GenericIdentity(userName));
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
using Bootstrap.DataAccess;
|
||||
using Bootstrap.DataAccess;
|
||||
using Longbow.Web.SignalR;
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.SignalR;
|
||||
using System.Linq;
|
||||
using System.Security.Principal;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Bootstrap.Admin.Controllers.Api
|
||||
|
@ -24,7 +25,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
[HttpGet]
|
||||
public bool Get(string userName)
|
||||
{
|
||||
return UserHelper.RetrieveUserByUserName(userName) == null && !UserHelper.RetrieveNewUsers().Any(u => u.UserName == userName);
|
||||
return UserHelper.RetrieveUserByUserName(new GenericIdentity(userName)) == null && !UserHelper.RetrieveNewUsers().Any(u => u.UserName == userName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -57,7 +58,7 @@ namespace Bootstrap.Admin.Controllers.Api
|
|||
[HttpPut]
|
||||
public bool Put([FromBody]ResetUser user)
|
||||
{
|
||||
if (UserHelper.RetrieveUserByUserName(user.UserName) == null) return true;
|
||||
if (UserHelper.RetrieveUserByUserName(new GenericIdentity(user.UserName)) == null) return true;
|
||||
return UserHelper.ForgotPassword(user);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ namespace Bootstrap.Admin.Controllers
|
|||
public IActionResult Index()
|
||||
{
|
||||
var model = new HeaderBarModel(User.Identity);
|
||||
if (string.IsNullOrEmpty(model.UserName)) return Redirect(Request.PathBase + CookieAuthenticationDefaults.LogoutPath);
|
||||
var url = DictHelper.RetrieveHomeUrl(model.AppCode);
|
||||
return url.Equals("~/Home/Index", System.StringComparison.OrdinalIgnoreCase) ? (IActionResult)View(model) : Redirect(url);
|
||||
}
|
||||
|
@ -39,4 +40,4 @@ namespace Bootstrap.Admin.Controllers
|
|||
return View(model);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ using Microsoft.Extensions.Diagnostics.HealthChecks;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Principal;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Task = System.Threading.Tasks.Task;
|
||||
|
@ -68,7 +69,7 @@ namespace Bootstrap.Admin.HealthChecks
|
|||
try
|
||||
{
|
||||
DbContextManager.Exception = null;
|
||||
var user = UserHelper.RetrieveUserByUserName(userName);
|
||||
var user = UserHelper.RetrieveUserByUserName(new GenericIdentity(userName));
|
||||
displayName = user?.DisplayName;
|
||||
roles = string.Join(",", RoleHelper.RetrievesByUserName(userName) ?? new string[0]);
|
||||
menusCount = MenuHelper.RetrieveMenusByUserName(userName)?.Count() ?? 0;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Bootstrap.DataAccess;
|
||||
using System;
|
||||
using System.Security.Principal;
|
||||
|
||||
namespace Bootstrap.Admin.Models
|
||||
|
@ -14,13 +15,16 @@ namespace Bootstrap.Admin.Models
|
|||
/// <param name="identity"></param>
|
||||
public HeaderBarModel(IIdentity identity)
|
||||
{
|
||||
var user = UserHelper.RetrieveUserByUserName(identity.Name);
|
||||
Icon = string.Format("{0}{1}", DictHelper.RetrieveIconFolderPath(), user.Icon);
|
||||
DisplayName = user.DisplayName;
|
||||
UserName = user.UserName;
|
||||
AppCode = user.App;
|
||||
Css = user.Css;
|
||||
ActiveCss = string.IsNullOrEmpty(Css) ? Theme : Css;
|
||||
var user = UserHelper.RetrieveUserByUserName(identity);
|
||||
if (user != null)
|
||||
{
|
||||
Icon = user.Icon.Contains("://", StringComparison.OrdinalIgnoreCase) ? user.Icon : string.Format("{0}{1}", DictHelper.RetrieveIconFolderPath(), user.Icon);
|
||||
DisplayName = user.DisplayName;
|
||||
UserName = user.UserName;
|
||||
AppCode = user.App;
|
||||
Css = user.Css;
|
||||
ActiveCss = string.IsNullOrEmpty(Css) ? Theme : Css;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -53,4 +57,4 @@ namespace Bootstrap.Admin.Models
|
|||
/// </summary>
|
||||
public string ActiveCss { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,12 @@
|
|||
namespace Bootstrap.Admin.Models
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// 登陆页面 Model
|
||||
/// </summary>
|
||||
public class LoginModel : ModelBase
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// 默认构造函数
|
||||
/// </summary>
|
||||
public LoginModel()
|
||||
{
|
||||
|
@ -21,7 +21,7 @@ namespace Bootstrap.Admin.Models
|
|||
public string ImageLibUrl { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// 是否登录认证失败
|
||||
/// 是否登录认证失败 为真时客户端弹出滑块验证码
|
||||
/// </summary>
|
||||
public bool AuthFailed { get; set; }
|
||||
}
|
||||
|
|
|
@ -20,6 +20,11 @@ namespace Bootstrap.Admin.Models
|
|||
/// </summary>
|
||||
public string FileName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 获得 是否为第三方用户
|
||||
/// </summary>
|
||||
public bool External { get; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
|
@ -39,6 +44,8 @@ namespace Bootstrap.Admin.Models
|
|||
FileName = Path.GetFileName(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
if (controller.User.Identity.AuthenticationType != Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme) External = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using Bootstrap.DataAccess;
|
||||
using Longbow.GiteeAuth;
|
||||
using Longbow.Web;
|
||||
using Longbow.Web.SignalR;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
|
@ -60,7 +61,7 @@ namespace Bootstrap.Admin
|
|||
services.AddSignalR().AddJsonProtocalDefault();
|
||||
services.AddSignalRExceptionFilterHandler<SignalRHub>((client, ex) => client.SendMessageBody(ex).ConfigureAwait(false));
|
||||
services.AddResponseCompression();
|
||||
services.AddBootstrapAdminAuthentication();
|
||||
services.AddBootstrapAdminAuthentication().AddGitee(OAuthHelper.Configure).AddGitHub(OAuthHelper.Configure);
|
||||
services.AddSwagger();
|
||||
services.AddButtonAuthorization(MenuHelper.AuthorizateButtons);
|
||||
services.AddBootstrapAdminBackgroundTask();
|
||||
|
|
|
@ -43,10 +43,10 @@
|
|||
}
|
||||
<div class="container">
|
||||
<input id="imgUrl" type="hidden" value="@Model.ImageLibUrl" />
|
||||
<form id="login" method="post" class="form-signin">
|
||||
<form id="login" method="post" class="form-signin" data-demo="True">
|
||||
<h2 class="form-signin-heading">@Model.Title</h2>
|
||||
<div class="login-wrap" data-auth="@Model.AuthFailed" data-toggle="LgbValidate" data-valid-button="button[type='submit']">
|
||||
<div class="alert alert-danger" asp-condition="@Model.AuthFailed">用户名或密码错误!</div>
|
||||
<div class="alert alert-danger d-none" asp-condition="@Model.AuthFailed">用户名或密码错误!</div>
|
||||
<div class="form-group">
|
||||
<div class="input-group">
|
||||
<div class="input-group-prepend">
|
||||
|
@ -54,7 +54,7 @@
|
|||
<span class="fa fa-user"></span>
|
||||
</div>
|
||||
</div>
|
||||
<input type="text" name="userName" class="form-control" placeholder="用户名" maxlength="16" data-required-msg="请输入用户名" value="@ViewBag.UserName" autofocus data-valid="true" />
|
||||
<input type="text" name="userName" class="form-control" placeholder="用户名" maxlength="16" data-required-msg="请输入用户名" value="" autofocus data-valid="true" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
|
@ -64,7 +64,7 @@
|
|||
<span class="fa fa-lock"></span>
|
||||
</div>
|
||||
</div>
|
||||
<input type="password" name="password" class="form-control" value="@ViewBag.Password" placeholder="密码" maxlength="16" data-required-msg="请输入密码" data-valid="true" />
|
||||
<input type="password" name="password" class="form-control" value="" placeholder="密码" maxlength="16" data-required-msg="请输入密码" data-valid="true" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group rememberPwd" onselectstart="return false">
|
||||
|
@ -72,11 +72,43 @@
|
|||
<span>记住密码自动登录</span>
|
||||
<input id="remember" name="remember" type="hidden" value="false" />
|
||||
</div>
|
||||
<button class="btn btn-lg btn-login btn-block" type="submit">登 录</button>
|
||||
<button class="btn btn-lg btn-login btn-block" data-toggle="tooltip" title="不填写密码默认使用 Gitee 认证" type="submit">登 录</button>
|
||||
<div class="login-footer">
|
||||
<a href="#" data-method="register">申请账号</a>
|
||||
<a href="#" data-method="forgot">忘记密码</a>
|
||||
</div>
|
||||
<div class="login-other">
|
||||
<span class="text-muted">
|
||||
其他方式登录
|
||||
</span>
|
||||
</div>
|
||||
<div class="login-list">
|
||||
<div class="item">
|
||||
<a href="~/Account/Gitee" data-toggle="tooltip" title="使用 Gitee 帐号登录">
|
||||
<img class="item" src="~/images/gitee.svg" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="item">
|
||||
<a href="~/Account/GitHub" data-toggle="tooltip" title="使用 GitHub 帐号登录">
|
||||
<img class="item" src="~/images/git.svg" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="item">
|
||||
<a href="#" data-toggle="tooltip" title="微信-暂未实现">
|
||||
<img class="item" src="~/images/weixin-2.svg" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="item">
|
||||
<a href="#" data-toggle="tooltip" title="QQ-暂未实现">
|
||||
<img class="item" src="~/images/qq-2.svg" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="item">
|
||||
<a href="#" data-toggle="tooltip" title="支付宝-暂未实现">
|
||||
<img class="item" src="~/images/zhifubao-2.svg" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="slidercaptcha card">
|
||||
<div class="card-header">
|
||||
<span>请完成安全验证</span>
|
||||
|
|
|
@ -53,7 +53,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card" asp-auth="savePassword">
|
||||
<div class="card" asp-auth="savePassword" asp-condition="!@Model.External">
|
||||
<div class="card-header">修改密码</div>
|
||||
<div class="card-body" data-toggle="LgbValidate" data-valid-button="#btnSavePassword">
|
||||
<div class="alert alert-danger" role="alert" asp-condition="@Model.IsDemo">
|
||||
|
|
|
@ -60,6 +60,28 @@
|
|||
"Folder": "TaskStorage",
|
||||
"Secure": false
|
||||
},
|
||||
"GiteeOptions": {
|
||||
"Enabled": true,
|
||||
"ClientId": "9bfe9b95d813ca7d613b110a54eda28bf227154b314c95f0c69e7680d64525e1",
|
||||
"ClientSecret": "3427f2d901ba9afc76c1842a7303b2d67f8e098e71acc15051f89fe6f3d265db",
|
||||
"CallbackPath": "/signin-gitee",
|
||||
"HomePath": "/Admin/Profiles",
|
||||
"Scope": [ "user_info", "projects" ],
|
||||
"Roles": [ "Administrators" ],
|
||||
"App": "0",
|
||||
"StarredUrl": "https://gitee.com/api/v5/user/starred/LongbowEnterprise/BootstrapAdmin"
|
||||
},
|
||||
"GitHubOptions": {
|
||||
"Enabled": true,
|
||||
"ClientId": "ec53ecfe238558a0423b",
|
||||
"ClientSecret": "ffa759ca599df941b869efecb5e750bc1b27334e",
|
||||
"CallbackPath": "/signin-github",
|
||||
"HomePath": "/Admin/Profiles",
|
||||
"Scope": [ "user_info", "repo" ],
|
||||
"Roles": [ "Administrators" ],
|
||||
"App": "0",
|
||||
"StarredUrl": "https://api.github.com/user/starred/ArgoZhang/BootstrapAdmin"
|
||||
},
|
||||
"LongbowCache": {
|
||||
"Enabled": true,
|
||||
"CorsItems": [
|
||||
|
|
|
@ -66,6 +66,26 @@
|
|||
"Folder": "TaskStorage",
|
||||
"Secure": true
|
||||
},
|
||||
"GiteeOptions": {
|
||||
"Eanbeld": true,
|
||||
"ClientId": "<ClientId>",
|
||||
"ClientSecret": "<ClientSecret>",
|
||||
"CallbackPath": "/signin-gitee",
|
||||
"HomePath": "/Home/Index",
|
||||
"Scope": [ "user_info", "projects" ],
|
||||
"Roles": [ "Default" ],
|
||||
"App": "2"
|
||||
},
|
||||
"GitHubOptions": {
|
||||
"Eanbeld": true,
|
||||
"ClientId": "<ClientId>",
|
||||
"ClientSecret": "<ClientSecret>",
|
||||
"CallbackPath": "/signin-github",
|
||||
"HomePath": "/Home/Index",
|
||||
"Scope": [ "user_info", "repo" ],
|
||||
"Roles": [ "Default" ],
|
||||
"App": "2"
|
||||
},
|
||||
"LongbowCache": {
|
||||
"Enabled": true,
|
||||
"CorsItems": [
|
||||
|
|
|
@ -31,26 +31,30 @@
|
|||
|
||||
.login-wrap {
|
||||
padding: 0;
|
||||
margin: 36px 0 0 370px;
|
||||
margin: 18px 0 0 370px;
|
||||
width: 280px;
|
||||
}
|
||||
|
||||
.slidercaptcha {
|
||||
top: -254px;
|
||||
top: -272px;
|
||||
left: -15px;
|
||||
}
|
||||
|
||||
.slidercaptcha.card .card-body {
|
||||
padding: 15px 15px 0 15px;
|
||||
}
|
||||
|
||||
.slidercaptcha, .slidercaptcha.forgot {
|
||||
width: 310px;
|
||||
height: 280px;
|
||||
}
|
||||
|
||||
.login-wrap[data-auth="True"] {
|
||||
margin: 12px 0 0 370px;
|
||||
margin: 20px 0 0 370px;
|
||||
}
|
||||
|
||||
.login-wrap[data-auth="True"] .slidercaptcha {
|
||||
top: -282px;
|
||||
top: -264px;
|
||||
}
|
||||
|
||||
.login-wrap[data-auth="True"] .slidercaptcha, .slidercaptcha.forgot {
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
.login-wrap {
|
||||
padding: 20px;
|
||||
height: 270px;
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.login-wrap .rememberPwd {
|
||||
|
@ -27,8 +27,8 @@
|
|||
width: 13px;
|
||||
}
|
||||
|
||||
.login-wrap[data-auth="True"] {
|
||||
height: 330px;
|
||||
.login-wrap .card {
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
.login-footer a:last-child {
|
||||
|
@ -42,9 +42,10 @@
|
|||
font-weight: 300;
|
||||
font-family: 'Open Sans', sans-serif;
|
||||
box-shadow: 0 4px #e56b60;
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 0.625rem;
|
||||
outline: none !important;
|
||||
margin-top: -4px;
|
||||
margin-top: -0.5rem;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.btn-login:focus {
|
||||
|
@ -67,8 +68,8 @@
|
|||
box-shadow: 0 0 10px #fff;
|
||||
left: 0;
|
||||
right: 0;
|
||||
top: -232px;
|
||||
height: 234px;
|
||||
top: -270px;
|
||||
height: 226px;
|
||||
}
|
||||
|
||||
.slidercaptcha canvas:first-child {
|
||||
|
@ -81,6 +82,10 @@
|
|||
margin-top: -2px;
|
||||
}
|
||||
|
||||
.slidercaptcha.card .card-body {
|
||||
padding: 0.625rem 0 0 0;
|
||||
}
|
||||
|
||||
.slidercaptcha.card .card-header {
|
||||
background-image: none;
|
||||
background-color: rgba(0, 0, 0, 0.03);
|
||||
|
@ -104,3 +109,38 @@
|
|||
.slidercaptcha.reg {
|
||||
bottom: 60px;
|
||||
}
|
||||
|
||||
.login-other {
|
||||
display: table;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
margin: 0.25rem 0 0.625rem 0;
|
||||
}
|
||||
|
||||
.login-other:before, .login-other:after {
|
||||
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAACCAYAAACuTHuKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1OThBRDY4OUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1OThBRDY4QUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjU5OEFENjg3Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjU5OEFENjg4Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+VU513gAAADVJREFUeNrs0DENACAQBDBIWLGBJQby/mUcJn5sJXQmOQMAAAAAAJqt+2prAAAAAACg2xdgANk6BEVuJgyMAAAAAElFTkSuQmCC");
|
||||
content: '';
|
||||
display: table-cell;
|
||||
position: relative;
|
||||
top: 50%;
|
||||
width: 50%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.login-other:before {
|
||||
background-position: right 1em top 50%;
|
||||
}
|
||||
|
||||
.login-other:after {
|
||||
background-position: left 1em top 50%;
|
||||
}
|
||||
|
||||
.login-list {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.login-list .item {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 34.133333c263.918933 0 477.866667 213.947733 477.866667 477.866667s-213.947733 477.866667-477.866667 477.866667S34.133333 775.918933 34.133333 512 248.081067 34.133333 512 34.133333z m307.2 564.224v-176.981333a101.376 101.376 0 0 0-101.410133-101.376h-134.2464l32.392533 45.841067 97.860267 29.969066c18.158933 5.7344 29.696 22.562133 29.5936 40.618667v146.8416a42.325333 42.325333 0 0 1-29.5936 40.618667l-97.860267 30.0032-32.426667 45.841066h134.280534A101.376 101.376 0 0 0 819.2 598.357333z m-405.981867-66.628266h202.922667v-45.738667h-202.922667v45.738667zM311.569067 699.733333h134.2464l-32.392534-45.841066-97.860266-30.0032a42.325333 42.325333 0 0 1-29.559467-40.618667V436.565333v-0.1024a42.325333 42.325333 0 0 1 29.559467-40.618666l97.860266-30.037334 32.426667-45.806933H311.534933a101.376 101.376 0 0 0-101.410133 101.376v176.9472A101.376 101.376 0 0 0 311.569067 699.733333z" fill="#515151" /></svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M514.304 3.072c-281.344 0-509.44 228.096-509.44 509.44s228.096 509.44 509.44 509.44 509.44-228.096 509.44-509.44-228.096-509.44-509.44-509.44z m221.184 438.016c-1.024 4.096-3.328 10.24-6.656 17.408l-0.512 0.768c-19.712 42.24-71.168 125.184-71.168 125.184s0-0.256-0.256-0.512l-15.104 26.112H714.24l-138.496 184.576 31.488-125.44h-57.088l19.712-82.944c-16.128 3.84-35.072 9.216-57.6 16.384 0 0-30.464 17.92-87.552-34.304 0 0-38.656-34.048-16.128-42.496 9.472-3.584 46.08-8.192 75.008-12.032 38.912-5.12 62.976-8.192 62.976-8.192s-120.064 1.792-148.736-2.56c-28.416-4.352-64.768-52.224-72.448-93.952 0 0-12.032-23.04 25.6-12.032s192.768 42.24 192.768 42.24-201.984-61.952-215.296-77.056c-13.312-15.104-39.424-82.688-36.096-124.16 0 0 1.536-10.24 12.032-7.68 0 0 149.248 68.352 251.392 105.728 102.4 37.632 191.232 56.576 179.712 104.96z" fill="#3AABF9" /></svg>
|
After Width: | Height: | Size: 1.1 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M722.579864 496.275801H481.439296v-179.19996l240.799235-34.952526 0.341333 214.12973z m0 243.711946l-241.140568-34.702215v-179.996404h240.913013l0.227555 214.721374zM452.562502 492.08878h-182.431248v-147.842812l182.658804-24.80355-0.227556 172.646362z m0 209.737908l-182.431248-25.167638v-151.460944h182.431248v176.628582zM874.018053 150.004589A510.998642 510.998642 0 0 0 512.022756 0 510.998642 510.998642 0 0 0 150.027458 150.004589c-200.021289 200.499155-200.021289 523.491439 0 723.990595A510.998642 510.998642 0 0 0 512 1023.999772a510.998642 510.998642 0 0 0 361.995297-150.004588c199.975778-200.521911 199.975778-523.468684 0-723.990595z" fill="#1296db" /></svg>
|
After Width: | Height: | Size: 937 B |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M0 520.886c0-69.368 13.51-135.697 40.498-199.02 26.987-63.323 63.322-117.826 109.006-163.51 45.65-45.65 100.154-81.985 163.51-109.006A502.289 502.289 0 0 1 512 8.92c69.335 0 135.663 13.477 198.986 40.497 63.356 26.988 117.86 63.323 163.51 109.007 45.684 45.65 82.02 100.154 109.006 163.51A502.289 502.289 0 0 1 1024 520.852c0 111.318-32.504 211.472-97.511 300.494-64.975 88.989-148.48 150.825-250.484 185.476-5.351 0-9.348-0.99-11.99-2.973-2.676-1.982-4.196-3.997-4.526-6.012a59.458 59.458 0 0 1-0.495-8.984 7.663 7.663 0 0 1-0.991-3.006v-128.99c0-40.63-14.336-75.314-43.008-103.986 76.667-13.345 134.011-41.819 171.999-85.487 37.987-43.669 57.013-96.52 57.013-158.522 0-58.005-18.663-108.346-56.022-150.99 13.345-42.678 11-87.668-6.97-135.003-18.697-1.322-39.011 1.85-61.01 9.513-22 7.663-38.318 14.831-49.02 21.47-10.637 6.673-20.316 13.016-28.97 19.027-38.68-10.669-81.854-16.02-129.486-16.02-47.7 0-90.509 5.351-128.529 16.02-7.333-5.35-15.855-11.164-25.5-17.507-9.68-6.342-26.493-14.005-50.507-22.99-23.982-9.018-45.65-12.85-65.008-11.495-18.663 47.996-20.645 93.646-5.979 136.984-36.665 42.678-54.998 92.986-54.998 150.99 0 62.002 18.663 114.689 55.99 157.994 37.326 43.339 94.67 72.01 171.998 86.016a142.303 142.303 0 0 0-39.969 70.029c-56.683 13.972-96.355 3.963-119.015-30.06-42.017-61.308-79.674-83.307-113.003-65.965-4.69 4.657-3.997 9.48 1.982 14.501 6.012 4.988 14.996 11.66 27.02 19.985 11.99 8.357 20.976 17.507 26.987 27.515 0.661 1.322 2.51 6.177 5.517 14.502a831.917 831.917 0 0 0 8.985 23.981c2.973 7.663 8.654 16.186 17.011 25.5 8.324 9.349 18.003 17.178 29.003 23.52 11 6.309 26.161 11 45.485 14.006 19.324 2.972 41.323 3.138 65.998 0.495v100.484c0 0.991-0.165 2.643-0.495 5.021-0.33 2.312-0.991 3.964-1.982 4.955-0.991 1.024-2.345 2.015-4.03 3.039a12.52 12.52 0 0 1-6.474 1.486c-2.676 0-6.012-0.33-10.009-0.99-101.343-35.345-183.825-97.182-247.51-185.51C31.842 731.037 0 631.577 0 520.92z" /></svg>
|
After Width: | Height: | Size: 2.1 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 1024C229.234 1024 0 794.766 0 512S229.234 0 512 0s512 229.234 512 512-229.234 512-512 512z m259.157-568.889l-290.759 0.014c-13.966 0-25.287 11.321-25.287 25.273l-0.028 63.218c0 13.966 11.306 25.287 25.273 25.287H657.38c13.966 0 25.287 11.307 25.287 25.273v12.644a75.847 75.847 0 0 1-75.847 75.847H366.606a25.287 25.287 0 0 1-25.287-25.273v-240.2a75.847 75.847 0 0 1 75.847-75.846l353.92-0.015c13.966 0 25.273-11.306 25.287-25.273l0.071-63.189c0-13.966-11.306-25.287-25.272-25.301l-353.992 0.014c-104.718-0.014-189.624 84.892-189.624 189.61v353.963c0 13.967 11.32 25.287 25.287 25.287h372.935c94.265 0 170.666-76.401 170.666-170.666v-145.38c0-13.952-11.32-25.273-25.287-25.273z" fill="#d81e06" /></svg>
|
After Width: | Height: | Size: 973 B |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 0C229.2224 0 0 229.21728 0 512s229.2224 512 512 512 512-229.21728 512-512S794.7776 0 512 0z m281.89696 671.57504c-13.22496 12.34432-35.92192-1.10592-57.74336-31.29856a330.44992 330.44992 0 0 1-36.1472 70.30784c30.85312 11.01824 50.69312 28.2112 50.69312 47.61088 0 33.50016-59.2896 60.61056-132.45952 60.61056-43.4176 0-81.77152-9.47712-106.01472-24.2432-24.02304 14.76608-62.592 24.2432-106.01472 24.2432-73.17504 0-132.45952-27.1104-132.45952-60.61056 0-19.1744 19.83488-36.58752 50.69312-47.61088-14.54592-21.16096-26.66496-44.74368-36.14208-70.30784-21.82144 29.97248-44.52352 43.63776-57.74336 31.29856-18.0736-16.9728-11.24352-76.92288 15.64672-133.7856 6.1696-13.0048 12.78464-24.68352 19.61472-34.82112 3.74784-165.30432 112.62976-297.98912 246.19008-297.98912h0.44032c133.56544 0 242.44736 132.45952 246.19008 297.98912 6.8352 10.1376 13.44 21.82144 19.61472 34.82112 26.65984 56.86272 33.7152 116.8128 15.6416 133.7856z" fill="#8a8a8a" /></svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 0C229.2224 0 0 229.21728 0 512s229.2224 512 512 512 512-229.21728 512-512S794.7776 0 512 0z m281.89696 671.57504c-13.22496 12.34432-35.92192-1.10592-57.74336-31.29856a330.44992 330.44992 0 0 1-36.1472 70.30784c30.85312 11.01824 50.69312 28.2112 50.69312 47.61088 0 33.50016-59.2896 60.61056-132.45952 60.61056-43.4176 0-81.77152-9.47712-106.01472-24.2432-24.02304 14.76608-62.592 24.2432-106.01472 24.2432-73.17504 0-132.45952-27.1104-132.45952-60.61056 0-19.1744 19.83488-36.58752 50.69312-47.61088-14.54592-21.16096-26.66496-44.74368-36.14208-70.30784-21.82144 29.97248-44.52352 43.63776-57.74336 31.29856-18.0736-16.9728-11.24352-76.92288 15.64672-133.7856 6.1696-13.0048 12.78464-24.68352 19.61472-34.82112 3.74784-165.30432 112.62976-297.98912 246.19008-297.98912h0.44032c133.56544 0 242.44736 132.45952 246.19008 297.98912 6.8352 10.1376 13.44 21.82144 19.61472 34.82112 26.65984 56.86272 33.7152 116.8128 15.6416 133.7856z" fill="#1296db" /></svg>
|
After Width: | Height: | Size: 1.2 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M512 1024C229.2224 1024 0 794.7776 0 512S229.2224 0 512 0s512 229.2224 512 512-229.2224 512-512 512z m-51.2-245.76c175.3088 0 316.0832-91.6992 316.0832-204.8 0-95.5648-119.68-95.5648-119.68-101.7344 0-6.144 59.5968-61.6704 0-96.2048s-168.576 17.9712-165.2992 12.3392c46.8736-80.64-20.1216-106.0864-54.272-106.0864-81.408 0-294.272 178.5856-294.272 291.6864s142.1312 204.8 317.44 204.8z m24.832-35.5328c-112.0256 15.744-211.1232-30.5152-221.3376-103.3216s72.2688-144.5888 184.2688-160.3328c112-15.744 211.0976 30.5152 221.3376 103.3216s-72.2688 144.5888-184.2688 160.3328z m-19.968-25.472c66.6112-12.9536 111.872-68.4544 101.0944-123.9552-10.8032-55.5264-73.5488-90.0352-140.16-77.056-66.6368 12.928-111.872 68.4288-101.0944 123.9296 10.8032 55.5264 73.5488 90.0352 140.16 77.0816zM450.56 593.92a20.48 20.48 0 1 1 0-40.96 20.48 20.48 0 0 1 0 40.96z m-38.0672 61.1584c-20.5056 9.5488-42.9568 4.8384-50.1248-10.5472-7.168-15.36 3.6352-35.584 24.1408-45.1328 20.5056-9.5744 42.9312-4.864 50.1248 10.496 7.168 15.4112-3.6608 35.6096-24.1408 45.184zM734.9248 326.144c-36.992-33.28-74.8032-21.888-74.8032-21.888a29.312 29.312 0 0 0-25.2416 28.3648v-15.872c0 14.08 11.4432 24.7552 25.7536 24.96 0 0 29.8752-5.6832 49.6128 17.7408 19.7376 23.4496 6.656 50.816 6.656 50.816-3.6608 13.4912 4.7104 24.448 18.9696 24.448h-8.064c14.1568 0 27.776-11.2384 29.4912-25.088 0 0 14.6432-50.176-22.3744-83.456z m69.0944-66.6112c-67.84-64.1536-151.3472-54.5792-151.3472-54.5792A38.272 38.272 0 0 0 614.4 243.4048V220.928c0 21.3248 16.9472 37.888 38.4256 38.2208 0 0 79.616-10.368 120.3456 48.0512s24.576 115.2 24.576 115.2c-2.6624 21.12 12.3392 38.2208 33.4592 38.2208h-22.2976c21.1456 0 40.5248-16.896 42.1888-38.4 0 0 20.7616-98.5344-47.104-162.688z" fill="#FF5222" /></svg>
|
After Width: | Height: | Size: 2.0 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="199.80px" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M504.5 417.262c14.997 0 24.939-10.008 24.939-24.944 0-14.99-9.93-24.863-24.94-24.863-14.94 0-29.93 9.862-29.93 24.863 0.003 14.936 14.994 24.944 29.93 24.944zM569.296 511.982c-9.927 0-19.941 10.007-19.941 19.949 0 10.069 10.018 19.923 19.941 19.923 15.078 0 24.944-9.854 24.944-19.923 0-9.942-9.87-19.95-24.944-19.95zM365.032 367.455c-14.928 0-30.006 9.862-30.006 24.863 0 14.936 15.078 24.944 30.006 24.944s24.871-10.008 24.882-24.944c0-14.99-9.953-24.863-24.882-24.863zM678.916 511.982c-9.858 0-19.8 10.007-19.8 19.949 0 10.069 9.942 19.923 19.8 19.923 14.93 0 24.943-9.854 24.943-19.923 0-9.942-10.018-19.95-24.943-19.95z" fill="#8a8a8a" /><path d="M512 0C229.232 0 0 229.232 0 512.004 0 794.77 229.232 1024 512 1024c282.771 0 512.007-229.229 512.007-511.996C1024.007 229.232 794.771 0 512 0z m-82.258 621.685c-24.87 0-44.863-5.063-69.799-10.014l-69.66 34.954 19.93-59.959c-49.864-34.809-79.726-79.733-79.726-134.469 0-94.807 89.73-169.48 199.277-169.48 97.987 0 183.813 59.653 201.056 139.932-6.352-0.702-12.74-1.179-19.193-1.179-94.658 0-169.43 70.658-169.43 157.666 0 14.474 2.263 28.42 6.148 41.756-6.144 0.488-12.353 0.793-18.603 0.793z m293.975 69.792l14.991 49.806-54.666-29.93c-19.938 5.005-39.942 9.996-59.788 9.996-94.812 0-169.492-64.8-169.492-144.6 0-79.62 74.677-144.555 169.492-144.555 89.536 0 169.258 64.939 169.258 144.556 0.004 44.946-29.803 84.738-69.795 114.727z" fill="#8a8a8a" /></svg>
|
After Width: | Height: | Size: 1.6 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="199.80px" viewBox="0 0 1025 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M511.489531 513.531406m-510.468594 0a510.468594 510.468594 0 1 0 1020.937189 0 510.468594 510.468594 0 1 0-1020.937189 0Z" fill="#26A92E" /><path d="M629.407777 406.333001c7.657029 0 15.314058 0.510469 22.971086 1.531406-20.418744-94.947159-122.001994-165.902293-238.388833-165.902293-129.659023 0-235.836491 88.311067-235.836491 200.614157 0 64.829511 35.222333 117.918245 94.43669 159.266202l-23.481555 70.955134 82.695912-41.347956c29.607178 5.615155 53.088734 11.740778 82.695913 11.740778 7.657029 0 14.803589-0.510469 21.950149-1.020937-4.594217-15.824526-7.14656-32.159521-7.14656-49.515454-0.510469-102.604187 88.311067-186.321037 200.103689-186.321037zM502.811565 342.524427c17.866401 0 29.607178 11.740778 29.607179 29.607178s-11.740778 29.607178-29.607179 29.607179-35.222333-11.740778-35.222333-29.607179c-0.510469-18.376869 17.355932-29.607178 35.222333-29.607178zM337.419741 401.228315c-17.866401 0-35.732802-11.740778-35.732802-29.607178s17.866401-29.607178 35.732802-29.607179 29.607178 11.740778 29.607178 29.607179-11.740778 29.607178-29.607178 29.607178z m507.405782 188.87338c0-94.43669-94.43669-171.006979-200.614157-171.006979-112.303091 0-200.614158 77.080758-200.614158 171.006979 0 94.43669 88.311067 171.006979 200.614158 171.006979 23.481555 0 47.473579-6.125623 70.955134-11.740778l64.829512 35.732802-17.866401-59.214357c47.473579-35.222333 82.695912-82.185444 82.695912-135.784646z m-265.443669-29.607179c-11.740778 0-23.481555-11.740778-23.481555-23.481555s11.740778-23.481555 23.481555-23.481555c17.866401 0 29.607178 11.740778 29.607179 23.481555 0 12.251246-11.740778 23.481555-29.607179 23.481555z m129.659023 0c-11.740778 0-23.481555-11.740778-23.481555-23.481555s11.740778-23.481555 23.481555-23.481555c17.866401 0 29.607178 11.740778 29.607179 23.481555 0 12.251246-11.740778 23.481555-29.607179 23.481555z" fill="#FFFFFF" /></svg>
|
After Width: | Height: | Size: 2.1 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M233.296349 578.657268a76.433787 76.433787 0 0 0-28.66267 41.783804 86.582495 86.582495 0 0 0 22.632894 79.278822 150.489633 150.489633 0 0 0 91.126059 38.556599 241.785545 241.785545 0 0 0 146.795333-50.573689 324.079255 324.079255 0 0 0 70.064305-69.384893 432.487843 432.487843 0 0 0-211.721589-60.934713 209.08887 209.08887 0 0 0-90.234332 21.27407zM982.559774 713.647828a511.936517 511.936517 0 1 0-56.391149 99.278996 56591.023592 56591.023592 0 0 0-320.809588-158.51518 395.247603 395.247603 0 0 1-176.010025 117.920347 253.335539 253.335539 0 0 1-126.582843 9.724076 167.942014 167.942014 0 0 1-89.979552-47.431411 170.235028 170.235028 0 0 1-27.049068-37.962114l1.18897 3.014889a91.041133 91.041133 0 0 1-7.685842-19.40569 87.134517 87.134517 0 0 1-3.312131-18.046866 94.820359 94.820359 0 0 1 0-12.993744 94.3108 94.3108 0 0 1 1.656066-23.949253A122.378985 122.378985 0 0 1 212.489374 560.100844 204.290526 204.290526 0 0 1 360.558604 509.824397a781.535468 781.535468 0 0 1 210.787398 48.153286 751.981071 751.981071 0 0 0 41.783804-120.510604h-305.310515v-32.866528h156.774189V338.612715H274.952763V305.576334h189.640717V239.588498c0-9.044665 1.783455-16.475727 16.518191-16.475727h74.268163V305.576334h206.286297v33.036381h-206.286297v65.987836h165.012052a648.243437 648.243437 0 0 1-68.365776 183.441088c114.990386 41.104392 276.775234 104.374582 330.533664 125.606189z" fill="#8a8a8a" /></svg>
|
After Width: | Height: | Size: 1.6 KiB |
|
@ -0,0 +1 @@
|
|||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M211.03874656 682.3954475a101.7592875 101.7592875 0 0 1 83.03941875-104.63926781c104.63926781-17.27987906 248.63826 69.5995125 248.63826 69.5995125a312.47781281 312.47781281 0 0 1-226.55841469 126.71911312c-60.95957344-4.31997-104.63926781-39.35972437-104.63926687-91.67935781z m741.59480906 35.03975438c-12.95990906-4.31997-309.5978325-95.99932781-300.95789343-104.63926782a573.11598844 573.11598844 0 0 0 73.9194825-174.71877656v-26.39981531h-174.71877657V346.39779875h213.59850469v-39.35972437h-213.59850469v-95.99932782H463.99697562v91.67935875H271.99832v39.35972438h191.99865562v65.2795425H311.35804437v26.39981531h313.9178025a536.63624344 536.63624344 0 0 1-43.67969437 139.67902219A709.43503406 709.43503406 0 0 0 358.87771156 511.99664c-83.03941875 4.31997-148.31896219 30.71978531-179.03874656 91.67935781-43.67969437 113.27920687 26.39981531 227.03841094 183.35871656 227.03841094a331.19768156 331.19768156 0 0 0 248.63826-143.99899219c26.39981531 12.95990906 174.23878031 87.35938875 265.91813813 135.35905313A473.27668687 473.27668687 0 0 1 511.99664 991.99328a479.99664 479.99664 0 1 1 479.99664-479.99664 442.5569025 442.5569025 0 0 1-39.35972437 204.95856563z m0 0" fill="#19A0E5" /></svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -26,10 +26,10 @@
|
|||
});
|
||||
},
|
||||
capWidth: function () {
|
||||
return $(window).width() < 768 ? 216 : 280;
|
||||
return $(window).width() < 768 ? 256 : 280;
|
||||
},
|
||||
capHeight: function () {
|
||||
return $(window).width() < 768 ? 110 : 150;
|
||||
return $(window).width() < 768 ? 106 : 150;
|
||||
},
|
||||
capRegSuccess: function () {
|
||||
$.bc({
|
||||
|
@ -116,4 +116,16 @@
|
|||
}
|
||||
}
|
||||
});
|
||||
|
||||
// use Gitee authentication when SystemDemoModel
|
||||
var $login = $('#login');
|
||||
if ($login.attr('data-demo') === 'True') {
|
||||
$login.find('[data-valid="true"]').attr('data-valid', 'false');
|
||||
$login.on('submit', function (e) {
|
||||
if ($('[name="userName"]').val() === '' && $('[name="password"]').val() === '') {
|
||||
location.href = "Gitee";
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
|
@ -4,6 +4,7 @@ using MongoDB.Driver;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Principal;
|
||||
|
||||
namespace Bootstrap.DataAccess.MongoDB
|
||||
{
|
||||
|
@ -104,7 +105,7 @@ namespace Bootstrap.DataAccess.MongoDB
|
|||
public override bool Save(DataAccess.User user)
|
||||
{
|
||||
// 已经存在或者已经在新用户中了
|
||||
if (UserHelper.RetrieveUserByUserName(user.UserName) != null || UserHelper.RetrieveNewUsers().Any(u => u.UserName == user.UserName)) return false;
|
||||
if (UserHelper.RetrieveUserByUserName(new GenericIdentity(user.UserName)) != null || UserHelper.RetrieveNewUsers().Any(u => u.UserName == user.UserName)) return false;
|
||||
|
||||
DbManager.Users.InsertOne(new User()
|
||||
{
|
||||
|
|
|
@ -6,12 +6,14 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Bootstrap.Security.DataAccess" Version="2.2.21" />
|
||||
<PackageReference Include="Longbow.Configuration" Version="2.2.7" />
|
||||
<PackageReference Include="Longbow.Data" Version="2.3.7" />
|
||||
<PackageReference Include="Longbow.GiteeAuth" Version="2.2.0" />
|
||||
<PackageReference Include="Longbow.GitHubAuth" Version="2.2.0" />
|
||||
<PackageReference Include="Longbow.Logging" Version="2.2.13" />
|
||||
<PackageReference Include="Longbow.PetaPoco" Version="1.0.2" />
|
||||
<PackageReference Include="Longbow.Security.Cryptography" Version="1.3.0" />
|
||||
<PackageReference Include="Longbow.Web" Version="2.2.16" />
|
||||
<PackageReference Include="Longbow.Cache" Version="2.2.15" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="2.2.6" />
|
||||
<PackageReference Include="PetaPoco.Extensions" Version="1.0.9" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -48,9 +48,14 @@ namespace Bootstrap.DataAccess
|
|||
cacheKeys.Add(MenuHelper.RetrieveMenusAll + "*");
|
||||
});
|
||||
cacheKeys.Add(UserHelper.RetrieveNewUsersDataKey + "*");
|
||||
cacheKeys.Add(UserHelper.RetrieveUsersDataKey + "*");
|
||||
corsKeys.Add(UserHelper.RetrieveUsersDataKey + "*");
|
||||
corsKeys.Add(MenuHelper.RetrieveMenusAll + "*");
|
||||
cacheKeys.Add(UserHelper.RetrieveUsersDataKey);
|
||||
cacheKeys.Add(GroupHelper.RetrieveGroupsByUserNameDataKey + "*");
|
||||
cacheKeys.Add(RoleHelper.RetrieveRolesDataKey + "*");
|
||||
cacheKeys.Add(AppHelper.RetrieveAppsByUserNameDataKey + "*");
|
||||
corsKeys.Add(UserHelper.RetrieveUsersDataKey);
|
||||
corsKeys.Add(GroupHelper.RetrieveGroupsByUserNameDataKey + "*");
|
||||
corsKeys.Add(RoleHelper.RetrieveRolesDataKey + "*");
|
||||
corsKeys.Add(AppHelper.RetrieveAppsByUserNameDataKey + "*");
|
||||
}
|
||||
if (groupIds != null)
|
||||
{
|
||||
|
|
|
@ -5,15 +5,19 @@ using System.Collections.Generic;
|
|||
namespace Bootstrap.DataAccess
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// 前台应用帮助类
|
||||
/// </summary>
|
||||
public static class AppHelper
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// 通过角色 ID 获得授权前台应用数据缓存键值
|
||||
/// </summary>
|
||||
public const string RetrieveAppsByRoleIdDataKey = "AppHelper-RetrieveAppsByRoleId";
|
||||
|
||||
/// <summary>
|
||||
/// 通过用户名称获得授权前台应用数据缓存键值
|
||||
/// </summary>
|
||||
public const string RetrieveAppsByUserNameDataKey = DbHelper.RetrieveAppsByUserNameDataKey;
|
||||
/// <summary>
|
||||
/// 根据角色ID指派应用程序
|
||||
/// </summary>
|
||||
|
@ -39,6 +43,6 @@ namespace Bootstrap.DataAccess
|
|||
/// </summary>
|
||||
/// <param name="userName"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<string> RetrievesByUserName(string userName) => CacheManager.GetOrAdd($"{DbHelper.RetrieveAppsByUserNameDataKey}-{userName}", key => DbContextManager.Create<App>().RetrievesByUserName(userName), DbHelper.RetrieveAppsByUserNameDataKey);
|
||||
public static IEnumerable<string> RetrievesByUserName(string userName) => CacheManager.GetOrAdd($"{DbHelper.RetrieveAppsByUserNameDataKey}-{userName}", key => DbContextManager.Create<App>().RetrievesByUserName(userName), RetrieveAppsByUserNameDataKey);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
using Bootstrap.Security;
|
||||
using Longbow.Configuration;
|
||||
using Longbow.OAuth;
|
||||
using Longbow.Security.Cryptography;
|
||||
using Microsoft.AspNetCore.WebUtilities;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
|
||||
namespace Bootstrap.DataAccess
|
||||
{
|
||||
/// <summary>
|
||||
/// Gitee 授权帮助类
|
||||
/// </summary>
|
||||
public static class OAuthHelper
|
||||
{
|
||||
private static readonly ConcurrentDictionary<string, OAuthUser> _pool = new ConcurrentDictionary<string, OAuthUser>();
|
||||
|
||||
/// <summary>
|
||||
/// 设置 GiteeOptions.Events.OnCreatingTicket 方法
|
||||
/// </summary>
|
||||
/// <param name="option"></param>
|
||||
public static void Configure<TOptions>(TOptions option) where TOptions : LgbOAuthOptions
|
||||
{
|
||||
option.Events.OnCreatingTicket = async context =>
|
||||
{
|
||||
var user = context.User.ToObject<OAuthUser>();
|
||||
user.Schema = context.Scheme.Name;
|
||||
_pool.AddOrUpdate(user.Login, userName => user, (userName, u) => { u = user; return user; });
|
||||
|
||||
// call webhook
|
||||
var config = context.HttpContext.RequestServices.GetRequiredService<IConfiguration>();
|
||||
var webhookUrl = config.GetValue($"{option.GetType().Name}:StarredUrl", "");
|
||||
if (!string.IsNullOrEmpty(webhookUrl))
|
||||
{
|
||||
var webhookParameters = new Dictionary<string, string>()
|
||||
{
|
||||
{ "access_token", context.AccessToken }
|
||||
};
|
||||
var url = QueryHelpers.AddQueryString(webhookUrl, webhookParameters);
|
||||
var requestMessage = new HttpRequestMessage(HttpMethod.Put, url);
|
||||
requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
await context.Backchannel.SendAsync(requestMessage, context.HttpContext.RequestAborted);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 插入 Gitee 授权用户到数据库中
|
||||
/// </summary>
|
||||
/// <param name="userName"></param>
|
||||
/// <returns></returns>
|
||||
public static BootstrapUser RetrieveUserByUserName<TOptions>(string userName) where TOptions : LgbOAuthOptions
|
||||
{
|
||||
User ret = null;
|
||||
var user = _pool.TryGetValue(userName, out var giteeUser) ? giteeUser : null;
|
||||
if (user != null)
|
||||
{
|
||||
var option = ConfigurationManager.Get<TOptions>();
|
||||
ret = new User()
|
||||
{
|
||||
ApprovedBy = "OAuth",
|
||||
ApprovedTime = DateTime.Now,
|
||||
DisplayName = user.Name,
|
||||
UserName = user.Login,
|
||||
Password = LgbCryptography.GenerateSalt(),
|
||||
Icon = user.Avatar_Url,
|
||||
Description = $"{user.Schema}({user.Id})",
|
||||
App = option.App
|
||||
};
|
||||
DbContextManager.Create<User>().Save(ret);
|
||||
CacheCleanUtility.ClearCache(cacheKey: UserHelper.RetrieveUsersDataKey);
|
||||
|
||||
// 根据配置文件设置默认角色
|
||||
var usr = UserHelper.Retrieves().First(u => u.UserName == userName);
|
||||
var roles = RoleHelper.Retrieves().Where(r => option.Roles.Any(rl => rl.Equals(r.RoleName, StringComparison.OrdinalIgnoreCase))).Select(r => r.Id);
|
||||
RoleHelper.SaveByUserId(usr.Id, roles);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ namespace Bootstrap.DataAccess
|
|||
{
|
||||
if (context.User.Identity.IsAuthenticated)
|
||||
{
|
||||
var user = UserHelper.RetrieveUserByUserName(context.User.Identity.Name);
|
||||
var user = UserHelper.RetrieveUserByUserName(context.User.Identity);
|
||||
|
||||
// user == null 以前登录过客户端保留了 Cookie 但是用户名可能被系统删除
|
||||
// link bug: https://gitee.com/LongbowEnterprise/BootstrapAdmin/issues/I123MH
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
using Bootstrap.Security;
|
||||
using Bootstrap.Security.DataAccess;
|
||||
using Longbow.Cache;
|
||||
using Longbow.GiteeAuth;
|
||||
using Longbow.GitHubAuth;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Principal;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace Bootstrap.DataAccess
|
||||
|
@ -95,7 +98,7 @@ namespace Bootstrap.DataAccess
|
|||
value = value.Where(v => !admins.Any(u => u.Id == v));
|
||||
if (!value.Any()) return true;
|
||||
var ret = DbContextManager.Create<User>().Delete(value);
|
||||
if (ret) CacheCleanUtility.ClearCache(userIds: value);
|
||||
if (ret) CacheCleanUtility.ClearCache(userIds: value, cacheKey: RetrieveUsersByNameDataKey + "*");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -307,9 +310,30 @@ namespace Bootstrap.DataAccess
|
|||
/// <summary>
|
||||
/// 通过登录名获取登录用户方法
|
||||
/// </summary>
|
||||
/// <param name="userName"></param>
|
||||
/// <param name="identity"></param>
|
||||
/// <returns></returns>
|
||||
public static BootstrapUser RetrieveUserByUserName(string userName) => CacheManager.GetOrAdd(string.Format("{0}-{1}", RetrieveUsersByNameDataKey, userName), k => DbContextManager.Create<User>()?.RetrieveUserByUserName(userName), RetrieveUsersByNameDataKey);
|
||||
public static BootstrapUser RetrieveUserByUserName(IIdentity identity) => CacheManager.GetOrAdd(string.Format("{0}-{1}", RetrieveUsersByNameDataKey, identity.Name), k =>
|
||||
{
|
||||
var userName = identity.Name;
|
||||
var proxyList = new List<Func<string, BootstrapUser>>();
|
||||
|
||||
// 本地数据库认证
|
||||
proxyList.Add(DbContextManager.Create<User>().RetrieveUserByUserName);
|
||||
|
||||
// Gitee 认证
|
||||
if (identity.AuthenticationType == GiteeDefaults.AuthenticationScheme) proxyList.Add(OAuthHelper.RetrieveUserByUserName<GiteeOptions>);
|
||||
|
||||
// GitHub 认证
|
||||
if (identity.AuthenticationType == GitHubDefaults.AuthenticationScheme) proxyList.Add(OAuthHelper.RetrieveUserByUserName<GitHubOptions>);
|
||||
|
||||
BootstrapUser user = null;
|
||||
foreach (var p in proxyList)
|
||||
{
|
||||
user = p.Invoke(userName);
|
||||
if (user != null) break;
|
||||
}
|
||||
return user;
|
||||
}, RetrieveUsersByNameDataKey);
|
||||
|
||||
/// <summary>
|
||||
/// 通过登录账号获得用户信息
|
||||
|
|
|
@ -204,12 +204,12 @@ namespace Bootstrap.DataAccess
|
|||
/// <returns></returns>
|
||||
public virtual bool Save(User user)
|
||||
{
|
||||
var ret = false;
|
||||
user.PassSalt = LgbCryptography.GenerateSalt();
|
||||
user.Password = LgbCryptography.ComputeHash(user.Password, user.PassSalt);
|
||||
user.RegisterTime = DateTime.Now;
|
||||
|
||||
var db = DbManager.Create();
|
||||
bool ret;
|
||||
try
|
||||
{
|
||||
db.BeginTransaction();
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Bootstrap.Security.Mvc" Version="2.2.16" />
|
||||
<PackageReference Include="Bootstrap.Security.Mvc" Version="2.2.17" />
|
||||
<PackageReference Include="Longbow.Configuration" Version="2.2.7" />
|
||||
<PackageReference Include="Longbow.Logging" Version="2.2.13" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.App" />
|
||||
|
|
|
@ -33,7 +33,7 @@ namespace Bootstrap.Client.Models
|
|||
|
||||
// set Icon
|
||||
var icon = $"/{DictHelper.RetrieveIconFolderPath().Trim('~', '/')}/{user.Icon}";
|
||||
Icon = string.IsNullOrEmpty(ConfigurationManager.GetValue("SimulateUserName", string.Empty)) ? $"{authHost.TrimEnd('/')}{icon}" : "/images/admin.jpg";
|
||||
Icon = user.Icon.Contains("://", StringComparison.OrdinalIgnoreCase) ? user.Icon : (string.IsNullOrEmpty(ConfigurationManager.GetValue("SimulateUserName", string.Empty)) ? $"{authHost.TrimEnd('/')}{icon}" : "/images/admin.jpg");
|
||||
if (!string.IsNullOrEmpty(user.Css)) Theme = user.Css;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
using Bootstrap.Client.DataAccess;
|
||||
using Longbow.Configuration;
|
||||
using Longbow.Web;
|
||||
using Longbow.Web.SignalR;
|
||||
using Microsoft.AspNetCore;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
|
@ -13,7 +11,6 @@ using Microsoft.Extensions.DependencyInjection;
|
|||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Bootstrap.Client
|
||||
{
|
||||
|
|
|
@ -10,8 +10,14 @@
|
|||
<script src="~/js/index.js"></script>
|
||||
}
|
||||
<p>这是开源后台管理框架前台系统首页,欢迎使用</p>
|
||||
<p>点击右上角登录信息下拉菜单中的设置按钮进入 <b>后台管理</b> 或者 <b><a href="@Model.SettingsUrl">直接进入</a></b></p>
|
||||
<p class="text-danger"><b>由于本系统为演示系统,内部对一些敏感操作进行了限制操作,如一些特殊用户不能删除</b></p>
|
||||
<p>点击右上角进入 <b>后台管理</b> 或者 <b><a href="@Model.SettingsUrl">直接进入</a></b></p>
|
||||
<p>系统密码</p>
|
||||
<p>
|
||||
<ol>
|
||||
<li>管理账号 Admin/123789</li>
|
||||
<li>普通账号 User/123789</li>
|
||||
</ol>
|
||||
</p>
|
||||
<p>最新功能更新请查看 <b><a href="https://gitee.com/LongbowEnterprise/BootstrapAdmin/wikis/%E6%9B%B4%E6%96%B0%E6%97%A5%E5%BF%97?sort_id=1585945">更新日志</a></b></p>
|
||||
<p>
|
||||
<button id="btnCaptcha" class="btn btn-success ml-2 ml-md-0"><i class="fa fa-send-o"></i><span>点击我出现行为验证码</span></button>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@model ModelBase
|
||||
<footer class="position-fixed">
|
||||
<div><span id="websiteFooter">@Model.Footer</span></div>
|
||||
<div><span id="websiteFooter">@Model.Footer (演示系统)</span></div>
|
||||
<a id="gotoTop" href="#" class="go-top" title="返回顶部" data-toggle="tooltip" data-placement="left">
|
||||
<i class="fa fa-angle-up"></i>
|
||||
</a>
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using Longbow.Web.Mvc;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Security.Principal;
|
||||
using Xunit;
|
||||
|
||||
namespace Bootstrap.DataAccess.SqlServer
|
||||
|
@ -134,7 +135,7 @@ namespace Bootstrap.DataAccess.SqlServer
|
|||
[Fact]
|
||||
public void RetrieveUserByUserName_Ok()
|
||||
{
|
||||
var usr = UserHelper.RetrieveUserByUserName("Admin");
|
||||
var usr = UserHelper.RetrieveUserByUserName(new GenericIdentity("Admin"));
|
||||
Assert.Equal("Administrator", usr.DisplayName);
|
||||
}
|
||||
|
||||
|
|