chore: 简化 AVUser
parent
c303a5d307
commit
e68a13590a
|
@ -5,14 +5,14 @@ using System.Net.Http;
|
|||
|
||||
namespace LeanCloud.Storage.Internal {
|
||||
public class AVUserController {
|
||||
public async Task<IObjectState> SignUpAsync(IObjectState state, IDictionary<string, IAVFieldOperation> operations, CancellationToken cancellationToken) {
|
||||
public async Task<IObjectState> SignUpAsync(IObjectState state, IDictionary<string, IAVFieldOperation> operations) {
|
||||
var objectJSON = AVObject.ToJSONObjectForSaving(operations);
|
||||
var command = new AVCommand {
|
||||
Path = "classes/_User",
|
||||
Method = HttpMethod.Post,
|
||||
Content = objectJSON
|
||||
};
|
||||
var ret = await AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command, cancellationToken);
|
||||
var ret = await AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command);
|
||||
var serverState = AVObjectCoder.Instance.Decode(ret.Item2, AVDecoder.Instance);
|
||||
serverState = serverState.MutatedClone(mutableClone => {
|
||||
mutableClone.IsNew = true;
|
||||
|
@ -43,7 +43,7 @@ namespace LeanCloud.Storage.Internal {
|
|||
return serverState;
|
||||
}
|
||||
|
||||
public async Task<IObjectState> LogInAsync(string authType, IDictionary<string, object> data, bool failOnNotExist, CancellationToken cancellationToken) {
|
||||
public async Task<IObjectState> LogInAsync(string authType, IDictionary<string, object> data, bool failOnNotExist) {
|
||||
var authData = new Dictionary<string, object> {
|
||||
[authType] = data
|
||||
};
|
||||
|
@ -55,7 +55,7 @@ namespace LeanCloud.Storage.Internal {
|
|||
{ "authData", authData}
|
||||
}
|
||||
};
|
||||
var ret = await AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command, cancellationToken);
|
||||
var ret = await AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command);
|
||||
var serverState = AVObjectCoder.Instance.Decode(ret.Item2, AVDecoder.Instance);
|
||||
serverState = serverState.MutatedClone(mutableClone => {
|
||||
mutableClone.IsNew = ret.Item1 == System.Net.HttpStatusCode.Created;
|
||||
|
|
|
@ -6,8 +6,7 @@ using System.Net.Http;
|
|||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace LeanCloud
|
||||
{
|
||||
namespace LeanCloud {
|
||||
/// <summary>
|
||||
/// AVFile is a local representation of a file that is saved to the LeanCloud.
|
||||
/// </summary>
|
||||
|
@ -24,8 +23,7 @@ namespace LeanCloud
|
|||
/// await obj.SaveAsync();
|
||||
/// </code>
|
||||
/// </example>
|
||||
public partial class AVFile : IJsonConvertible
|
||||
{
|
||||
public partial class AVFile : IJsonConvertible {
|
||||
internal static int objectCounter = 0;
|
||||
internal static readonly object Mutex = new object();
|
||||
private FileState state;
|
||||
|
@ -40,18 +38,15 @@ namespace LeanCloud
|
|||
/// <param name="data">数据流</param>
|
||||
/// <param name="mimeType">文件类型</param>
|
||||
/// <param name="metaData">文件源信息</param>
|
||||
public AVFile(string name, Stream data, string mimeType = null, IDictionary<string, object> metaData = null)
|
||||
{
|
||||
public AVFile(string name, Stream data, string mimeType = null, IDictionary<string, object> metaData = null) {
|
||||
mimeType = mimeType == null ? GetMIMEType(name) : mimeType;
|
||||
state = new FileState
|
||||
{
|
||||
state = new FileState {
|
||||
Name = name,
|
||||
MimeType = mimeType,
|
||||
MetaData = metaData
|
||||
};
|
||||
this.dataStream = data;
|
||||
lock (Mutex)
|
||||
{
|
||||
lock (Mutex) {
|
||||
objectCounter++;
|
||||
state.counter = objectCounter;
|
||||
}
|
||||
|
@ -73,8 +68,7 @@ namespace LeanCloud
|
|||
/// <param name="data">文件流数据</param>
|
||||
/// <param name="mimeType">文件类型</param>
|
||||
public AVFile(string name, Stream data, string mimeType = null)
|
||||
: this(name, data, mimeType, new Dictionary<string, object>())
|
||||
{
|
||||
: this(name, data, mimeType, new Dictionary<string, object>()) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -83,8 +77,7 @@ namespace LeanCloud
|
|||
/// <param name="name">文件名</param>
|
||||
/// <param name="data">文件的 byte[] 数据</param>
|
||||
public AVFile(string name, byte[] data)
|
||||
: this(name, new MemoryStream(data), new Dictionary<string, object>())
|
||||
{
|
||||
: this(name, new MemoryStream(data), new Dictionary<string, object>()) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -95,8 +88,7 @@ namespace LeanCloud
|
|||
/// <param name="data">文件的 byte[] 数据</param>
|
||||
/// <param name="metaData">元数据</param>
|
||||
public AVFile(string name, byte[] data, IDictionary<string, object> metaData)
|
||||
: this(name, new MemoryStream(data), metaData)
|
||||
{
|
||||
: this(name, new MemoryStream(data), metaData) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -107,8 +99,7 @@ namespace LeanCloud
|
|||
/// <param name="data">文件的数据流</param>
|
||||
/// <param name="metaData">元数据</param>
|
||||
public AVFile(string name, Stream data, IDictionary<string, object> metaData)
|
||||
: this(name, data, GetMIMEType(name), metaData)
|
||||
{
|
||||
: this(name, data, GetMIMEType(name), metaData) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -117,8 +108,7 @@ namespace LeanCloud
|
|||
/// <param name="name">文件名</param>
|
||||
/// <param name="data">文件的数据流</param>
|
||||
public AVFile(string name, Stream data)
|
||||
: this(name, data, new Dictionary<string, object>())
|
||||
{
|
||||
: this(name, data, new Dictionary<string, object>()) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -130,18 +120,15 @@ namespace LeanCloud
|
|||
/// <param name="uri">文件Uri</param>
|
||||
/// <param name="mimeType">文件类型</param>
|
||||
/// <param name="metaData">文件源信息</param>
|
||||
public AVFile(string name, Uri uri, string mimeType = null, IDictionary<string, object> metaData = null)
|
||||
{
|
||||
public AVFile(string name, Uri uri, string mimeType = null, IDictionary<string, object> metaData = null) {
|
||||
mimeType = mimeType == null ? GetMIMEType(name) : mimeType;
|
||||
state = new FileState
|
||||
{
|
||||
state = new FileState {
|
||||
Name = name,
|
||||
Url = uri,
|
||||
MetaData = metaData,
|
||||
MimeType = mimeType
|
||||
};
|
||||
lock (Mutex)
|
||||
{
|
||||
lock (Mutex) {
|
||||
objectCounter++;
|
||||
state.counter = objectCounter;
|
||||
}
|
||||
|
@ -156,8 +143,7 @@ namespace LeanCloud
|
|||
/// <param name="mimeType">文件类型</param>
|
||||
/// <param name="metaData">文件源信息</param>
|
||||
public AVFile(string name, string url, string mimeType = null, IDictionary<string, object> metaData = null)
|
||||
: this(name, new Uri(url), mimeType, metaData)
|
||||
{
|
||||
: this(name, new Uri(url), mimeType, metaData) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -168,8 +154,7 @@ namespace LeanCloud
|
|||
/// <param name="url">文件 Url</param>
|
||||
/// <param name="metaData">文件源信息</param>
|
||||
public AVFile(string name, string url, IDictionary<string, object> metaData)
|
||||
: this(name, url, null, metaData)
|
||||
{
|
||||
: this(name, url, null, metaData) {
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -179,8 +164,7 @@ namespace LeanCloud
|
|||
/// <param name="uri">文件 Uri</param>
|
||||
/// <param name="mimeType">文件类型</param>
|
||||
public AVFile(string name, Uri uri, string mimeType = null)
|
||||
: this(name, uri, mimeType, new Dictionary<string, object>())
|
||||
{
|
||||
: this(name, uri, mimeType, new Dictionary<string, object>()) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -190,8 +174,7 @@ namespace LeanCloud
|
|||
/// <param name="name">文件名</param>
|
||||
/// <param name="uri">文件 Uri</param>
|
||||
public AVFile(string name, Uri uri)
|
||||
: this(name, uri, null, new Dictionary<string, object>())
|
||||
{
|
||||
: this(name, uri, null, new Dictionary<string, object>()) {
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
|
@ -200,20 +183,16 @@ namespace LeanCloud
|
|||
/// <param name="name">文件名</param>
|
||||
/// <param name="url">文件的 Url</param>
|
||||
public AVFile(string name, string url)
|
||||
: this(name, new Uri(url))
|
||||
{
|
||||
: this(name, new Uri(url)) {
|
||||
}
|
||||
|
||||
internal AVFile(FileState filestate)
|
||||
{
|
||||
internal AVFile(FileState filestate) {
|
||||
this.state = filestate;
|
||||
}
|
||||
internal AVFile(string objectId)
|
||||
: this(new FileState()
|
||||
{
|
||||
: this(new FileState() {
|
||||
ObjectId = objectId
|
||||
})
|
||||
{
|
||||
}) {
|
||||
|
||||
}
|
||||
#endregion
|
||||
|
@ -225,10 +204,8 @@ namespace LeanCloud
|
|||
/// <summary>
|
||||
/// Gets whether the file still needs to be saved.
|
||||
/// </summary>
|
||||
public bool IsDirty
|
||||
{
|
||||
get
|
||||
{
|
||||
public bool IsDirty {
|
||||
get {
|
||||
return state.Url == null;
|
||||
}
|
||||
}
|
||||
|
@ -238,10 +215,8 @@ namespace LeanCloud
|
|||
/// the user. After save is called, that name gets prefixed with a unique identifier.
|
||||
/// </summary>
|
||||
[AVFieldName("name")]
|
||||
public string Name
|
||||
{
|
||||
get
|
||||
{
|
||||
public string Name {
|
||||
get {
|
||||
return state.Name;
|
||||
}
|
||||
}
|
||||
|
@ -251,10 +226,8 @@ namespace LeanCloud
|
|||
/// inferred from the file extension. "unknown/unknown" will be used if neither is
|
||||
/// available.
|
||||
/// </summary>
|
||||
public string MimeType
|
||||
{
|
||||
get
|
||||
{
|
||||
public string MimeType {
|
||||
get {
|
||||
return state.MimeType;
|
||||
}
|
||||
}
|
||||
|
@ -264,28 +237,22 @@ namespace LeanCloud
|
|||
/// you get the file from a <see cref="AVObject"/>.
|
||||
/// </summary>
|
||||
[AVFieldName("url")]
|
||||
public Uri Url
|
||||
{
|
||||
get
|
||||
{
|
||||
public Uri Url {
|
||||
get {
|
||||
return state.Url;
|
||||
}
|
||||
}
|
||||
|
||||
internal static AVFileController FileController
|
||||
{
|
||||
get
|
||||
{
|
||||
internal static AVFileController FileController {
|
||||
get {
|
||||
return AVPlugins.Instance.FileController;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
IDictionary<string, object> IJsonConvertible.ToJSON()
|
||||
{
|
||||
if (this.IsDirty)
|
||||
{
|
||||
IDictionary<string, object> IJsonConvertible.ToJSON() {
|
||||
if (this.IsDirty) {
|
||||
throw new InvalidOperationException(
|
||||
"AVFile must be saved before it can be serialized.");
|
||||
}
|
||||
|
@ -302,8 +269,7 @@ namespace LeanCloud
|
|||
/// <summary>
|
||||
/// Saves the file to the LeanCloud cloud.
|
||||
/// </summary>
|
||||
public Task SaveAsync()
|
||||
{
|
||||
public Task SaveAsync() {
|
||||
return SaveAsync(null, CancellationToken.None);
|
||||
}
|
||||
|
||||
|
@ -311,8 +277,7 @@ namespace LeanCloud
|
|||
/// Saves the file to the LeanCloud cloud.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
public Task SaveAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
public Task SaveAsync(CancellationToken cancellationToken) {
|
||||
return SaveAsync(null, cancellationToken);
|
||||
}
|
||||
|
||||
|
@ -320,8 +285,7 @@ namespace LeanCloud
|
|||
/// Saves the file to the LeanCloud cloud.
|
||||
/// </summary>
|
||||
/// <param name="progress">The progress callback.</param>
|
||||
public Task SaveAsync(IProgress<AVUploadProgressEventArgs> progress)
|
||||
{
|
||||
public Task SaveAsync(IProgress<AVUploadProgressEventArgs> progress) {
|
||||
return SaveAsync(progress, CancellationToken.None);
|
||||
}
|
||||
|
||||
|
@ -331,21 +295,18 @@ namespace LeanCloud
|
|||
/// <param name="progress">The progress callback.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
public Task SaveAsync(IProgress<AVUploadProgressEventArgs> progress,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
CancellationToken cancellationToken) {
|
||||
if (this.isExternal)
|
||||
return this.SaveExternal();
|
||||
|
||||
return taskQueue.Enqueue(
|
||||
toAwait => FileController.SaveAsync(state, dataStream, AVUser.CurrentUser.SessionToken, progress, cancellationToken), cancellationToken)
|
||||
.OnSuccess(t =>
|
||||
{
|
||||
.OnSuccess(t => {
|
||||
state = t.Result;
|
||||
});
|
||||
}
|
||||
|
||||
internal Task SaveExternal()
|
||||
{
|
||||
internal Task SaveExternal() {
|
||||
Dictionary<string, object> strs = new Dictionary<string, object>()
|
||||
{
|
||||
{ "url", this.Url.ToString() },
|
||||
|
@ -369,8 +330,7 @@ namespace LeanCloud
|
|||
};
|
||||
}
|
||||
|
||||
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(cmd).OnSuccess(t =>
|
||||
{
|
||||
return AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(cmd).OnSuccess(t => {
|
||||
var result = t.Result.Item2;
|
||||
state.ObjectId = result["objectId"].ToString();
|
||||
});
|
||||
|
@ -385,13 +345,10 @@ namespace LeanCloud
|
|||
/// <summary>
|
||||
/// 文件在 LeanCloud 的唯一Id 标识
|
||||
/// </summary>
|
||||
public string ObjectId
|
||||
{
|
||||
get
|
||||
{
|
||||
public string ObjectId {
|
||||
get {
|
||||
String str;
|
||||
lock (this.mutex)
|
||||
{
|
||||
lock (this.mutex) {
|
||||
str = state.ObjectId;
|
||||
}
|
||||
return str;
|
||||
|
@ -401,10 +358,8 @@ namespace LeanCloud
|
|||
/// <summary>
|
||||
/// 文件的元数据。
|
||||
/// </summary>
|
||||
public IDictionary<string, object> MetaData
|
||||
{
|
||||
get
|
||||
{
|
||||
public IDictionary<string, object> MetaData {
|
||||
get {
|
||||
return state.MetaData;
|
||||
}
|
||||
}
|
||||
|
@ -414,16 +369,13 @@ namespace LeanCloud
|
|||
/// </summary>
|
||||
/// <value>
|
||||
/// </value>
|
||||
public bool IsExternal
|
||||
{
|
||||
get
|
||||
{
|
||||
public bool IsExternal {
|
||||
get {
|
||||
return isExternal;
|
||||
}
|
||||
}
|
||||
|
||||
static AVFile()
|
||||
{
|
||||
static AVFile() {
|
||||
Dictionary<string, string> strs = new Dictionary<string, string>()
|
||||
{
|
||||
{ "ai", "application/postscript" },
|
||||
|
@ -617,19 +569,14 @@ namespace LeanCloud
|
|||
};
|
||||
AVFile.MIMETypesDictionary = strs;
|
||||
}
|
||||
internal static string GetMIMEType(string fileName)
|
||||
{
|
||||
try
|
||||
{
|
||||
internal static string GetMIMEType(string fileName) {
|
||||
try {
|
||||
string str = Path.GetExtension(fileName).Remove(0, 1);
|
||||
if (!AVFile.MIMETypesDictionary.ContainsKey(str))
|
||||
{
|
||||
if (!AVFile.MIMETypesDictionary.ContainsKey(str)) {
|
||||
return "unknown/unknown";
|
||||
}
|
||||
return AVFile.MIMETypesDictionary[str];
|
||||
}
|
||||
catch
|
||||
{
|
||||
} catch {
|
||||
return "unknown/unknown";
|
||||
}
|
||||
}
|
||||
|
@ -639,28 +586,23 @@ namespace LeanCloud
|
|||
/// </summary>
|
||||
/// <remarks>获取之后并没有实际执行下载,只是加载了文件的元信息以及物理地址(Url)
|
||||
/// </remarks>
|
||||
public static Task<AVFile> GetFileWithObjectIdAsync(string objectId, CancellationToken cancellationToken)
|
||||
{
|
||||
public static Task<AVFile> GetFileWithObjectIdAsync(string objectId, CancellationToken cancellationToken) {
|
||||
string currentSessionToken = AVUser.CurrentUser.SessionToken;
|
||||
return FileController.GetAsync(objectId, currentSessionToken, cancellationToken).OnSuccess(_ =>
|
||||
{
|
||||
return FileController.GetAsync(objectId, currentSessionToken, cancellationToken).OnSuccess(_ => {
|
||||
var filestate = _.Result;
|
||||
return new AVFile(filestate);
|
||||
});
|
||||
}
|
||||
|
||||
public static AVFile CreateWithoutData(string objectId)
|
||||
{
|
||||
public static AVFile CreateWithoutData(string objectId) {
|
||||
return new AVFile(objectId);
|
||||
}
|
||||
|
||||
public static AVFile CreateWithState(FileState state)
|
||||
{
|
||||
public static AVFile CreateWithState(FileState state) {
|
||||
return new AVFile(state);
|
||||
}
|
||||
|
||||
public static AVFile CreateWithData(string objectId,string name, string url,IDictionary<string,object> metaData)
|
||||
{
|
||||
public static AVFile CreateWithData(string objectId, string name, string url, IDictionary<string, object> metaData) {
|
||||
var fileState = new FileState();
|
||||
fileState.Name = name;
|
||||
fileState.ObjectId = objectId;
|
||||
|
@ -673,23 +615,18 @@ namespace LeanCloud
|
|||
/// </summary>
|
||||
/// <remarks>获取之后并没有实际执行下载,只是加载了文件的元信息以及物理地址(Url)
|
||||
/// </remarks>
|
||||
public static Task<AVFile> GetFileWithObjectIdAsync(string objectId)
|
||||
{
|
||||
public static Task<AVFile> GetFileWithObjectIdAsync(string objectId) {
|
||||
return GetFileWithObjectIdAsync(objectId, CancellationToken.None);
|
||||
}
|
||||
|
||||
internal void MergeFromJSON(IDictionary<string, object> jsonData)
|
||||
{
|
||||
lock (this.mutex)
|
||||
{
|
||||
internal void MergeFromJSON(IDictionary<string, object> jsonData) {
|
||||
lock (this.mutex) {
|
||||
state.ObjectId = jsonData["objectId"] as string;
|
||||
state.Url = new Uri(jsonData["url"] as string, UriKind.Absolute);
|
||||
if (jsonData.ContainsKey("name"))
|
||||
{
|
||||
if (jsonData.ContainsKey("name")) {
|
||||
state.Name = jsonData["name"] as string;
|
||||
}
|
||||
if (jsonData.ContainsKey("metaData"))
|
||||
{
|
||||
if (jsonData.ContainsKey("metaData")) {
|
||||
state.MetaData = jsonData["metaData"] as Dictionary<string, object>;
|
||||
}
|
||||
|
||||
|
@ -700,32 +637,25 @@ namespace LeanCloud
|
|||
/// 删除文件
|
||||
/// </summary>
|
||||
/// <returns>Task</returns>
|
||||
public Task DeleteAsync()
|
||||
{
|
||||
public Task DeleteAsync() {
|
||||
return DeleteAsync(CancellationToken.None);
|
||||
}
|
||||
internal Task DeleteAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
internal Task DeleteAsync(CancellationToken cancellationToken) {
|
||||
return taskQueue.Enqueue(toAwait => DeleteAsync(toAwait, cancellationToken),
|
||||
cancellationToken);
|
||||
|
||||
}
|
||||
internal Task DeleteAsync(Task toAwait, CancellationToken cancellationToken)
|
||||
{
|
||||
if (ObjectId == null)
|
||||
{
|
||||
internal Task DeleteAsync(Task toAwait, CancellationToken cancellationToken) {
|
||||
if (ObjectId == null) {
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
string sessionToken = AVUser.CurrentUser.SessionToken;
|
||||
|
||||
return toAwait.OnSuccess(_ =>
|
||||
{
|
||||
return toAwait.OnSuccess(_ => {
|
||||
return FileController.DeleteAsync(state, sessionToken, cancellationToken);
|
||||
}).Unwrap().OnSuccess(_ => { });
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ namespace LeanCloud {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 手机号。
|
||||
/// 手机号
|
||||
/// </summary>
|
||||
[AVFieldName("mobilePhoneNumber")]
|
||||
public string MobilePhoneNumber {
|
||||
|
@ -143,29 +143,31 @@ namespace LeanCloud {
|
|||
}
|
||||
}
|
||||
|
||||
internal async Task SignUpAsync(Task toAwait, CancellationToken cancellationToken) {
|
||||
await Create(toAwait, cancellationToken);
|
||||
CurrentUser = this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Signs up a new user. This will create a new AVUser on the server and will also persist the
|
||||
/// session on disk so that you can access the user using <see cref="CurrentUser"/>. A username and
|
||||
/// password must be set before calling SignUpAsync.
|
||||
/// 注册新用户,注册成功后将保存为当前用户。必须设置用户名和密码。
|
||||
/// </summary>
|
||||
public Task SignUpAsync() {
|
||||
return SignUpAsync(CancellationToken.None);
|
||||
}
|
||||
/// <returns></returns>
|
||||
public async Task SignUpAsync() {
|
||||
if (AuthData == null) {
|
||||
if (string.IsNullOrEmpty(Username)) {
|
||||
throw new InvalidOperationException("Cannot sign up user with an empty name.");
|
||||
}
|
||||
if (string.IsNullOrEmpty(Password)) {
|
||||
throw new InvalidOperationException("Cannot sign up user with an empty password.");
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(ObjectId)) {
|
||||
throw new InvalidOperationException("Cannot sign up a user that already exists.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Signs up a new user. This will create a new AVUser on the server and will also persist the
|
||||
/// session on disk so that you can access the user using <see cref="CurrentUser"/>. A username and
|
||||
/// password must be set before calling SignUpAsync.
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
public Task SignUpAsync(CancellationToken cancellationToken) {
|
||||
return taskQueue.Enqueue(toAwait => SignUpAsync(toAwait, cancellationToken),
|
||||
cancellationToken);
|
||||
IDictionary<string, IAVFieldOperation> currentOperations = StartSave();
|
||||
try {
|
||||
var serverState = await UserController.SignUpAsync(State, currentOperations);
|
||||
HandleSave(serverState);
|
||||
CurrentUser = this;
|
||||
} catch (Exception) {
|
||||
HandleFailedSave(currentOperations);
|
||||
}
|
||||
}
|
||||
|
||||
#region 事件流系统相关 API
|
||||
|
@ -187,7 +189,7 @@ namespace LeanCloud {
|
|||
/// <returns></returns>
|
||||
public Task FollowAsync(string userObjectId, IDictionary<string, object> data) {
|
||||
if (data != null) {
|
||||
data = this.EncodeForSaving(data);
|
||||
data = EncodeForSaving(data);
|
||||
}
|
||||
var command = new AVCommand {
|
||||
Path = $"users/{ObjectId}/friendship/{userObjectId}",
|
||||
|
@ -329,21 +331,19 @@ namespace LeanCloud {
|
|||
/// <summary>
|
||||
/// 更新用户的密码,需要用户的旧密码
|
||||
/// </summary>
|
||||
/// <param name="oldPassword">Old password.</param>
|
||||
/// <param name="newPassword">New password.</param>
|
||||
/// <param name="oldPassword">旧密码</param>
|
||||
/// <param name="newPassword">新密码</param>
|
||||
public async Task UpdatePasswordAsync(string oldPassword, string newPassword) {
|
||||
IObjectState state = await UserController.UpdatePasswordAsync(ObjectId, oldPassword, newPassword);
|
||||
HandleFetchResult(state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the authData for this user.
|
||||
/// 用户数据
|
||||
/// </summary>
|
||||
internal IDictionary<string, IDictionary<string, object>> AuthData {
|
||||
get {
|
||||
IDictionary<string, IDictionary<string, object>> authData;
|
||||
if (this.TryGetValue<IDictionary<string, IDictionary<string, object>>>(
|
||||
"authData", out authData)) {
|
||||
if (TryGetValue("authData", out IDictionary<string, IDictionary<string, object>> authData)) {
|
||||
return authData;
|
||||
}
|
||||
return null;
|
||||
|
@ -354,8 +354,7 @@ namespace LeanCloud {
|
|||
}
|
||||
|
||||
private static IAVAuthenticationProvider GetProvider(string providerName) {
|
||||
IAVAuthenticationProvider provider;
|
||||
if (authProviders.TryGetValue(providerName, out provider)) {
|
||||
if (authProviders.TryGetValue(providerName, out IAVAuthenticationProvider provider)) {
|
||||
return provider;
|
||||
}
|
||||
return null;
|
||||
|
@ -407,29 +406,27 @@ namespace LeanCloud {
|
|||
if (authData == null || provider == null) {
|
||||
return;
|
||||
}
|
||||
IDictionary<string, object> data;
|
||||
if (authData.TryGetValue(provider.AuthType, out data)) {
|
||||
if (authData.TryGetValue(provider.AuthType, out IDictionary<string, object> data)) {
|
||||
restorationSuccess = provider.RestoreAuthentication(data);
|
||||
}
|
||||
}
|
||||
|
||||
if (!restorationSuccess) {
|
||||
this.UnlinkFromAsync(provider.AuthType, CancellationToken.None);
|
||||
UnlinkFromAsync(provider.AuthType, CancellationToken.None);
|
||||
}
|
||||
}
|
||||
|
||||
public Task LinkWithAsync(string authType, IDictionary<string, object> data, CancellationToken cancellationToken) {
|
||||
return taskQueue.Enqueue(toAwait => {
|
||||
AuthData = new Dictionary<string, IDictionary<string, object>>();
|
||||
AuthData[authType] = data;
|
||||
return SaveAsync(cancellationToken);
|
||||
}, cancellationToken);
|
||||
public Task LinkWithAsync(string authType, IDictionary<string, object> data) {
|
||||
AuthData = new Dictionary<string, IDictionary<string, object>> {
|
||||
[authType] = data
|
||||
};
|
||||
return SaveAsync();
|
||||
}
|
||||
|
||||
public Task LinkWithAsync(string authType, CancellationToken cancellationToken) {
|
||||
var provider = GetProvider(authType);
|
||||
return provider.AuthenticateAsync(cancellationToken)
|
||||
.OnSuccess(t => LinkWithAsync(authType, t.Result, cancellationToken))
|
||||
.OnSuccess(t => LinkWithAsync(authType, t.Result))
|
||||
.Unwrap();
|
||||
}
|
||||
|
||||
|
@ -437,7 +434,7 @@ namespace LeanCloud {
|
|||
/// Unlinks a user from a service.
|
||||
/// </summary>
|
||||
public Task UnlinkFromAsync(string authType, CancellationToken cancellationToken) {
|
||||
return LinkWithAsync(authType, null, cancellationToken);
|
||||
return LinkWithAsync(authType, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -449,12 +446,8 @@ namespace LeanCloud {
|
|||
}
|
||||
}
|
||||
|
||||
internal static async Task<AVUser> LogInWithAsync(string authType,
|
||||
IDictionary<string, object> data,
|
||||
bool failOnNotExist,
|
||||
CancellationToken cancellationToken) {
|
||||
|
||||
var ret = await UserController.LogInAsync(authType, data, failOnNotExist, cancellationToken);
|
||||
internal static async Task<AVUser> LogInWithAsync(string authType, IDictionary<string, object> data, bool failOnNotExist) {
|
||||
var ret = await UserController.LogInAsync(authType, data, failOnNotExist);
|
||||
AVUser user = FromState<AVUser>(ret, "_User");
|
||||
user.AuthData = new Dictionary<string, IDictionary<string, object>>();
|
||||
user.AuthData[authType] = data;
|
||||
|
@ -463,17 +456,16 @@ namespace LeanCloud {
|
|||
return CurrentUser;
|
||||
}
|
||||
|
||||
internal static Task<AVUser> LogInWithAsync(string authType,
|
||||
CancellationToken cancellationToken) {
|
||||
internal static Task<AVUser> LogInWithAsync(string authType) {
|
||||
var provider = GetProvider(authType);
|
||||
return provider.AuthenticateAsync(cancellationToken)
|
||||
.OnSuccess(authData => LogInWithAsync(authType, authData.Result, false, cancellationToken))
|
||||
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 = AVUser.CurrentUser;
|
||||
var curUser = CurrentUser;
|
||||
if (curUser != null) {
|
||||
curUser.SynchronizeAuthData(provider);
|
||||
}
|
||||
|
@ -482,8 +474,8 @@ namespace LeanCloud {
|
|||
#region 手机号登录
|
||||
|
||||
internal static async Task<AVUser> LogInWithParametersAsync(Dictionary<string, object> strs) {
|
||||
var ret = await UserController.LogInWithParametersAsync("login", strs);
|
||||
var user = CreateWithoutData<AVUser>(null);
|
||||
IObjectState ret = await UserController.LogInWithParametersAsync("login", strs);
|
||||
AVUser user = CreateWithoutData<AVUser>(null);
|
||||
user.HandleFetchResult(ret);
|
||||
CurrentUser = user;
|
||||
return CurrentUser;
|
||||
|
@ -523,7 +515,7 @@ namespace LeanCloud {
|
|||
/// <param name="mobilePhoneNumber">手机号</param>
|
||||
/// <param name="smsCode">短信验证码</param>
|
||||
/// <returns></returns>
|
||||
public static Task<AVUser> LogInBySmsCodeAsync(string mobilePhoneNumber, string smsCode) {
|
||||
public static Task<AVUser> LogInByMobilePhoneNumberSmsCodeAsync(string mobilePhoneNumber, string smsCode) {
|
||||
Dictionary<string, object> strs = new Dictionary<string, object> {
|
||||
{ "mobilePhoneNumber", mobilePhoneNumber },
|
||||
{ "smsCode", smsCode }
|
||||
|
@ -532,44 +524,13 @@ namespace LeanCloud {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests the login SMS code asynchronous.
|
||||
/// 请求登录短信验证码
|
||||
/// </summary>
|
||||
/// <param name="mobilePhoneNumber">The mobile phone number.</param>
|
||||
/// <returns></returns>
|
||||
public static Task RequestLogInSmsCodeAsync(string mobilePhoneNumber) {
|
||||
return RequestLogInSmsCodeAsync(mobilePhoneNumber, CancellationToken.None);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests the login SMS code asynchronous.
|
||||
/// </summary>
|
||||
/// <param name="mobilePhoneNumber">The mobile phone number.</param>
|
||||
/// <param name="validateToken">Validate token.</param>
|
||||
/// <param name="mobilePhoneNumber">手机号</param>
|
||||
/// <param name="validateToken">验证码</param>
|
||||
/// <returns></returns>
|
||||
public static Task RequestLogInSmsCodeAsync(string mobilePhoneNumber, string validateToken) {
|
||||
return RequestLogInSmsCodeAsync(mobilePhoneNumber, null, CancellationToken.None);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests the login SMS code asynchronous.
|
||||
/// </summary>
|
||||
/// <param name="mobilePhoneNumber">The mobile phone number.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
public static Task RequestLogInSmsCodeAsync(string mobilePhoneNumber, CancellationToken cancellationToken) {
|
||||
return RequestLogInSmsCodeAsync(mobilePhoneNumber, null, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Requests the login SMS code asynchronous.
|
||||
/// </summary>
|
||||
/// <param name="mobilePhoneNumber">The mobile phone number.</param>
|
||||
/// <param name="validateToken">Validate token.</param>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <returns></returns>
|
||||
public static Task RequestLogInSmsCodeAsync(string mobilePhoneNumber, string validateToken, CancellationToken cancellationToken) {
|
||||
Dictionary<string, object> strs = new Dictionary<string, object>()
|
||||
{
|
||||
Dictionary<string, object> strs = new Dictionary<string, object> {
|
||||
{ "mobilePhoneNumber", mobilePhoneNumber },
|
||||
};
|
||||
if (String.IsNullOrEmpty(validateToken)) {
|
||||
|
@ -603,87 +564,15 @@ namespace LeanCloud {
|
|||
|
||||
#endregion
|
||||
|
||||
#region 手机短信
|
||||
|
||||
/// <summary>
|
||||
/// Send sign up sms code async.
|
||||
/// </summary>
|
||||
/// <returns>The sign up sms code async.</returns>
|
||||
/// <param name="mobilePhoneNumber">Mobile phone number.</param>
|
||||
public static Task SendSignUpSmsCodeAsync(string mobilePhoneNumber) {
|
||||
return AVCloud.RequestSMSCodeAsync(mobilePhoneNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sign up by mobile phone async.
|
||||
/// </summary>
|
||||
/// <returns>The up by mobile phone async.</returns>
|
||||
/// <param name="mobilePhoneNumber">Mobile phone number.</param>
|
||||
/// <param name="smsCode">Sms code.</param>
|
||||
public static Task<AVUser> SignUpByMobilePhoneAsync(string mobilePhoneNumber, string smsCode) {
|
||||
return SignUpOrLogInByMobilePhoneAsync(mobilePhoneNumber, smsCode);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Send log in sms code async.
|
||||
/// </summary>
|
||||
/// <returns>The log in sms code async.</returns>
|
||||
/// <param name="mobilePhoneNumber">Mobile phone number.</param>
|
||||
public static Task SendLogInSmsCodeAsync(string mobilePhoneNumber) {
|
||||
return RequestLogInSmsCodeAsync(mobilePhoneNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log in by mobile phone async.
|
||||
/// </summary>
|
||||
/// <returns>The in by mobile phone async.</returns>
|
||||
/// <param name="mobilePhoneNumber">Mobile phone number.</param>
|
||||
/// <param name="smsCode">Sms code.</param>
|
||||
public static Task<AVUser> LogInByMobilePhoneAsync(string mobilePhoneNumber, string smsCode) {
|
||||
return LogInBySmsCodeAsync(mobilePhoneNumber, smsCode);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region 重置密码
|
||||
|
||||
/// <summary>
|
||||
/// 请求重置密码,需要传入注册时使用的手机号。
|
||||
/// </summary>
|
||||
/// <param name="mobilePhoneNumber">注册时使用的手机号</param>
|
||||
/// <param name="validateToken">图形验证码</param>
|
||||
/// <returns></returns>
|
||||
public static Task RequestPasswordResetBySmsCode(string mobilePhoneNumber) {
|
||||
return RequestPasswordResetBySmsCode(mobilePhoneNumber, null, CancellationToken.None);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 请求重置密码,需要传入注册时使用的手机号。
|
||||
/// </summary>
|
||||
/// <param name="mobilePhoneNumber">注册时使用的手机号</param>
|
||||
/// <param name="cancellationToken">cancellationToken</param>
|
||||
/// <returns></returns>
|
||||
public static Task RequestPasswordResetBySmsCode(string mobilePhoneNumber, CancellationToken cancellationToken) {
|
||||
return RequestPasswordResetBySmsCode(mobilePhoneNumber, null, cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 请求重置密码,需要传入注册时使用的手机号。
|
||||
/// </summary>
|
||||
/// <param name="mobilePhoneNumber">注册时使用的手机号</param>
|
||||
/// <param name="validateToken">Validate token.</param>
|
||||
/// <returns></returns>
|
||||
public static Task RequestPasswordResetBySmsCode(string mobilePhoneNumber, string validateToken) {
|
||||
return RequestPasswordResetBySmsCode(mobilePhoneNumber, validateToken, CancellationToken.None);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 请求重置密码,需要传入注册时使用的手机号。
|
||||
/// </summary>
|
||||
/// <param name="mobilePhoneNumber">注册时使用的手机号</param>
|
||||
/// <param name="validateToken">Validate token.</param>
|
||||
/// <param name="cancellationToken">cancellationToken</param>
|
||||
/// <returns></returns>
|
||||
public static Task RequestPasswordResetBySmsCode(string mobilePhoneNumber, string validateToken, CancellationToken cancellationToken) {
|
||||
public static Task RequestPasswordResetBySmsCode(string mobilePhoneNumber, string validateToken = null) {
|
||||
Dictionary<string, object> strs = new Dictionary<string, object> {
|
||||
{ "mobilePhoneNumber", mobilePhoneNumber },
|
||||
};
|
||||
|
@ -702,20 +591,9 @@ namespace LeanCloud {
|
|||
/// 通过验证码重置密码。
|
||||
/// </summary>
|
||||
/// <param name="newPassword">新密码</param>
|
||||
/// <param name="smsCode">6位数验证码</param>
|
||||
/// <param name="smsCode">6 位数验证码</param>
|
||||
/// <returns></returns>
|
||||
public static Task ResetPasswordBySmsCodeAsync(string newPassword, string smsCode) {
|
||||
return ResetPasswordBySmsCodeAsync(newPassword, smsCode, CancellationToken.None);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过验证码重置密码。
|
||||
/// </summary>
|
||||
/// <param name="newPassword">新密码</param>
|
||||
/// <param name="smsCode">6位数验证码</param>
|
||||
/// <param name="cancellationToken">cancellationToken</param>
|
||||
/// <returns></returns>
|
||||
public static Task ResetPasswordBySmsCodeAsync(string newPassword, string smsCode, CancellationToken cancellationToken) {
|
||||
Dictionary<string, object> strs = new Dictionary<string, object> {
|
||||
{ "password", newPassword }
|
||||
};
|
||||
|
@ -786,53 +664,6 @@ namespace LeanCloud {
|
|||
|
||||
#endregion
|
||||
|
||||
#region in no-local-storage enviroment
|
||||
|
||||
internal Task Create() {
|
||||
return this.Create(CancellationToken.None);
|
||||
}
|
||||
internal Task Create(CancellationToken cancellationToken) {
|
||||
return taskQueue.Enqueue(toAwait => Create(toAwait, cancellationToken),
|
||||
cancellationToken);
|
||||
}
|
||||
|
||||
internal Task Create(Task toAwait, CancellationToken cancellationToken) {
|
||||
if (AuthData == null) {
|
||||
// TODO (hallucinogen): make an Extension of Task to create Task with exception/canceled.
|
||||
if (string.IsNullOrEmpty(Username)) {
|
||||
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
|
||||
tcs.TrySetException(new InvalidOperationException("Cannot sign up user with an empty name."));
|
||||
return tcs.Task;
|
||||
}
|
||||
if (string.IsNullOrEmpty(Password)) {
|
||||
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
|
||||
tcs.TrySetException(new InvalidOperationException("Cannot sign up user with an empty password."));
|
||||
return tcs.Task;
|
||||
}
|
||||
}
|
||||
if (!string.IsNullOrEmpty(ObjectId)) {
|
||||
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
|
||||
tcs.TrySetException(new InvalidOperationException("Cannot sign up a user that already exists."));
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
IDictionary<string, IAVFieldOperation> currentOperations = StartSave();
|
||||
|
||||
return toAwait.OnSuccess(_ => {
|
||||
return UserController.SignUpAsync(State, currentOperations, cancellationToken);
|
||||
}).Unwrap().ContinueWith(t => {
|
||||
if (t.IsFaulted || t.IsCanceled) {
|
||||
HandleFailedSave(currentOperations);
|
||||
} else {
|
||||
var serverState = t.Result;
|
||||
HandleSave(serverState);
|
||||
}
|
||||
return t;
|
||||
}).Unwrap();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region AVUser Extension
|
||||
|
||||
public IDictionary<string, IDictionary<string, object>> GetAuthData() {
|
||||
|
@ -844,42 +675,32 @@ namespace LeanCloud {
|
|||
/// </summary>
|
||||
/// <param name="data">OAuth data, like {"accessToken":"xxxxxx"}</param>
|
||||
/// <param name="platform">auth platform,maybe "facebook"/"twiiter"/"weibo"/"weixin" .etc</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public static Task<AVUser> LogInWithAuthDataAsync(IDictionary<string, object> data,
|
||||
string platform,
|
||||
AVUserAuthDataLogInOption options = null,
|
||||
CancellationToken cancellationToken = default(System.Threading.CancellationToken)) {
|
||||
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, cancellationToken);
|
||||
return LogInWithAsync(platform, data, options.FailOnNotExist);
|
||||
}
|
||||
|
||||
public static Task<AVUser> LogInWithAuthDataAndUnionIdAsync(
|
||||
IDictionary<string, object> authData,
|
||||
string platform,
|
||||
string unionId,
|
||||
AVUserAuthDataLogInOption options = null,
|
||||
CancellationToken cancellationToken = default(System.Threading.CancellationToken)) {
|
||||
AVUserAuthDataLogInOption options = null) {
|
||||
if (options == null) {
|
||||
options = new AVUserAuthDataLogInOption();
|
||||
}
|
||||
MergeAuthData(authData, unionId, options);
|
||||
return LogInWithAsync(platform, authData, options.FailOnNotExist, cancellationToken);
|
||||
return LogInWithAsync(platform, authData, options.FailOnNotExist);
|
||||
}
|
||||
|
||||
public static Task<AVUser> LogInAnonymouslyAsync(CancellationToken cancellationToken = default(System.Threading.CancellationToken)) {
|
||||
public static Task<AVUser> LogInAnonymouslyAsync() {
|
||||
var data = new Dictionary<string, object> {
|
||||
{ "id", Guid.NewGuid().ToString() }
|
||||
};
|
||||
var options = new AVUserAuthDataLogInOption();
|
||||
return LogInWithAuthDataAsync(data, "anonymous", options, cancellationToken);
|
||||
}
|
||||
|
||||
[Obsolete("please use LogInWithAuthDataAsync instead.")]
|
||||
public static Task<AVUser> LogInWithAsync(string authType, IDictionary<string, object> data, CancellationToken cancellationToken) {
|
||||
return LogInWithAsync(authType, data, false, cancellationToken);
|
||||
return LogInWithAuthDataAsync(data, "anonymous", options);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -887,23 +708,21 @@ namespace LeanCloud {
|
|||
/// </summary>
|
||||
/// <param name="data">OAuth data, like {"accessToken":"xxxxxx"}</param>
|
||||
/// <param name="platform">auth platform,maybe "facebook"/"twiiter"/"weibo"/"weixin" .etc</param>
|
||||
/// <param name="cancellationToken"></param>
|
||||
/// <returns></returns>
|
||||
public Task AssociateAuthDataAsync(IDictionary<string, object> data, string platform, CancellationToken cancellationToken = default(System.Threading.CancellationToken)) {
|
||||
return LinkWithAsync(platform, data, cancellationToken);
|
||||
public Task AssociateAuthDataAsync(IDictionary<string, object> data, string platform) {
|
||||
return LinkWithAsync(platform, data);
|
||||
}
|
||||
|
||||
public Task AssociateAuthDataAndUnionIdAsync(
|
||||
IDictionary<string, object> authData,
|
||||
string platform,
|
||||
string unionId,
|
||||
AVUserAuthDataLogInOption options = null,
|
||||
CancellationToken cancellationToken = default(System.Threading.CancellationToken)) {
|
||||
AVUserAuthDataLogInOption options = null) {
|
||||
if (options == null) {
|
||||
options = new AVUserAuthDataLogInOption();
|
||||
}
|
||||
MergeAuthData(authData, unionId, options);
|
||||
return LinkWithAsync(platform, authData, cancellationToken);
|
||||
return LinkWithAsync(platform, authData);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
Loading…
Reference in New Issue