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; } } }