From 6576cbd47f21f6e69019c102f5c25452fffbadb5 Mon Sep 17 00:00:00 2001 From: oneRain Date: Thu, 27 Feb 2020 11:31:38 +0800 Subject: [PATCH] =?UTF-8?q?*=20UserTest.cs:=20chore:=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E5=8A=9F=E8=83=BD=E5=92=8C=E6=B5=8B=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * LCUser.cs: * LCUserAuthDataLoginOption.cs: * LCHttpClient.cs: --- Storage/Storage.Test/UserTest.cs | 214 ++++--- Storage/Storage/Internal/Http/LCHttpClient.cs | 10 +- Storage/Storage/LCUser.cs | 542 ++++++++++++++++++ Storage/Storage/LCUserAuthDataLoginOption.cs | 28 +- 4 files changed, 721 insertions(+), 73 deletions(-) diff --git a/Storage/Storage.Test/UserTest.cs b/Storage/Storage.Test/UserTest.cs index 5641c58..1504f3a 100644 --- a/Storage/Storage.Test/UserTest.cs +++ b/Storage/Storage.Test/UserTest.cs @@ -1,114 +1,186 @@ using NUnit.Framework; +using System; using System.Collections.Generic; using System.Threading.Tasks; -using System.Linq; -using System; -using LeanCloud; +using LeanCloud.Storage; namespace LeanCloud.Test { public class UserTest { [SetUp] public void SetUp() { - AVClient.Initialize(new AVClient.Configuration { - ApplicationId = "BMYV4RKSTwo8WSqt8q9ezcWF-gzGzoHsz", - ApplicationKey = "pbf6Nk5seyjilexdpyrPwjSp", - ApiServer = "https://avoscloud.com" - }); - AVClient.HttpLog(TestContext.Out.WriteLine); + Logger.LogDelegate += Utils.Print; + LeanCloud.Initialize("ikGGdRE2YcVOemAaRbgp1xGJ-gzGzoHsz", "NUKmuRbdAhg1vrb2wexYo1jo", "https://ikggdre2.lc-cn-n1-shared.com"); + } + + [TearDown] + public void TearDown() { + Logger.LogDelegate -= Utils.Print; } [Test] - public async Task Register() { - AVUser user = new AVUser { - Username = $"hello_{DateTimeOffset.UtcNow.ToUnixTimeSeconds()}", - Password = "world" - }; - await user.SignUpAsync(); - TestContext.Out.WriteLine($"{user.ObjectId} registered"); + public async Task SignUp() { + LCUser user = new LCUser(); + long unixTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); + user.Username = $"{unixTime}"; + user.Password = "world"; + string email = $"{unixTime}@qq.com"; + user.Email = email; + string mobile = $"{unixTime / 100}"; + user.Mobile = mobile; + await user.SignUp(); + + TestContext.WriteLine(user.Username); + TestContext.WriteLine(user.Password); + + Assert.NotNull(user.ObjectId); + TestContext.WriteLine(user.ObjectId); + Assert.NotNull(user.SessionToken); + TestContext.WriteLine(user.SessionToken); + Assert.AreEqual(user.Email, email); } [Test] - public async Task LoginWithUsername() { - AVUser user = await AVUser.LogInAsync("hello", "111111"); - TestContext.Out.WriteLine($"{user.ObjectId}, {user.SessionToken} login"); + public async Task Login() { + await LCUser.Login("hello", "world"); + LCUser current = await LCUser.GetCurrent(); + Assert.NotNull(current.ObjectId); + Assert.IsFalse(current.EmailVerified); + Assert.IsFalse(current.MobileVerified); + Assert.AreEqual(current.Mobile, "15101006008"); } [Test] - public async Task LoginWithEmail() { - AVUser user = await AVUser.LogInWithEmailAsync("111111@qq.com", "111111"); - Assert.AreEqual(user, AVUser.CurrentUser); - TestContext.Out.WriteLine($"{AVUser.CurrentUser.SessionToken} login"); + public async Task LoginByEmail() { + await LCUser.LoginByEmail("171253484@qq.com", "world"); + LCUser current = await LCUser.GetCurrent(); + Assert.NotNull(current.ObjectId); } [Test] - public async Task Become() { - AVUser user = await AVUser.BecomeAsync("o8onm9bq8z127lz837mi6qhcg"); - Assert.AreEqual(user, AVUser.CurrentUser); - TestContext.Out.WriteLine($"{AVUser.CurrentUser.SessionToken} login"); + public async Task LoginBySessionToken() { + string sessionToken = "luo2fpl4qij2050e7enqfz173"; + await LCUser.BecomeWithSessionToken(sessionToken); + LCUser current = await LCUser.GetCurrent(); + Assert.NotNull(current.ObjectId); } [Test] - public async Task IsAuthenticated() { - AVUser user = await AVUser.LogInWithEmailAsync("111111@qq.com", "111111"); - Assert.IsTrue(user.IsCurrent); - Assert.AreEqual(user, AVUser.CurrentUser); - bool authenticated = await user.IsAuthenticatedAsync(); - Assert.IsTrue(authenticated); + public async Task RelateObject() { + LCUser user = await LCUser.LoginByMobilePhoneNumber("15101006007", "112358"); + LCObject account = new LCObject("Account"); + account["user"] = user; + await account.Save(); + Assert.AreEqual(user.ObjectId, "5e0d5c667d5774006a5c1177"); } [Test] - public async Task RefreshSessionToken() { - AVUser user = await AVUser.LogInWithEmailAsync("111111@qq.com", "111111"); - Assert.IsTrue(user.IsCurrent); - await user.RefreshSessionTokenAsync(); - TestContext.Out.WriteLine(user.SessionToken); - } - - [Test] - public async Task UpdatePassword() { - AVUser user = await AVUser.LogInAsync("111111", "111111"); - await user.UpdatePasswordAsync("111111", "222222"); - await user.UpdatePasswordAsync("222222", "111111"); + public async Task LoginAnonymous() { + LCUser user = await LCUser.LoginAnonymously(); + Assert.NotNull(user.ObjectId); } [Test] public async Task LoginWithAuthData() { - AVUser user = await AVUser.LogInWithAuthDataAsync(new Dictionary { - { "openid", "0395BA18A5CD6255E5BA185E7BEBA242" }, - { "access_token", "12345678-SaMpLeTuo3m2avZxh5cjJmIrAfx4ZYyamdofM7IjU" }, - { "expires_in", 1382686496 } - }, "qq"); - Assert.NotNull(user.SessionToken); - TestContext.Out.WriteLine(user.SessionToken); + string uuid = Guid.NewGuid().ToString(); + Dictionary authData = new Dictionary { + { "expires_in", 7200 }, + { "openid", uuid }, + { "access_token", uuid } + }; + LCUser currentUser = await LCUser.LoginWithAuthData(authData, "weixin"); + TestContext.WriteLine(currentUser.SessionToken); + Assert.NotNull(currentUser.SessionToken); + string userId = currentUser.ObjectId; + TestContext.WriteLine($"userId: {userId}"); + TestContext.WriteLine(currentUser.AuthData); + + await LCUser.Logout(); + currentUser = await LCUser.GetCurrent(); + Assert.IsNull(currentUser); + + currentUser = await LCUser.LoginWithAuthData(authData, "weixin"); + TestContext.WriteLine(currentUser.SessionToken); + Assert.NotNull(currentUser.SessionToken); + Assert.AreEqual(currentUser.ObjectId, userId); + TestContext.WriteLine(currentUser.AuthData); } [Test] public async Task AssociateAuthData() { - AVUser user = await AVUser.LogInAsync("111111", "111111"); - Assert.NotNull(user.SessionToken); - await user.AssociateAuthDataAsync(new Dictionary { - { "openid", "0395BA18A5CD6255E5BA185E7BEBA243" }, - { "access_token", "12345678-SaMpLeTuo3m2avZxh5cjJmIrAfx4ZYyamdofM7IjU" }, - { "expires_in", 1382686496 } - }, "qq"); + string uuid = Guid.NewGuid().ToString(); + LCUser currentUser = await LCUser.Login("hello", "world"); + Dictionary authData = new Dictionary { + { "expires_in", 7200 }, + { "openid", uuid }, + { "access_token", uuid } + }; + await currentUser.AssociateAuthData(authData, "weixin"); + TestContext.WriteLine(currentUser.AuthData); + TestContext.WriteLine(currentUser.AuthData["weixin"]); } [Test] - public async Task Anonymously() { - AVUser user = await AVUser.LogInAnonymouslyAsync(); - Assert.NotNull(user.SessionToken); - TestContext.Out.WriteLine(user.SessionToken); + public async Task DisassociateAuthData() { + LCUser currentUser = await LCUser.Login("hello", "world"); + await currentUser.DisassociateWithAuthData("weixin"); } [Test] - public async Task GetRoles() { - AVUser user = await AVUser.LogInAsync("111111", "111111"); - Assert.NotNull(user.SessionToken); - IEnumerable roles = await user.GetRolesAsync(); - Assert.Greater(roles.Count(), 0); - foreach (AVRole role in roles) { - TestContext.Out.WriteLine(role.Name); - } + public async Task IsAuthenticated() { + LCUser currentUser = await LCUser.Login("hello", "world"); + bool isAuthenticated = await currentUser.IsAuthenticated(); + TestContext.WriteLine(isAuthenticated); + Assert.IsTrue(isAuthenticated); + } + + [Test] + public async Task UpdatePassword() { + LCUser currentUser = await LCUser.Login("hello", "world"); + await currentUser.UpdatePassword("world", "newWorld"); + await currentUser.UpdatePassword("newWorld", "world"); + } + + [Test] + public async Task LoginWithAuthDataWithUnionId() { + string uuid = Guid.NewGuid().ToString(); + Dictionary authData = new Dictionary { + { "expires_in", 7200 }, + { "openid", uuid }, + { "access_token", uuid } + }; + string unionId = Guid.NewGuid().ToString(); + + LCUserAuthDataLoginOption option = new LCUserAuthDataLoginOption(); + option.AsMainAccount = true; + LCUser currentUser = await LCUser.LoginWithAuthDataAndUnionId(authData, "weixin_app", unionId, option: option); + TestContext.WriteLine(currentUser.SessionToken); + Assert.NotNull(currentUser.SessionToken); + string userId = currentUser.ObjectId; + TestContext.WriteLine($"userId: {userId}"); + TestContext.WriteLine(currentUser.AuthData); + + await LCUser.Logout(); + currentUser = await LCUser.GetCurrent(); + Assert.IsNull(currentUser); + + currentUser = await LCUser.LoginWithAuthDataAndUnionId(authData, "weixin_mini_app", unionId, option: option); + TestContext.WriteLine(currentUser.SessionToken); + Assert.NotNull(currentUser.SessionToken); + Assert.AreEqual(currentUser.ObjectId, userId); + TestContext.WriteLine(currentUser.AuthData); + } + + [Test] + public async Task AssociateAuthDataWithUnionId() { + LCUser currentUser = await LCUser.Login("hello", "world"); + string uuid = Guid.NewGuid().ToString(); + Dictionary authData = new Dictionary { + { "expires_in", 7200 }, + { "openid", uuid }, + { "access_token", uuid } + }; + string unionId = Guid.NewGuid().ToString(); + await currentUser.AssociateAuthDataAndUnionId(authData, "qq", unionId); } } } diff --git a/Storage/Storage/Internal/Http/LCHttpClient.cs b/Storage/Storage/Internal/Http/LCHttpClient.cs index 424a1b3..1293fc9 100644 --- a/Storage/Storage/Internal/Http/LCHttpClient.cs +++ b/Storage/Storage/Internal/Http/LCHttpClient.cs @@ -34,7 +34,7 @@ namespace LeanCloud.Storage.Internal.Http { client.DefaultRequestHeaders.UserAgent.Add(new ProductInfoHeaderValue(product)); client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); client.DefaultRequestHeaders.Add("X-LC-Id", appId); - // TODO + // TODO 改为 signature client.DefaultRequestHeaders.Add("X-LC-Key", appKey); } @@ -58,6 +58,10 @@ namespace LeanCloud.Storage.Internal.Http { request.Headers.Add(kv.Key, kv.Value.ToString()); } } + LCUser currentUser = await LCUser.GetCurrent(); + if (currentUser != null) { + request.Headers.Add("X-LC-Session", currentUser.SessionToken); + } HttpUtils.PrintRequest(client, request); HttpResponseMessage response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); request.Dispose(); @@ -144,6 +148,10 @@ namespace LeanCloud.Storage.Internal.Http { Content = new StringContent(content) }; request.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); + LCUser currentUser = await LCUser.GetCurrent(); + if (currentUser != null) { + request.Headers.Add("X-LC-Session", currentUser.SessionToken); + } HttpUtils.PrintRequest(client, request, content); HttpResponseMessage response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead); request.Dispose(); diff --git a/Storage/Storage/LCUser.cs b/Storage/Storage/LCUser.cs index e4a5fa1..b8355a6 100644 --- a/Storage/Storage/LCUser.cs +++ b/Storage/Storage/LCUser.cs @@ -1,11 +1,553 @@ using System; +using System.Threading.Tasks; +using System.Collections.Generic; +using LeanCloud.Storage.Internal.Object; namespace LeanCloud.Storage { public class LCUser : LCObject { public const string CLASS_NAME = "_User"; + public string Username { + get { + return this["username"] as string; + } set { + this["username"] = value; + } + } + + public string Password { + get { + return this["password"] as string; + } set { + this["password"] = value; + } + } + + public string Email { + get { + return this["email"] as string; + } set { + this["email"] = value; + } + } + + public string Mobile { + get { + return this["mobilePhoneNumber"] as string; + } set { + this["mobilePhoneNumber"] = value; + } + } + + public string SessionToken { + get { + return this["sessionToken"] as string; + } set { + this["sessionToken"] = value; + } + } + + public bool EmailVerified { + get { + return (bool)this["emailVerified"]; + } + } + + public bool MobileVerified { + get { + return (bool)this["mobilePhoneVerified"]; + } + } + + public Dictionary AuthData { + get { + return this["authData"] as Dictionary; + } set { + this["authData"] = value; + } + } + + static LCUser currentUser; + + public static Task GetCurrent() { + // TODO 加载持久化数据 + + return Task.FromResult(currentUser); + } + public LCUser() : base(CLASS_NAME) { } + + LCUser(LCObjectData objectData) : this() { + Merge(objectData); + } + + /// + /// 注册 + /// + /// + public async Task SignUp() { + if (string.IsNullOrEmpty(Username)) { + throw new ArgumentNullException(nameof(Username)); + } + if (string.IsNullOrEmpty(Password)) { + throw new ArgumentNullException(nameof(Password)); + } + if (!string.IsNullOrEmpty(ObjectId)) { + throw new ArgumentException("Cannot sign up a user that already exists."); + } + await Save(); + currentUser = this; + // TODO Persistence + + return this; + } + + /// + /// 请求登录注册码 + /// + /// + /// + public static async Task RequestLoginSMSCode(string mobile) { + if (string.IsNullOrEmpty(mobile)) { + throw new ArgumentNullException(nameof(mobile)); + } + Dictionary data = new Dictionary { + { "mobilePhoneNumber", mobile } + }; + await LeanCloud.HttpClient.Post>("requestLoginSmsCode", data: data); + } + + /// + /// 使用手机号和验证码注册或登录 + /// + /// + /// + /// + public static async Task SignUpOrLoginByMobilePhone(string mobile, string code) { + if (string.IsNullOrEmpty(mobile)) { + throw new ArgumentNullException(nameof(mobile)); + } + if (string.IsNullOrEmpty(mobile)) { + throw new ArgumentNullException(nameof(code)); + } + Dictionary data = new Dictionary { + { "mobilePhoneNumber", mobile }, + { "smsCode", code } + }; + Dictionary response = await LeanCloud.HttpClient.Post>("usersByMobilePhone", data: data); + LCObjectData objectData = LCObjectData.Decode(response); + currentUser = new LCUser(objectData); + return currentUser; + } + + /// + /// 以账号和密码登陆 + /// + /// + /// + /// + public static Task Login(string username, string password) { + if (string.IsNullOrEmpty(username)) { + throw new ArgumentNullException(nameof(username)); + } + if (string.IsNullOrEmpty(password)) { + throw new ArgumentNullException(nameof(password)); + } + Dictionary data = new Dictionary { + { "username", username }, + { "password", password } + }; + return Login(data); + } + + /// + /// 以邮箱和密码登陆 + /// + /// + /// + /// + public static Task LoginByEmail(string email, string password) { + if (string.IsNullOrEmpty(email)) { + throw new ArgumentNullException(nameof(email)); + } + if (string.IsNullOrEmpty(password)) { + throw new ArgumentNullException(nameof(password)); + } + Dictionary data = new Dictionary { + { "email", email }, + { "password", password } + }; + return Login(data); + } + + /// + /// 以手机号和密码登陆 + /// + /// + /// + /// + public static Task LoginByMobilePhoneNumber(string mobile, string password) { + if (string.IsNullOrEmpty(mobile)) { + throw new ArgumentNullException(nameof(mobile)); + } + if (string.IsNullOrEmpty(password)) { + throw new ArgumentNullException(nameof(password)); + } + Dictionary data = new Dictionary { + { "mobilePhoneNumber", mobile }, + { "password", password } + }; + return Login(data); + } + + /// + /// 以手机号和验证码登录 + /// + /// + /// + /// + public static Task LoginBySMSCode(string mobile, string code) { + if (string.IsNullOrEmpty(mobile)) { + throw new ArgumentNullException(nameof(mobile)); + } + if (string.IsNullOrEmpty(code)) { + throw new ArgumentNullException(nameof(code)); + } + Dictionary data = new Dictionary { + { "mobilePhoneNumber", mobile }, + { "smsCode", code } + }; + return Login(data); + } + + /// + /// 使用第三方数据登录 + /// + /// + /// + /// + /// + public static Task LoginWithAuthData(Dictionary authData, string platform, + LCUserAuthDataLoginOption option = null) { + if (authData == null) { + throw new ArgumentNullException(nameof(authData)); + } + if (string.IsNullOrEmpty(platform)) { + throw new ArgumentNullException(nameof(platform)); + } + if (option == null) { + option = new LCUserAuthDataLoginOption(); + } + return LoginWithAuthData(platform, authData, option.FailOnNotExist); + } + + /// + /// 使用第三方数据和 Union Id 登录 + /// + /// + /// + /// + /// + /// + public static Task LoginWithAuthDataAndUnionId(Dictionary authData, string platform, string unionId, + LCUserAuthDataLoginOption option = null) { + if (authData == null) { + throw new ArgumentNullException(nameof(authData)); + } + if (string.IsNullOrEmpty(platform)) { + throw new ArgumentNullException(nameof(platform)); + } + if (string.IsNullOrEmpty(unionId)) { + throw new ArgumentNullException(nameof(unionId)); + } + if (option == null) { + option = new LCUserAuthDataLoginOption(); + } + MergeAuthData(authData, unionId, option); + return LoginWithAuthData(platform, authData, option.FailOnNotExist); + } + + /// + /// 绑定第三方登录 + /// + /// + /// + /// + public Task AssociateAuthData(Dictionary authData, string platform) { + if (authData == null) { + throw new ArgumentNullException(nameof(authData)); + } + if (string.IsNullOrEmpty(platform)) { + throw new ArgumentNullException(nameof(platform)); + } + return LinkWithAuthData(platform, authData); + } + + /// + /// 使用 Union Id 绑定第三方登录 + /// + /// + /// + /// + /// + /// + public Task AssociateAuthDataAndUnionId(Dictionary authData, string platform, string unionId, + LCUserAuthDataLoginOption option = null) { + if (authData == null) { + throw new ArgumentNullException(nameof(authData)); + } + if (string.IsNullOrEmpty(platform)) { + throw new ArgumentNullException(nameof(platform)); + } + if (string.IsNullOrEmpty(unionId)) { + throw new ArgumentNullException(nameof(unionId)); + } + if (option == null) { + option = new LCUserAuthDataLoginOption(); + } + MergeAuthData(authData, unionId, option); + return LinkWithAuthData(platform, authData); + } + + /// + /// 解绑第三方登录 + /// + /// + /// + public Task DisassociateWithAuthData(string platform) { + if (string.IsNullOrEmpty(platform)) { + throw new ArgumentNullException(nameof(platform)); + } + return LinkWithAuthData(platform, null); + } + + /// + /// 匿名登录 + /// + /// + public static Task LoginAnonymously() { + Dictionary data = new Dictionary { + { "id", Guid.NewGuid().ToString() } + }; + return LoginWithAuthData(data, "anonymous"); + } + + /// + /// 请求验证邮箱 + /// + /// + /// + public static async Task RequestEmailVerify(string email) { + if (string.IsNullOrEmpty(email)) { + throw new ArgumentNullException(nameof(email)); + } + Dictionary data = new Dictionary { + { "email", email } + }; + await LeanCloud.HttpClient.Post>("requestEmailVerify", data: data); + } + + /// + /// 请求手机验证码 + /// + /// + /// + public static async Task RequestMobilePhoneVerify(string mobile) { + if (string.IsNullOrEmpty(mobile)) { + throw new ArgumentNullException(nameof(mobile)); + } + Dictionary data = new Dictionary { + { "mobilePhoneNumber", mobile } + }; + await LeanCloud.HttpClient.Post>("requestMobilePhoneVerify", data: data); + } + + /// + /// 验证手机号 + /// + /// + /// + /// + public static async Task VerifyMobilePhone(string mobile, string code) { + if (string.IsNullOrEmpty(mobile)) { + throw new ArgumentNullException(nameof(mobile)); + } + if (string.IsNullOrEmpty(code)) { + throw new ArgumentNullException(nameof(code)); + } + string path = $"verifyMobilePhone/{code}"; + Dictionary data = new Dictionary { + { "mobilePhoneNumber", mobile } + }; + await LeanCloud.HttpClient.Post>(path, data: data); + } + + /// + /// 设置当前用户 + /// + /// + /// + public static async Task BecomeWithSessionToken(string sessionToken) { + if (string.IsNullOrEmpty(sessionToken)) { + throw new ArgumentNullException(nameof(sessionToken)); + } + Dictionary headers = new Dictionary { + { "X-LC-Session", sessionToken } + }; + Dictionary response = await LeanCloud.HttpClient.Get>("users/me", + headers: headers); + LCObjectData objectData = LCObjectData.Decode(response); + currentUser = new LCUser(objectData); + return currentUser; + } + + /// + /// 请求使用邮箱重置密码 + /// + /// + /// + public static async Task RequestPasswordReset(string email) { + if (string.IsNullOrEmpty(email)) { + throw new ArgumentNullException(nameof(email)); + } + Dictionary data = new Dictionary { + { "email", email } + }; + await LeanCloud.HttpClient.Post>("requestPasswordReset", + data: data); + } + + /// + /// 请求验证码重置密码 + /// + /// + /// + public static async Task RequestPasswordRestBySmsCode(string mobile) { + if (string.IsNullOrEmpty(mobile)) { + throw new ArgumentNullException(nameof(mobile)); + } + Dictionary data = new Dictionary { + { "mobilePhoneNumber", mobile } + }; + await LeanCloud.HttpClient.Post>("requestPasswordResetBySmsCode", + data: data); + } + + /// + /// 使用验证码重置密码 + /// + /// + /// + /// + /// + public static async Task ResetPasswordBySmsCode(string mobile, string code, string newPassword) { + if (string.IsNullOrEmpty(mobile)) { + throw new ArgumentNullException(nameof(mobile)); + } + if (string.IsNullOrEmpty(code)) { + throw new ArgumentNullException(nameof(code)); + } + if (string.IsNullOrEmpty(newPassword)) { + throw new ArgumentNullException(nameof(newPassword)); + } + Dictionary data = new Dictionary { + { "mobilePhoneNumber", mobile }, + { "password", newPassword } + }; + await LeanCloud.HttpClient.Put>($"resetPasswordBySmsCode/{code}", + data: data); + } + + /// + /// 更新密码 + /// + /// + /// + /// + public async Task UpdatePassword(string oldPassword, string newPassword) { + if (string.IsNullOrEmpty(oldPassword)) { + throw new ArgumentNullException(nameof(oldPassword)); + } + if (string.IsNullOrEmpty(newPassword)) { + throw new ArgumentNullException(nameof(newPassword)); + } + Dictionary data = new Dictionary { + { "old_password", oldPassword }, + { "new_password", newPassword } + }; + Dictionary response = await LeanCloud.HttpClient.Put>( + $"users/{ObjectId}/updatePassword", data:data); + LCObjectData objectData = LCObjectData.Decode(response); + Merge(objectData); + } + + /// + /// 注销登录 + /// + public static Task Logout() { + currentUser = null; + // TODO 清理持久化数据 + + return Task.FromResult(null); + } + + /// + /// 是否是有效登录 + /// + /// + public async Task IsAuthenticated() { + if (SessionToken == null || ObjectId == null) { + return false; + } + try { + await LeanCloud.HttpClient.Get>("users/me"); + return true; + } catch (Exception) { + return false; + } + } + + /// + /// 得到 LCUser 类型的查询对象 + /// + /// + public static LCQuery GetQuery() { + return new LCQuery(CLASS_NAME); + } + + Task LinkWithAuthData(string authType, Dictionary data) { + AuthData = new Dictionary { + { authType, data } + }; + return Save(); + } + + static async Task Login(Dictionary data) { + Dictionary response = await LeanCloud.HttpClient.Post>("login", data: data); + LCObjectData objectData = LCObjectData.Decode(response); + currentUser = new LCUser(objectData); + return currentUser; + } + + static async Task LoginWithAuthData(string authType, Dictionary data, bool failOnNotExist) { + Dictionary authData = new Dictionary { + { authType, data } + }; + string path = failOnNotExist ? "users?failOnNotExist=true" : "users"; + Dictionary response = await LeanCloud.HttpClient.Post>(path, data: new Dictionary { + { "authData", authData } + }); + LCObjectData objectData = LCObjectData.Decode(response); + currentUser = new LCUser(objectData); + return currentUser; + } + + static void MergeAuthData(Dictionary authData, string unionId, LCUserAuthDataLoginOption option) { + authData["platform"] = option.UnionIdPlatform; + authData["main_account"] = option.AsMainAccount; + authData["unionid"] = unionId; + } } } diff --git a/Storage/Storage/LCUserAuthDataLoginOption.cs b/Storage/Storage/LCUserAuthDataLoginOption.cs index 564fed9..e4541ef 100644 --- a/Storage/Storage/LCUserAuthDataLoginOption.cs +++ b/Storage/Storage/LCUserAuthDataLoginOption.cs @@ -1,7 +1,33 @@ -using System; +/// +/// 第三方登录选项 +/// namespace LeanCloud.Storage { public class LCUserAuthDataLoginOption { + /// + /// Union Id 平台 + /// + public string UnionIdPlatform { + get; set; + } + + /// + /// 是否作为主账号 + /// + public bool AsMainAccount { + get; set; + } + + /// + /// 是否在不存在的情况下返回失败 + /// + public bool FailOnNotExist { + get; set; + } + public LCUserAuthDataLoginOption() { + UnionIdPlatform = "weixin"; + AsMainAccount = false; + FailOnNotExist = false; } } }