chore: 简化 AVUser 接口

oneRain 2019-08-22 11:52:26 +08:00
parent e68a13590a
commit 3786595bf1
3 changed files with 277 additions and 410 deletions

View File

@ -35,7 +35,7 @@ namespace LeanCloudTests {
[Test] [Test]
public async Task LoginWithEmail() { public async Task LoginWithEmail() {
AVUser user = await AVUser.LogInByEmailAsync("111111@qq.com", "111111"); AVUser user = await AVUser.LogInWithEmailAsync("111111@qq.com", "111111");
Assert.AreEqual(user, AVUser.CurrentUser); Assert.AreEqual(user, AVUser.CurrentUser);
TestContext.Out.WriteLine($"{AVUser.CurrentUser.SessionToken} login"); TestContext.Out.WriteLine($"{AVUser.CurrentUser.SessionToken} login");
} }
@ -49,7 +49,7 @@ namespace LeanCloudTests {
[Test] [Test]
public async Task IsAuthenticated() { public async Task IsAuthenticated() {
AVUser user = await AVUser.LogInByEmailAsync("111111@qq.com", "111111"); AVUser user = await AVUser.LogInWithEmailAsync("111111@qq.com", "111111");
Assert.IsTrue(user.IsCurrent); Assert.IsTrue(user.IsCurrent);
Assert.AreEqual(user, AVUser.CurrentUser); Assert.AreEqual(user, AVUser.CurrentUser);
bool authenticated = await user.IsAuthenticatedAsync(); bool authenticated = await user.IsAuthenticatedAsync();
@ -58,7 +58,7 @@ namespace LeanCloudTests {
[Test] [Test]
public async Task RefreshSessionToken() { public async Task RefreshSessionToken() {
AVUser user = await AVUser.LogInByEmailAsync("111111@qq.com", "111111"); AVUser user = await AVUser.LogInWithEmailAsync("111111@qq.com", "111111");
Assert.IsTrue(user.IsCurrent); Assert.IsTrue(user.IsCurrent);
await user.RefreshSessionTokenAsync(); await user.RefreshSessionTokenAsync();
TestContext.Out.WriteLine(user.SessionToken); TestContext.Out.WriteLine(user.SessionToken);

View File

@ -1,36 +0,0 @@
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace LeanCloud.Storage.Internal {
public interface IAVAuthenticationProvider {
/// <summary>
/// Authenticates with the service.
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
Task<IDictionary<string, object>> AuthenticateAsync(CancellationToken cancellationToken);
/// <summary>
/// Deauthenticates (logs out) the user associated with this provider. This
/// call may block.
/// </summary>
void Deauthenticate();
/// <summary>
/// Restores authentication that has been serialized, such as session keys,
/// etc.
/// </summary>
/// <param name="authData">The auth data for the provider. This value may be null
/// when unlinking an account.</param>
/// <returns><c>true</c> iff the authData was successfully synchronized. A <c>false</c> return
/// value indicates that the user should no longer be associated because of bad auth
/// data.</returns>
bool RestoreAuthentication(IDictionary<string, object> authData);
/// <summary>
/// Provides a unique name for the type of authentication the provider does.
/// For example, the FacebookAuthenticationProvider would return "facebook".
/// </summary>
string AuthType { get; }
}
}

View File

@ -11,9 +11,6 @@ namespace LeanCloud {
/// </summary> /// </summary>
[AVClassName("_User")] [AVClassName("_User")]
public class AVUser : AVObject { public class AVUser : AVObject {
private static readonly IDictionary<string, IAVAuthenticationProvider> authProviders =
new Dictionary<string, IAVAuthenticationProvider>();
internal static AVUserController UserController { internal static AVUserController UserController {
get { get {
return AVPlugins.Instance.UserController; return AVPlugins.Instance.UserController;
@ -21,52 +18,22 @@ namespace LeanCloud {
} }
/// <summary> /// <summary>
/// 判断是否是当前用户 /// 获取当前用户
/// </summary> /// </summary>
public bool IsCurrent { public static AVUser CurrentUser {
get;
internal set;
}
/// <summary>
/// 创建一个 AVUser 查询对象
/// </summary>
public static AVQuery<AVUser> Query {
get { get {
return CurrentUser == this; return new AVQuery<AVUser>();
} }
} }
/// <summary>
/// 判断当前用户的 Session Token 是否有效
/// </summary>
/// <returns></returns>
public async Task<bool> IsAuthenticatedAsync() {
lock (mutex) {
if (SessionToken == null || CurrentUser == null || CurrentUser.ObjectId != ObjectId) {
return false;
}
}
var command = new AVCommand {
Path = $"users/me?session_token={SessionToken}",
Method = HttpMethod.Get
};
await AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command);
return true;
}
/// <summary>
/// 刷新用户的 Session Token刷新后 Session Token 将会改变
/// </summary>
/// <returns></returns>
public async Task RefreshSessionTokenAsync() {
var serverState = await UserController.RefreshSessionTokenAsync(ObjectId);
HandleSave(serverState);
}
/// <summary>
/// 获取 Session Token
/// </summary>
public string SessionToken {
get {
if (State.ContainsKey("sessionToken")) {
return State["sessionToken"] as string;
}
return null;
}
}
/// <summary> /// <summary>
/// 用户名 /// 用户名
@ -134,6 +101,33 @@ namespace LeanCloud {
} }
} }
/// <summary>
/// 获取 Session Token
/// </summary>
public string SessionToken {
get {
if (State.ContainsKey("sessionToken")) {
return State["sessionToken"] as string;
}
return null;
}
}
/// <summary>
/// 用户数据
/// </summary>
internal IDictionary<string, IDictionary<string, object>> AuthData {
get {
if (TryGetValue("authData", out IDictionary<string, IDictionary<string, object>> authData)) {
return authData;
}
return null;
}
private set {
this["authData"] = value;
}
}
/// <summary> /// <summary>
/// 判断用户是否为匿名用户 /// 判断用户是否为匿名用户
/// </summary> /// </summary>
@ -143,6 +137,44 @@ namespace LeanCloud {
} }
} }
/// <summary>
/// 判断是否是当前用户
/// </summary>
public bool IsCurrent {
get {
return CurrentUser == this;
}
}
/// <summary>
/// 判断当前用户的 Session Token 是否有效
/// </summary>
/// <returns></returns>
public async Task<bool> IsAuthenticatedAsync() {
lock (mutex) {
if (SessionToken == null || CurrentUser == null || CurrentUser.ObjectId != ObjectId) {
return false;
}
}
var command = new AVCommand {
Path = $"users/me?session_token={SessionToken}",
Method = HttpMethod.Get
};
await AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command);
return true;
}
/// <summary>
/// 刷新用户的 Session Token刷新后 Session Token 将会改变
/// </summary>
/// <returns></returns>
public async Task RefreshSessionTokenAsync() {
var serverState = await UserController.RefreshSessionTokenAsync(ObjectId);
HandleSave(serverState);
}
#region 账号密码登陆
/// <summary> /// <summary>
/// 注册新用户,注册成功后将保存为当前用户。必须设置用户名和密码。 /// 注册新用户,注册成功后将保存为当前用户。必须设置用户名和密码。
/// </summary> /// </summary>
@ -170,99 +202,6 @@ namespace LeanCloud {
} }
} }
#region 事件流系统相关 API
/// <summary>
/// 关注某个用户
/// </summary>
/// <param name="userObjectId">被关注的用户</param>
/// <returns></returns>
public Task FollowAsync(string userObjectId) {
return FollowAsync(userObjectId, null);
}
/// <summary>
/// 关注某个用户
/// </summary>
/// <param name="userObjectId">被关注的用户Id</param>
/// <param name="data">关注的时候附加属性</param>
/// <returns></returns>
public Task FollowAsync(string userObjectId, IDictionary<string, object> data) {
if (data != null) {
data = EncodeForSaving(data);
}
var command = new AVCommand {
Path = $"users/{ObjectId}/friendship/{userObjectId}",
Method = HttpMethod.Post,
Content = data
};
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command);
}
/// <summary>
/// 取关某一个用户
/// </summary>
/// <param name="userObjectId"></param>
/// <returns></returns>
public Task UnfollowAsync(string userObjectId) {
var command = new AVCommand {
Path = $"users/{ObjectId}/friendship/{userObjectId}",
Method = HttpMethod.Delete
};
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command);
}
/// <summary>
/// 获取当前用户的关注者的查询
/// </summary>
/// <returns></returns>
public AVQuery<AVUser> GetFollowerQuery() {
AVQuery<AVUser> query = new AVQuery<AVUser> {
Path = $"users/{ObjectId}/followers"
};
return query;
}
/// <summary>
/// 获取当前用户所关注的用户的查询
/// </summary>
/// <returns></returns>
public AVQuery<AVUser> GetFolloweeQuery() {
AVQuery<AVUser> query = new AVQuery<AVUser> {
Path = $"users/{ObjectId}/followees"
};
return query;
}
/// <summary>
/// 同时查询关注了当前用户的关注者和当前用户所关注的用户
/// </summary>
/// <returns></returns>
public AVQuery<AVUser> GetFollowersAndFolloweesQuery() {
AVQuery<AVUser> query = new AVQuery<AVUser> {
Path = $"users/{ObjectId}/followersAndFollowees"
};
return query;
}
/// <summary>
/// 获取当前用户的关注者
/// </summary>
/// <returns></returns>
public Task<IEnumerable<AVUser>> GetFollowersAsync() {
return GetFollowerQuery().FindAsync(CancellationToken.None);
}
/// <summary>
/// 获取当前用户所关注的用户
/// </summary>
/// <returns></returns>
public Task<IEnumerable<AVUser>> GetFolloweesAsync() {
return GetFolloweeQuery().FindAsync(CancellationToken.None);
}
#endregion
/// <summary> /// <summary>
/// 使用用户名和密码登陆。登陆成功后,将用户设置为当前用户 /// 使用用户名和密码登陆。登陆成功后,将用户设置为当前用户
/// </summary> /// </summary>
@ -277,45 +216,16 @@ namespace LeanCloud {
} }
/// <summary> /// <summary>
/// 使用 Session Token 登录。 /// 用邮箱作和密码匹配登录
/// </summary> /// </summary>
/// <param name="sessionToken">Session Token</param> /// <param name="email">邮箱</param>
/// <param name="password">密码</param>
/// <returns></returns> /// <returns></returns>
public static async Task<AVUser> BecomeAsync(string sessionToken) { public static async Task<AVUser> LogInWithEmailAsync(string email, string password) {
var ret = await UserController.GetUserAsync(sessionToken); var ret = await UserController.LogInAsync(null, email, password);
AVUser user = FromState<AVUser>(ret, "_User"); AVUser user = FromState<AVUser>(ret, "_User");
CurrentUser = user; CurrentUser = user;
return user; return CurrentUser;
}
/// <summary>
/// 用户登出
/// </summary>
public static void LogOut() {
CurrentUser = null;
}
private static void LogOutWithProviders() {
foreach (var provider in authProviders.Values) {
provider.Deauthenticate();
}
}
/// <summary>
/// 获取当前用户
/// </summary>
public static AVUser CurrentUser {
get;
internal set;
}
/// <summary>
/// 创建一个 AVUser 查询对象
/// </summary>
public static AVQuery<AVUser> Query {
get {
return new AVQuery<AVUser>();
}
} }
/// <summary> /// <summary>
@ -339,83 +249,99 @@ namespace LeanCloud {
} }
/// <summary> /// <summary>
/// 用户数据 /// 申请发送验证邮箱的邮件,一周之内有效
/// 如果该邮箱已经验证通过,会直接返回 True并不会真正发送邮件
/// 注意,不能频繁的调用此接口,一天之内只允许向同一个邮箱发送验证邮件 3 次,超过调用次数,会直接返回错误
/// </summary> /// </summary>
internal IDictionary<string, IDictionary<string, object>> AuthData { /// <param name="email">邮箱地址</param>
get { /// <returns></returns>
if (TryGetValue("authData", out IDictionary<string, IDictionary<string, object>> authData)) { public static Task RequestEmailVerifyAsync(string email) {
return authData; Dictionary<string, object> strs = new Dictionary<string, object> {
} { "email", email }
return null; };
} var command = new AVCommand {
private set { Path = "requestEmailVerify",
this["authData"] = value; Method = HttpMethod.Post,
} Content = strs
};
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command);
} }
private static IAVAuthenticationProvider GetProvider(string providerName) { #endregion
if (authProviders.TryGetValue(providerName, out IAVAuthenticationProvider provider)) {
return provider;
#region 第三方登录
/// <summary>
/// 使用第三方数据注册;如果已经存在相同的 Auth Data则执行登录
/// </summary>
/// <param name="authData">Auth Data</param>
/// <param name="platform">平台</param>
/// <param name="options"></param>
/// <returns></returns>
public static Task<AVUser> LogInWithAuthDataAsync(IDictionary<string, object> authData, string platform, AVUserAuthDataLogInOption options = null) {
if (options == null) {
options = new AVUserAuthDataLogInOption();
} }
return null; return LogInWithAsync(platform, authData, options.FailOnNotExist);
} }
/// <summary> /// <summary>
/// Removes null values from authData (which exist temporarily for unlinking) /// 使用第三方数据注册;
/// </summary> /// </summary>
private void CleanupAuthData() { /// <param name="authData">Auth data</param>
lock (mutex) { /// <param name="platform">平台标识</param>
if (!IsCurrent) { /// <param name="unionId"></param>
return; /// <param name="options"></param>
} /// <returns></returns>
var authData = AuthData; public static Task<AVUser> LogInWithAuthDataAndUnionIdAsync(IDictionary<string, object> authData, string platform, string unionId,
AVUserAuthDataLogInOption options = null) {
if (authData == null) { if (options == null) {
return; options = new AVUserAuthDataLogInOption();
}
foreach (var pair in new Dictionary<string, IDictionary<string, object>>(authData)) {
if (pair.Value == null) {
authData.Remove(pair.Key);
}
}
} }
MergeAuthData(authData, unionId, options);
return LogInWithAsync(platform, authData, options.FailOnNotExist);
} }
/// <summary> /// <summary>
/// Synchronizes authData for all providers. /// 绑定第三方登录
/// </summary> /// </summary>
private void SynchronizeAllAuthData() { /// <param name="authData">Auth data</param>
lock (mutex) { /// <param name="platform">平台标识</param>
var authData = AuthData; /// <returns></returns>
public Task AssociateAuthDataAsync(IDictionary<string, object> authData, string platform) {
if (authData == null) { return LinkWithAsync(platform, authData);
return;
}
foreach (var pair in authData) {
SynchronizeAuthData(GetProvider(pair.Key));
}
}
} }
private void SynchronizeAuthData(IAVAuthenticationProvider provider) { /// <summary>
bool restorationSuccess = false; /// 绑定第三方登录
lock (mutex) { /// </summary>
var authData = AuthData; /// <param name="authData">OAuth data</param>
if (authData == null || provider == null) { /// <param name="platform">平台标识</param>
return; /// <param name="unionId"></param>
} /// <param name="options"></param>
if (authData.TryGetValue(provider.AuthType, out IDictionary<string, object> data)) { /// <returns></returns>
restorationSuccess = provider.RestoreAuthentication(data); public Task AssociateAuthDataAndUnionIdAsync(IDictionary<string, object> authData, string platform, string unionId,
} AVUserAuthDataLogInOption options = null) {
} if (options == null) {
options = new AVUserAuthDataLogInOption();
if (!restorationSuccess) {
UnlinkFromAsync(provider.AuthType, CancellationToken.None);
} }
MergeAuthData(authData, unionId, options);
return LinkWithAsync(platform, authData);
} }
/// <summary>
/// 解绑第三方登录
/// </summary>
/// <param name="platform">平台标识</param>
/// <returns></returns>
public Task DisassociateWithAuthDataAsync(string platform) {
return LinkWithAsync(platform, null);
}
#endregion
public Task LinkWithAsync(string authType, IDictionary<string, object> data) { public Task LinkWithAsync(string authType, IDictionary<string, object> data) {
AuthData = new Dictionary<string, IDictionary<string, object>> { AuthData = new Dictionary<string, IDictionary<string, object>> {
[authType] = data [authType] = data
@ -423,85 +349,25 @@ namespace LeanCloud {
return SaveAsync(); return SaveAsync();
} }
public Task LinkWithAsync(string authType, CancellationToken cancellationToken) {
var provider = GetProvider(authType);
return provider.AuthenticateAsync(cancellationToken)
.OnSuccess(t => LinkWithAsync(authType, t.Result))
.Unwrap();
}
/// <summary>
/// Unlinks a user from a service.
/// </summary>
public Task UnlinkFromAsync(string authType, CancellationToken cancellationToken) {
return LinkWithAsync(authType, null);
}
/// <summary>
/// Checks whether a user is linked to a service.
/// </summary>
internal bool IsLinked(string authType) {
lock (mutex) {
return AuthData != null && AuthData.ContainsKey(authType) && AuthData[authType] != null;
}
}
internal static async Task<AVUser> LogInWithAsync(string authType, IDictionary<string, object> data, bool failOnNotExist) { internal static async Task<AVUser> LogInWithAsync(string authType, IDictionary<string, object> data, bool failOnNotExist) {
var ret = await UserController.LogInAsync(authType, data, failOnNotExist); var ret = await UserController.LogInAsync(authType, data, failOnNotExist);
AVUser user = FromState<AVUser>(ret, "_User"); AVUser user = FromState<AVUser>(ret, "_User");
user.AuthData = new Dictionary<string, IDictionary<string, object>>(); user.AuthData = new Dictionary<string, IDictionary<string, object>> {
user.AuthData[authType] = data; [authType] = data
user.SynchronizeAllAuthData(); };
CurrentUser = user; CurrentUser = user;
return CurrentUser; return CurrentUser;
} }
internal static Task<AVUser> LogInWithAsync(string authType) {
var provider = GetProvider(authType);
return provider.AuthenticateAsync(CancellationToken.None)
.OnSuccess(authData => LogInWithAsync(authType, authData.Result, false))
.Unwrap();
}
internal static void RegisterProvider(IAVAuthenticationProvider provider) {
authProviders[provider.AuthType] = provider;
var curUser = CurrentUser;
if (curUser != null) {
curUser.SynchronizeAuthData(provider);
}
}
#region 手机号登录 #region 手机号登录
internal static async Task<AVUser> LogInWithParametersAsync(Dictionary<string, object> strs) {
IObjectState ret = await UserController.LogInWithParametersAsync("login", strs);
AVUser user = CreateWithoutData<AVUser>(null);
user.HandleFetchResult(ret);
CurrentUser = user;
return CurrentUser;
}
/// <summary>
/// 用邮箱作和密码匹配登录
/// </summary>
/// <param name="email">邮箱</param>
/// <param name="password">密码</param>
/// <returns></returns>
public static async Task<AVUser> LogInByEmailAsync(string email, string password) {
var ret = await UserController.LogInAsync(null, email, password);
AVUser user = FromState<AVUser>(ret, "_User");
CurrentUser = user;
return CurrentUser;
}
/// <summary> /// <summary>
/// 用手机号和密码匹配登陆 /// 用手机号和密码匹配登陆
/// </summary> /// </summary>
/// <param name="mobilePhoneNumber">手机号</param> /// <param name="mobilePhoneNumber">手机号</param>
/// <param name="password">密码</param> /// <param name="password">密码</param>
/// <returns></returns> /// <returns></returns>
public static Task<AVUser> LogInByMobilePhoneNumberAsync(string mobilePhoneNumber, string password) { public static Task<AVUser> LogInWithMobilePhoneNumberAsync(string mobilePhoneNumber, string password) {
Dictionary<string, object> strs = new Dictionary<string, object> { Dictionary<string, object> strs = new Dictionary<string, object> {
{ "mobilePhoneNumber", mobilePhoneNumber }, { "mobilePhoneNumber", mobilePhoneNumber },
{ "password", password } { "password", password }
@ -515,7 +381,7 @@ namespace LeanCloud {
/// <param name="mobilePhoneNumber">手机号</param> /// <param name="mobilePhoneNumber">手机号</param>
/// <param name="smsCode">短信验证码</param> /// <param name="smsCode">短信验证码</param>
/// <returns></returns> /// <returns></returns>
public static Task<AVUser> LogInByMobilePhoneNumberSmsCodeAsync(string mobilePhoneNumber, string smsCode) { public static Task<AVUser> LogInWithMobilePhoneNumberSmsCodeAsync(string mobilePhoneNumber, string smsCode) {
Dictionary<string, object> strs = new Dictionary<string, object> { Dictionary<string, object> strs = new Dictionary<string, object> {
{ "mobilePhoneNumber", mobilePhoneNumber }, { "mobilePhoneNumber", mobilePhoneNumber },
{ "smsCode", smsCode } { "smsCode", smsCode }
@ -641,60 +507,10 @@ namespace LeanCloud {
#endregion #endregion
#region 邮箱验证
/// <summary> /// <summary>
/// 申请发送验证邮箱的邮件,一周之内有效 /// 匿名登录
/// 如果该邮箱已经验证通过,会直接返回 True并不会真正发送邮件
/// 注意,不能频繁的调用此接口,一天之内只允许向同一个邮箱发送验证邮件 3 次,超过调用次数,会直接返回错误
/// </summary> /// </summary>
/// <param name="email">邮箱地址</param>
/// <returns></returns> /// <returns></returns>
public static Task RequestEmailVerifyAsync(string email) {
Dictionary<string, object> strs = new Dictionary<string, object> {
{ "email", email }
};
var command = new AVCommand {
Path = "requestEmailVerify",
Method = HttpMethod.Post,
Content = strs
};
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command);
}
#endregion
#region AVUser Extension
public IDictionary<string, IDictionary<string, object>> GetAuthData() {
return AuthData;
}
/// <summary>
/// use 3rd auth data to sign up or log in.if user with the same auth data exits,it will transfer as log in.
/// </summary>
/// <param name="data">OAuth data, like {"accessToken":"xxxxxx"}</param>
/// <param name="platform">auth platform,maybe "facebook"/"twiiter"/"weibo"/"weixin" .etc</param>
/// <returns></returns>
public static Task<AVUser> LogInWithAuthDataAsync(IDictionary<string, object> data, string platform, AVUserAuthDataLogInOption options = null) {
if (options == null) {
options = new AVUserAuthDataLogInOption();
}
return LogInWithAsync(platform, data, options.FailOnNotExist);
}
public static Task<AVUser> LogInWithAuthDataAndUnionIdAsync(
IDictionary<string, object> authData,
string platform,
string unionId,
AVUserAuthDataLogInOption options = null) {
if (options == null) {
options = new AVUserAuthDataLogInOption();
}
MergeAuthData(authData, unionId, options);
return LogInWithAsync(platform, authData, options.FailOnNotExist);
}
public static Task<AVUser> LogInAnonymouslyAsync() { public static Task<AVUser> LogInAnonymouslyAsync() {
var data = new Dictionary<string, object> { var data = new Dictionary<string, object> {
{ "id", Guid.NewGuid().ToString() } { "id", Guid.NewGuid().ToString() }
@ -704,35 +520,124 @@ namespace LeanCloud {
} }
/// <summary> /// <summary>
/// link a 3rd auth account to the user. /// 使用 Session Token 登录。
/// </summary> /// </summary>
/// <param name="data">OAuth data, like {"accessToken":"xxxxxx"}</param> /// <param name="sessionToken">Session Token</param>
/// <param name="platform">auth platform,maybe "facebook"/"twiiter"/"weibo"/"weixin" .etc</param>
/// <returns></returns> /// <returns></returns>
public Task AssociateAuthDataAsync(IDictionary<string, object> data, string platform) { public static async Task<AVUser> BecomeAsync(string sessionToken) {
return LinkWithAsync(platform, data); var ret = await UserController.GetUserAsync(sessionToken);
} AVUser user = FromState<AVUser>(ret, "_User");
CurrentUser = user;
public Task AssociateAuthDataAndUnionIdAsync( return user;
IDictionary<string, object> authData,
string platform,
string unionId,
AVUserAuthDataLogInOption options = null) {
if (options == null) {
options = new AVUserAuthDataLogInOption();
}
MergeAuthData(authData, unionId, options);
return LinkWithAsync(platform, authData);
} }
/// <summary> /// <summary>
/// unlink a 3rd auth account from the user. /// 用户登出
/// </summary> /// </summary>
/// <param name="platform">auth platform,maybe "facebook"/"twiiter"/"weibo"/"weixin" .etc</param> public static void LogOut() {
/// <param name="cancellationToken"></param> CurrentUser = null;
}
#region 事件流系统相关 API
/// <summary>
/// 关注某个用户
/// </summary>
/// <param name="userObjectId">被关注的用户</param>
/// <returns></returns> /// <returns></returns>
public Task DisassociateWithAuthDataAsync(string platform, CancellationToken cancellationToken = default(System.Threading.CancellationToken)) { public Task FollowAsync(string userObjectId) {
return UnlinkFromAsync(platform, cancellationToken); return FollowAsync(userObjectId, null);
}
/// <summary>
/// 关注某个用户
/// </summary>
/// <param name="userObjectId">被关注的用户Id</param>
/// <param name="data">关注的时候附加属性</param>
/// <returns></returns>
public Task FollowAsync(string userObjectId, IDictionary<string, object> data) {
if (data != null) {
data = EncodeForSaving(data);
}
var command = new AVCommand {
Path = $"users/{ObjectId}/friendship/{userObjectId}",
Method = HttpMethod.Post,
Content = data
};
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command);
}
/// <summary>
/// 取关某一个用户
/// </summary>
/// <param name="userObjectId"></param>
/// <returns></returns>
public Task UnfollowAsync(string userObjectId) {
var command = new AVCommand {
Path = $"users/{ObjectId}/friendship/{userObjectId}",
Method = HttpMethod.Delete
};
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command);
}
/// <summary>
/// 获取当前用户的关注者的查询
/// </summary>
/// <returns></returns>
public AVQuery<AVUser> GetFollowerQuery() {
AVQuery<AVUser> query = new AVQuery<AVUser> {
Path = $"users/{ObjectId}/followers"
};
return query;
}
/// <summary>
/// 获取当前用户所关注的用户的查询
/// </summary>
/// <returns></returns>
public AVQuery<AVUser> GetFolloweeQuery() {
AVQuery<AVUser> query = new AVQuery<AVUser> {
Path = $"users/{ObjectId}/followees"
};
return query;
}
/// <summary>
/// 同时查询关注了当前用户的关注者和当前用户所关注的用户
/// </summary>
/// <returns></returns>
public AVQuery<AVUser> GetFollowersAndFolloweesQuery() {
AVQuery<AVUser> query = new AVQuery<AVUser> {
Path = $"users/{ObjectId}/followersAndFollowees"
};
return query;
}
/// <summary>
/// 获取当前用户的关注者
/// </summary>
/// <returns></returns>
public Task<IEnumerable<AVUser>> GetFollowersAsync() {
return GetFollowerQuery().FindAsync(CancellationToken.None);
}
/// <summary>
/// 获取当前用户所关注的用户
/// </summary>
/// <returns></returns>
public Task<IEnumerable<AVUser>> GetFolloweesAsync() {
return GetFolloweeQuery().FindAsync(CancellationToken.None);
}
#endregion
internal static async Task<AVUser> LogInWithParametersAsync(Dictionary<string, object> strs) {
IObjectState ret = await UserController.LogInWithParametersAsync("login", strs);
AVUser user = CreateWithoutData<AVUser>(null);
user.HandleFetchResult(ret);
CurrentUser = user;
return CurrentUser;
} }
/// 合并为支持 AuthData 的格式 /// 合并为支持 AuthData 的格式
@ -741,7 +646,5 @@ namespace LeanCloud {
authData["main_account"] = options.AsMainAccount; authData["main_account"] = options.AsMainAccount;
authData["unionid"] = unionId; authData["unionid"] = unionId;
} }
#endregion
} }
} }