using System.Web;
using JNPF.Common.Const;
using JNPF.Common.Core.Manager;
using JNPF.Common.Enums;
using JNPF.Common.Manager;
using JNPF.Common.Models.User;
using JNPF.Common.Options;
using JNPF.Common.Security;
using JNPF.DependencyInjection;
using JNPF.DynamicApiController;
using JNPF.Extras.CollectiveOAuth.Cache;
using JNPF.Extras.CollectiveOAuth.Config;
using JNPF.Extras.CollectiveOAuth.Enums;
using JNPF.Extras.CollectiveOAuth.Models;
using JNPF.Extras.CollectiveOAuth.Request;
using JNPF.Extras.CollectiveOAuth.Utils;
using JNPF.FriendlyException;
using JNPF.Logging.Attributes;
using JNPF.RemoteRequest.Extensions;
using JNPF.Systems.Entitys.Dto.Socials;
using JNPF.Systems.Entitys.Model.Permission.SocialsUser;
using JNPF.Systems.Entitys.Permission;
using JNPF.Systems.Interfaces.Permission;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
using SqlSugar;
namespace JNPF.Systems;
///
/// 业务实现:第三方登录.
///
[ApiDescriptionSettings(Tag = "Permission", Name = "Socials", Order = 168)]
[Route("api/permission/[controller]")]
public class SocialsUserService : ISocialsUserService, IDynamicApiController, ITransient
{
///
/// 配置文档.
///
private readonly SocialsOptions _socialsOptions = App.GetConfig("Socials", true);
///
/// 基础仓储.
///
private readonly ISqlSugarRepository _repository;
///
/// 操作权限服务.
///
private readonly IAuthorizeService _authorizeService;
///
/// 缓存管理器.
///
private readonly ICacheManager _cacheManager;
///
/// 用户管理.
///
private readonly IUserManager _userManager;
///
/// 多租户配置选项.
///
private readonly TenantOptions _tenant;
///
/// 初始化.
///
public SocialsUserService(
ISqlSugarRepository userRepository,
IAuthorizeService authorizeService,
ICacheManager cacheManager,
IOptions tenantOptions,
IUserManager userManager)
{
_tenant = tenantOptions.Value;
_repository = userRepository;
_authorizeService = authorizeService;
_cacheManager = cacheManager;
_userManager = userManager;
}
#region GET
///
/// 获取用户授权列表.
///
///
///
[HttpGet("")]
public async Task GetList(string userId)
{
if (userId.IsNullOrWhiteSpace()) userId = _userManager.UserId;
if (_socialsOptions.Config == null || !_socialsOptions.Config.Any())
throw Oops.Oh(ErrorCode.D5025);
var res = new List();
var platformInfos = GetPlatFormInfos();
_socialsOptions.Config.ForEach(item =>
{
platformInfos.ForEach(it =>
{
if (it["enname"].ToString().ToLower().Equals(item.Provider))
res.Add(it.Adapt());
});
});
// 查询绑定信息
var data = await _repository.AsQueryable().Where(x => x.UserId == userId && x.DeleteMark == null).ToListAsync();
res.ForEach(item =>
{
data.ForEach(it =>
{
if (item.enname.Equals(it.SocialType.ToLower())) item.entity = it.Adapt();
});
});
return res;
}
///
/// 重定向第三方登录页面.
///
///
///
[HttpGet("Render/{source}")]
[IgnoreLog]
[NonUnify]
public async Task Render(string source)
{
var authRequest = GetAuthRequest(source, _userManager.UserId, false, null, _userManager.TenantId);
var res = authRequest.authorize(AuthStateUtils.createState());
return new { code = 200, msg = res };
}
///
/// 获取当前用户信息.
///
///
///
[HttpGet("List")]
public List GetLoginList(string ticket)
{
if (!_socialsOptions.SocialsEnabled) return null;
var platformInfos = GetPlatFormInfos();
var res = new List();
_socialsOptions.Config.ForEach(item =>
{
platformInfos.ForEach(it =>
{
if (it["enname"].ToString().ToLower().Equals(item.Provider))
{
var itModel = it.Adapt();
var authRequest = GetAuthRequest(itModel.enname, null, true, ticket, null);
itModel.renderUrl = authRequest.authorize(AuthStateUtils.createState());
res.Add(itModel);
}
});
});
return res;
}
///
/// 绑定.
///
///
public async Task Binding([FromQuery] SocialsUserInputModel model)
{
var res = new AuthResponse(5001, string.Empty);
// 微信小程序唤醒登录.
if (!model.uuid.IsNullOrWhiteSpace())
{
AuthUser user = new AuthUser();
user.uuid = model.uuid;
user.source = model.source;
user.username = model.socialName;
res = new AuthResponse(2000, null, user);
}
else
{
// 获取第三方请求
AuthCallbackNew callback = SetAuthCallback(model.code, model.state);
// 获取第三方请求
var authRequest = GetAuthRequest(model.source, model.userId, false, null, null);
res = authRequest.login(callback);
}
if (res.ok())
{
var resData = res.data.ToObject();
var uuid = GetSocialUuid(res);
var socialsUserEntity = new SocialsUsersEntity();
socialsUserEntity.UserId = model.userId;
socialsUserEntity.SocialType = model.source;
socialsUserEntity.SocialName = resData.username;
socialsUserEntity.SocialId = uuid;
if (model.jnpf_ticket.IsNullOrEmpty())
{
var sInfo = await _repository.AsQueryable().Where(x => (x.SocialId.Equals(uuid) || x.UserId.Equals(model.userId)) && x.SocialType.Equals(model.source) && x.DeleteMark == null).FirstAsync();
if (sInfo != null)
{
UserEntity info = await _repository.AsSugarClient().Queryable().Where(x => x.Id.Equals(sInfo.UserId)).FirstAsync();
return new { code = 201, message = "当前账户已被" + info.RealName + "/" + info.Account + "绑定,不能重复绑定", msg = "当前账户已被" + info.RealName + "/" + info.Account + "绑定,不能重复绑定" }.ToJsonString();
}
var resCount = await _repository.AsSugarClient().Insertable(socialsUserEntity).CallEntityMethod(m => m.Creator()).ExecuteCommandAsync();
// 租户开启时-添加租户库绑定数据
if (_tenant.MultiTenancy && resCount > 0)
{
var info = await _repository.AsSugarClient().Queryable().FirstAsync(x => x.Id.Equals(model.userId));
var param = socialsUserEntity.ToObject>();
param.Add("tenantId", model.tenantId);
param.Add("account", info.Account);
param.Add("accountName", info.RealName + "/" + info.Account);
var postUrl = _tenant.MultiTenancyDBInterFace + "socials";
var result = (await postUrl.SetBody(param).PostAsStringAsync()).ToObject>();
if (result == null || "500".Equals(result["code"]) || "400".Equals(result["code"]))
{
return new { code = 201, message = "用户租户绑定错误!", msg = "用户租户绑定错误!" }.ToJsonString();
}
}
}
return new { code = 200, message = "绑定成功!", msg = "绑定成功!", data = socialsUserEntity }.ToJsonString();
}
return new { code = 201, message = "第三方回调失败!", msg = "第三方回调失败!" }.ToJsonString();
}
#endregion
#region Post
///
/// 解绑.
///
///
[HttpDelete("{id}")]
[IgnoreLog]
[NonUnify]
public async Task DeleteSocials(string id)
{
var oidList = _userManager.DataScope.Where(x => x.Edit).Select(x => x.organizeId).ToList();
var entity = await _repository.AsQueryable().FirstAsync(x => x.Id.Equals(id));
if (!_userManager.IsAdministrator && !_userManager.UserId.Equals(entity.UserId)
&& !_repository.AsSugarClient().Queryable().Any(x => oidList.Contains(x.ObjectId) && x.UserId.Equals(entity.UserId) && x.ObjectType.Equals("Organize")))
return new { code = 500, msg = "没有编辑权限,不能解绑" };
var res = await _repository.AsUpdateable(entity).CallEntityMethod(m => m.Delete()).UpdateColumns(it => new { it.DeleteMark, it.DeleteTime, it.DeleteUserId })
.Where(x => x.Id.Equals(id)).ExecuteCommandHasChangeAsync();
if (res)
{
// 多租户开启-解除绑定
if (_tenant.MultiTenancy)
{
var postUrl = string.Format(_tenant.MultiTenancyDBInterFace + "socials?userId={0}&tenantId={1}&socialsType={2}", entity.UserId, _userManager.TenantId, entity.SocialType);
var result = (await postUrl.DeleteAsStringAsync()).ToObject>();
if (result == null || "500".Equals(result["code"]) || "400".Equals(result["code"]))
return new { code = 500, msg = "多租户解绑失败" };
}
return new { code = 200, msg = "解绑成功" };
}
return new { code = 500, msg = "解绑失败" };
}
#endregion
///
/// 获取第三方登录相关基础信息.
///
///
public List> GetPlatFormInfos()
{
var list = new List>();
list.Add(new List