* AVACL.cs:

* ObjectTest.cs:
* AVObject.cs:
* AVException.cs:
* ObjectControllerTests.cs:

* AVObjectController.cs: chore: AVObject 增加符合条件删除
oneRain 2019-09-23 16:16:04 +08:00
parent d118935f21
commit 68a047ba1e
6 changed files with 420 additions and 422 deletions

View File

@ -1,157 +0,0 @@
using NUnit.Framework;
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
using LeanCloud;
namespace LeanCloud.Test {
public class ObjectControllerTests {
[SetUp]
public void SetUp() {
Utils.InitNorthChina();
}
[Test]
public async Task Save() {
AVObject obj = AVObject.Create("Foo");
obj["content"] = "hello, world";
obj["list"] = new List<int> { 1, 1, 2, 3, 5, 8 };
obj["dict"] = new Dictionary<string, int> {
{ "hello", 1 },
{ "world", 2 }
};
await obj.SaveAsync();
Assert.NotNull(obj.ObjectId);
Assert.NotNull(obj.CreatedAt);
Assert.NotNull(obj.UpdatedAt);
}
[Test]
public async Task SaveWithOptions() {
AVObject account = AVObject.CreateWithoutData("Account", "5d65fa5330863b008065e476");
account["balance"] = 100;
await account.SaveAsync();
AVQuery<AVObject> query = new AVQuery<AVObject>("Account");
query.WhereGreaterThan("balance", 80);
account["balance"] = 50;
await account.SaveAsync(true, query);
TestContext.Out.WriteLine($"balance: {account["balance"]}");
}
[Test]
public async Task SaveWithPointer() {
AVObject comment = new AVObject("Comment") {
{ "content", "Hello, Comment" }
};
AVObject post = new AVObject("Post") {
{ "name", "New Post" },
{ "category", new AVObject("Category") {
{ "name", "new post category" }
} }
};
comment["post"] = post;
AVObject testPost = new AVObject("Post") {
{ "name", "Test Post" },
{ "category", new AVObject("Category") {
{ "name", "test post category" }
} }
};
comment["test_post"] = testPost;
await comment.SaveAsync();
TestContext.Out.WriteLine(post);
TestContext.Out.WriteLine(testPost);
TestContext.Out.WriteLine(comment);
}
[Test]
public async Task SaveBatch() {
List<AVObject> objList = new List<AVObject>();
for (int i = 0; i < 5; i++) {
AVObject obj = AVObject.Create("Foo");
obj["content"] = "batch object";
objList.Add(obj);
}
try {
await objList.SaveAllAsync();
objList.ForEach(obj => {
Assert.NotNull(obj.ObjectId);
});
} catch (Exception e) {
TestContext.Out.WriteLine(e.Message);
}
}
[Test]
public async Task Fetch() {
AVObject obj = AVObject.CreateWithoutData("Todo", "5d5f6039d5de2b006cf29c8f");
await obj.FetchAsync();
Assert.NotNull(obj["title"]);
Assert.NotNull(obj["content"]);
TestContext.Out.WriteLine($"{obj["title"]}, {obj["content"]}");
}
[Test]
public async Task FetchWithKeys() {
AVObject obj = AVObject.CreateWithoutData("Post", "5d3abfa530863b0068e1b326");
await obj.FetchAsync(new List<string> { "pubUser" });
TestContext.Out.WriteLine($"{obj["pubUser"]}");
}
[Test]
public async Task FetchWithIncludes() {
AVObject obj = AVObject.CreateWithoutData("Post", "5d3abfa530863b0068e1b326");
await obj.FetchAsync(includes: new List<string> { "tag" });
AVObject tag = obj["tag"] as AVObject;
TestContext.Out.WriteLine($"{tag["name"]}");
}
[Test]
public async Task FetchAll() {
List<AVObject> objList = new List<AVObject> {
AVObject.CreateWithoutData("Tag", "5d64e5ebc05a8000730340ba"),
AVObject.CreateWithoutData("Tag", "5d64e5eb12215f0073db271c"),
AVObject.CreateWithoutData("Tag", "5d64e57f43e78c0068a14315")
};
await objList.FetchAllAsync();
objList.ForEach(obj => {
Assert.NotNull(obj.ObjectId);
TestContext.Out.WriteLine($"{obj.ObjectId}, {obj["name"]}");
});
}
[Test]
public async Task Delete() {
AVObject obj = AVObject.Create("Foo");
obj["content"] = "hello, world";
await obj.SaveAsync();
Assert.NotNull(obj);
await obj.DeleteAsync();
}
[Test]
public async Task DeleteAll() {
List<AVObject> objList = new List<AVObject>();
for (int i = 0; i < 5; i++) {
AVObject obj = AVObject.Create("Foo");
obj["content"] = "batch object";
objList.Add(obj);
}
await objList.SaveAllAsync();
await AVObject.DeleteAllAsync(objList);
}
[Test]
public async Task Set() {
AVObject obj = AVObject.Create("Foo");
obj["hello"] = "world";
await obj.SaveAsync();
obj["world"] = "aaa";
obj.Revert();
TestContext.Out.WriteAsync(obj["hello"] as string);
}
}
}

View File

@ -1,7 +1,8 @@
using NUnit.Framework; using NUnit.Framework;
using LeanCloud; using System;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Collections.Generic;
namespace LeanCloud.Test { namespace LeanCloud.Test {
public class ObjectTests { public class ObjectTests {
@ -11,22 +12,166 @@ namespace LeanCloud.Test {
} }
[Test] [Test]
public void TestAVObjectConstructor() { public async Task Save() {
AVObject obj = new AVObject("Foo"); AVObject obj = AVObject.Create("Foo");
Assert.AreEqual("Foo", obj.ClassName); obj["content"] = "hello, world";
Assert.Null(obj.CreatedAt); obj["list"] = new List<int> { 1, 1, 2, 3, 5, 8 };
Assert.True(obj.IsDataAvailable); obj["dict"] = new Dictionary<string, int> {
Assert.True(obj.IsDirty); { "hello", 1 },
{ "world", 2 }
};
await obj.SaveAsync();
Assert.NotNull(obj.ObjectId);
Assert.NotNull(obj.CreatedAt);
Assert.NotNull(obj.UpdatedAt);
} }
[Test] [Test]
public void TestAVObjectCreate() { public async Task SaveWithOptions() {
AVObject obj = AVObject.CreateWithoutData("Foo", "5d356b1cd5de2b00837162ca"); AVObject account = AVObject.CreateWithoutData("Account", "5d65fa5330863b008065e476");
Assert.AreEqual("Foo", obj.ClassName); account["balance"] = 100;
Assert.AreEqual("5d356b1cd5de2b00837162ca", obj.ObjectId); await account.SaveAsync();
Assert.Null(obj.CreatedAt); AVQuery<AVObject> query = new AVQuery<AVObject>("Account");
Assert.False(obj.IsDataAvailable); query.WhereGreaterThan("balance", 80);
Assert.False(obj.IsDirty); account["balance"] = 50;
await account.SaveAsync(true, query);
TestContext.Out.WriteLine($"balance: {account["balance"]}");
}
[Test]
public async Task SaveWithPointer() {
AVObject comment = new AVObject("Comment") {
{ "content", "Hello, Comment" }
};
AVObject post = new AVObject("Post") {
{ "name", "New Post" },
{ "category", new AVObject("Category") {
{ "name", "new post category" }
} }
};
comment["post"] = post;
AVObject testPost = new AVObject("Post") {
{ "name", "Test Post" },
{ "category", new AVObject("Category") {
{ "name", "test post category" }
} }
};
comment["test_post"] = testPost;
await comment.SaveAsync();
TestContext.Out.WriteLine(post);
TestContext.Out.WriteLine(testPost);
TestContext.Out.WriteLine(comment);
}
[Test]
public async Task SaveBatch() {
List<AVObject> objList = new List<AVObject>();
for (int i = 0; i < 5; i++) {
AVObject obj = AVObject.Create("Foo");
obj["content"] = "batch object";
objList.Add(obj);
}
try {
await objList.SaveAllAsync();
objList.ForEach(obj => {
Assert.NotNull(obj.ObjectId);
});
} catch (Exception e) {
TestContext.Out.WriteLine(e.Message);
}
}
[Test]
public async Task Fetch() {
AVObject obj = AVObject.CreateWithoutData("Todo", "5d5f6039d5de2b006cf29c8f");
await obj.FetchAsync();
Assert.NotNull(obj["title"]);
Assert.NotNull(obj["content"]);
TestContext.Out.WriteLine($"{obj["title"]}, {obj["content"]}");
}
[Test]
public async Task FetchWithKeys() {
AVObject obj = AVObject.CreateWithoutData("Post", "5d3abfa530863b0068e1b326");
await obj.FetchAsync(new List<string> { "pubUser" });
TestContext.Out.WriteLine($"{obj["pubUser"]}");
}
[Test]
public async Task FetchWithIncludes() {
AVObject obj = AVObject.CreateWithoutData("Post", "5d3abfa530863b0068e1b326");
await obj.FetchAsync(includes: new List<string> { "tag" });
AVObject tag = obj["tag"] as AVObject;
TestContext.Out.WriteLine($"{tag["name"]}");
}
[Test]
public async Task FetchAll() {
List<AVObject> objList = new List<AVObject> {
AVObject.CreateWithoutData("Tag", "5d64e5ebc05a8000730340ba"),
AVObject.CreateWithoutData("Tag", "5d64e5eb12215f0073db271c"),
AVObject.CreateWithoutData("Tag", "5d64e57f43e78c0068a14315")
};
await objList.FetchAllAsync();
objList.ForEach(obj => {
Assert.NotNull(obj.ObjectId);
TestContext.Out.WriteLine($"{obj.ObjectId}, {obj["name"]}");
});
}
[Test]
public async Task Delete() {
AVObject obj = AVObject.Create("Foo");
obj["content"] = "hello, world";
await obj.SaveAsync();
Assert.NotNull(obj);
await obj.DeleteAsync();
}
[Test]
public async Task DeleteWithCondition() {
AVObject account = new AVObject("Account") {
{ "balance", 100 },
};
account.ACL = new AVACL {
PublicWriteAccess = true,
PublicReadAccess = true
};
await account.SaveAsync();
AVQuery<AVObject> condition = new AVQuery<AVObject>();
condition.WhereGreaterThan("balance", 10);
await account.DeleteAsync(condition);
account = new AVObject("Account") {
{ "balance", 8 },
};
account.ACL = new AVACL {
PublicWriteAccess = true,
PublicReadAccess = true
};
await account.SaveAsync();
condition = new AVQuery<AVObject>();
condition.WhereGreaterThan("balance", 10);
try {
await account.DeleteAsync(condition);
} catch (AVException e) {
Assert.AreEqual(e.Code, AVException.ErrorCode.NoEffectOnUpdatingOrDeleting);
}
}
[Test]
public async Task DeleteAll() {
List<AVObject> objList = new List<AVObject>();
for (int i = 0; i < 5; i++) {
AVObject obj = AVObject.Create("Foo");
obj["content"] = "batch object";
objList.Add(obj);
}
await objList.SaveAllAsync();
await AVObject.DeleteAllAsync(objList);
} }
[Test] [Test]

View File

@ -74,12 +74,17 @@ namespace LeanCloud.Storage.Internal {
return stateTasks; return stateTasks;
} }
public async Task DeleteAsync(IObjectState state, public async Task DeleteAsync(IObjectState state, AVQuery<AVObject> query, CancellationToken cancellationToken) {
CancellationToken cancellationToken) {
var command = new AVCommand { var command = new AVCommand {
Path = $"classes/{state.ClassName}/{state.ObjectId}", Path = $"classes/{state.ClassName}/{state.ObjectId}",
Method = HttpMethod.Delete Method = HttpMethod.Delete
}; };
if (query != null) {
Dictionary<string, object> where = new Dictionary<string, object> {
{ "where", query.BuildWhere() }
};
command.Path = $"{command.Path}?{AVClient.BuildQueryString(where)}";
}
await AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command, cancellationToken); await AVPlugins.Instance.CommandRunner.RunCommandAsync<IDictionary<string, object>>(command, cancellationToken);
} }

View File

@ -12,273 +12,273 @@ namespace LeanCloud {
/// set of users could write to that object. /// set of users could write to that object.
/// </summary> /// </summary>
public class AVACL : IJsonConvertible { public class AVACL : IJsonConvertible {
private enum AccessKind { private enum AccessKind {
Read, Read,
Write Write
}
private const string publicName = "*";
private readonly ICollection<string> readers = new HashSet<string>();
private readonly ICollection<string> writers = new HashSet<string>();
internal AVACL(IDictionary<string, object> jsonObject) {
readers = new HashSet<string>(from pair in jsonObject
where ((IDictionary<string, object>)pair.Value).ContainsKey("read")
select pair.Key);
writers = new HashSet<string>(from pair in jsonObject
where ((IDictionary<string, object>)pair.Value).ContainsKey("write")
select pair.Key);
}
/// <summary>
/// Creates an ACL with no permissions granted.
/// </summary>
public AVACL() {
}
/// <summary>
/// Creates an ACL where only the provided user has access.
/// </summary>
/// <param name="owner">The only user that can read or write objects governed by this ACL.</param>
public AVACL(AVUser owner) {
SetReadAccess(owner, true);
SetWriteAccess(owner, true);
}
IDictionary<string, object> IJsonConvertible.ToJSON() {
var result = new Dictionary<string, object>();
foreach (var user in readers.Union(writers)) {
var userPermissions = new Dictionary<string, object>();
if (readers.Contains(user)) {
userPermissions["read"] = true;
} }
if (writers.Contains(user)) { private const string publicName = "*";
userPermissions["write"] = true; private readonly ICollection<string> readers = new HashSet<string>();
private readonly ICollection<string> writers = new HashSet<string>();
internal AVACL(IDictionary<string, object> jsonObject) {
readers = new HashSet<string>(from pair in jsonObject
where ((IDictionary<string, object>)pair.Value).ContainsKey("read")
select pair.Key);
writers = new HashSet<string>(from pair in jsonObject
where ((IDictionary<string, object>)pair.Value).ContainsKey("write")
select pair.Key);
} }
result[user] = userPermissions;
}
return result;
}
private void SetAccess(AccessKind kind, string userId, bool allowed) { /// <summary>
if (userId == null) { /// Creates an ACL with no permissions granted.
throw new ArgumentException("Cannot set access for an unsaved user or role."); /// </summary>
} public AVACL() {
ICollection<string> target = null; }
switch (kind) {
case AccessKind.Read:
target = readers;
break;
case AccessKind.Write:
target = writers;
break;
default:
throw new NotImplementedException("Unknown AccessKind");
}
if (allowed) {
target.Add(userId);
} else {
target.Remove(userId);
}
}
private bool GetAccess(AccessKind kind, string userId) { /// <summary>
if (userId == null) { /// Creates an ACL where only the provided user has access.
throw new ArgumentException("Cannot get access for an unsaved user or role."); /// </summary>
} /// <param name="owner">The only user that can read or write objects governed by this ACL.</param>
switch (kind) { public AVACL(AVUser owner) {
case AccessKind.Read: SetReadAccess(owner, true);
return readers.Contains(userId); SetWriteAccess(owner, true);
case AccessKind.Write: }
return writers.Contains(userId);
default:
throw new NotImplementedException("Unknown AccessKind");
}
}
/// <summary> IDictionary<string, object> IJsonConvertible.ToJSON() {
/// Gets or sets whether the public is allowed to read this object. var result = new Dictionary<string, object>();
/// </summary> foreach (var user in readers.Union(writers)) {
public bool PublicReadAccess { var userPermissions = new Dictionary<string, object>();
get { if (readers.Contains(user)) {
return GetAccess(AccessKind.Read, publicName); userPermissions["read"] = true;
} }
set { if (writers.Contains(user)) {
SetAccess(AccessKind.Read, publicName, value); userPermissions["write"] = true;
} }
} result[user] = userPermissions;
}
return result;
}
/// <summary> private void SetAccess(AccessKind kind, string userId, bool allowed) {
/// Gets or sets whether the public is allowed to write this object. if (userId == null) {
/// </summary> throw new ArgumentException("Cannot set access for an unsaved user or role.");
public bool PublicWriteAccess { }
get { ICollection<string> target = null;
return GetAccess(AccessKind.Write, publicName); switch (kind) {
} case AccessKind.Read:
set { target = readers;
SetAccess(AccessKind.Write, publicName, value); break;
} case AccessKind.Write:
} target = writers;
break;
default:
throw new NotImplementedException("Unknown AccessKind");
}
if (allowed) {
target.Add(userId);
} else {
target.Remove(userId);
}
}
/// <summary> private bool GetAccess(AccessKind kind, string userId) {
/// Sets whether the given user id is allowed to read this object. if (userId == null) {
/// </summary> throw new ArgumentException("Cannot get access for an unsaved user or role.");
/// <param name="userId">The objectId of the user.</param> }
/// <param name="allowed">Whether the user has permission.</param> switch (kind) {
public void SetReadAccess(string userId, bool allowed) { case AccessKind.Read:
SetAccess(AccessKind.Read, userId, allowed); return readers.Contains(userId);
} case AccessKind.Write:
return writers.Contains(userId);
default:
throw new NotImplementedException("Unknown AccessKind");
}
}
/// <summary> /// <summary>
/// Sets whether the given user is allowed to read this object. /// Gets or sets whether the public is allowed to read this object.
/// </summary> /// </summary>
/// <param name="user">The user.</param> public bool PublicReadAccess {
/// <param name="allowed">Whether the user has permission.</param> get {
public void SetReadAccess(AVUser user, bool allowed) { return GetAccess(AccessKind.Read, publicName);
SetReadAccess(user.ObjectId, allowed); }
} set {
SetAccess(AccessKind.Read, publicName, value);
}
}
/// <summary> /// <summary>
/// Sets whether the given user id is allowed to write this object. /// Gets or sets whether the public is allowed to write this object.
/// </summary> /// </summary>
/// <param name="userId">The objectId of the user.</param> public bool PublicWriteAccess {
/// <param name="allowed">Whether the user has permission.</param> get {
public void SetWriteAccess(string userId, bool allowed) { return GetAccess(AccessKind.Write, publicName);
SetAccess(AccessKind.Write, userId, allowed); }
} set {
SetAccess(AccessKind.Write, publicName, value);
}
}
/// <summary> /// <summary>
/// Sets whether the given user is allowed to write this object. /// Sets whether the given user id is allowed to read this object.
/// </summary> /// </summary>
/// <param name="user">The user.</param> /// <param name="userId">The objectId of the user.</param>
/// <param name="allowed">Whether the user has permission.</param> /// <param name="allowed">Whether the user has permission.</param>
public void SetWriteAccess(AVUser user, bool allowed) { public void SetReadAccess(string userId, bool allowed) {
SetWriteAccess(user.ObjectId, allowed); SetAccess(AccessKind.Read, userId, allowed);
} }
/// <summary> /// <summary>
/// Gets whether the given user id is *explicitly* allowed to read this object. /// Sets whether the given user is allowed to read this object.
/// Even if this returns false, the user may still be able to read it if /// </summary>
/// PublicReadAccess is true or a role that the user belongs to has read access. /// <param name="user">The user.</param>
/// </summary> /// <param name="allowed">Whether the user has permission.</param>
/// <param name="userId">The user objectId to check.</param> public void SetReadAccess(AVUser user, bool allowed) {
/// <returns>Whether the user has access.</returns> SetReadAccess(user.ObjectId, allowed);
public bool GetReadAccess(string userId) { }
return GetAccess(AccessKind.Read, userId);
}
/// <summary> /// <summary>
/// Gets whether the given user is *explicitly* allowed to read this object. /// Sets whether the given user id is allowed to write this object.
/// Even if this returns false, the user may still be able to read it if /// </summary>
/// PublicReadAccess is true or a role that the user belongs to has read access. /// <param name="userId">The objectId of the user.</param>
/// </summary> /// <param name="allowed">Whether the user has permission.</param>
/// <param name="user">The user to check.</param> public void SetWriteAccess(string userId, bool allowed) {
/// <returns>Whether the user has access.</returns> SetAccess(AccessKind.Write, userId, allowed);
public bool GetReadAccess(AVUser user) { }
return GetReadAccess(user.ObjectId);
}
/// <summary> /// <summary>
/// Gets whether the given user id is *explicitly* allowed to write this object. /// Sets whether the given user is allowed to write this object.
/// Even if this returns false, the user may still be able to write it if /// </summary>
/// PublicReadAccess is true or a role that the user belongs to has write access. /// <param name="user">The user.</param>
/// </summary> /// <param name="allowed">Whether the user has permission.</param>
/// <param name="userId">The user objectId to check.</param> public void SetWriteAccess(AVUser user, bool allowed) {
/// <returns>Whether the user has access.</returns> SetWriteAccess(user.ObjectId, allowed);
public bool GetWriteAccess(string userId) { }
return GetAccess(AccessKind.Write, userId);
}
/// <summary> /// <summary>
/// Gets whether the given user is *explicitly* allowed to write this object. /// Gets whether the given user id is *explicitly* allowed to read this object.
/// Even if this returns false, the user may still be able to write it if /// Even if this returns false, the user may still be able to read it if
/// PublicReadAccess is true or a role that the user belongs to has write access. /// PublicReadAccess is true or a role that the user belongs to has read access.
/// </summary> /// </summary>
/// <param name="user">The user to check.</param> /// <param name="userId">The user objectId to check.</param>
/// <returns>Whether the user has access.</returns> /// <returns>Whether the user has access.</returns>
public bool GetWriteAccess(AVUser user) { public bool GetReadAccess(string userId) {
return GetWriteAccess(user.ObjectId); return GetAccess(AccessKind.Read, userId);
} }
/// <summary> /// <summary>
/// Sets whether users belonging to the role with the given <paramref name="roleName"/> /// Gets whether the given user is *explicitly* allowed to read this object.
/// are allowed to read this object. /// Even if this returns false, the user may still be able to read it if
/// </summary> /// PublicReadAccess is true or a role that the user belongs to has read access.
/// <param name="roleName">The name of the role.</param> /// </summary>
/// <param name="allowed">Whether the role has access.</param> /// <param name="user">The user to check.</param>
public void SetRoleReadAccess(string roleName, bool allowed) { /// <returns>Whether the user has access.</returns>
SetAccess(AccessKind.Read, "role:" + roleName, allowed); public bool GetReadAccess(AVUser user) {
} return GetReadAccess(user.ObjectId);
}
/// <summary> /// <summary>
/// Sets whether users belonging to the given role are allowed to read this object. /// Gets whether the given user id is *explicitly* allowed to write this object.
/// </summary> /// Even if this returns false, the user may still be able to write it if
/// <param name="role">The role.</param> /// PublicReadAccess is true or a role that the user belongs to has write access.
/// <param name="allowed">Whether the role has access.</param> /// </summary>
public void SetRoleReadAccess(AVRole role, bool allowed) { /// <param name="userId">The user objectId to check.</param>
SetRoleReadAccess(role.Name, allowed); /// <returns>Whether the user has access.</returns>
} public bool GetWriteAccess(string userId) {
return GetAccess(AccessKind.Write, userId);
}
/// <summary> /// <summary>
/// Gets whether users belonging to the role with the given <paramref name="roleName"/> /// Gets whether the given user is *explicitly* allowed to write this object.
/// are allowed to read this object. Even if this returns false, the role may still be /// Even if this returns false, the user may still be able to write it if
/// able to read it if a parent role has read access. /// PublicReadAccess is true or a role that the user belongs to has write access.
/// </summary> /// </summary>
/// <param name="roleName">The name of the role.</param> /// <param name="user">The user to check.</param>
/// <returns>Whether the role has access.</returns> /// <returns>Whether the user has access.</returns>
public bool GetRoleReadAccess(string roleName) { public bool GetWriteAccess(AVUser user) {
return GetAccess(AccessKind.Read, "role:" + roleName); return GetWriteAccess(user.ObjectId);
} }
/// <summary> /// <summary>
/// Gets whether users belonging to the role are allowed to read this object. /// Sets whether users belonging to the role with the given <paramref name="roleName"/>
/// Even if this returns false, the role may still be able to read it if a /// are allowed to read this object.
/// parent role has read access. /// </summary>
/// </summary> /// <param name="roleName">The name of the role.</param>
/// <param name="role">The name of the role.</param> /// <param name="allowed">Whether the role has access.</param>
/// <returns>Whether the role has access.</returns> public void SetRoleReadAccess(string roleName, bool allowed) {
public bool GetRoleReadAccess(AVRole role) { SetAccess(AccessKind.Read, "role:" + roleName, allowed);
return GetRoleReadAccess(role.Name); }
}
/// <summary> /// <summary>
/// Sets whether users belonging to the role with the given <paramref name="roleName"/> /// Sets whether users belonging to the given role are allowed to read this object.
/// are allowed to write this object. /// </summary>
/// </summary> /// <param name="role">The role.</param>
/// <param name="roleName">The name of the role.</param> /// <param name="allowed">Whether the role has access.</param>
/// <param name="allowed">Whether the role has access.</param> public void SetRoleReadAccess(AVRole role, bool allowed) {
public void SetRoleWriteAccess(string roleName, bool allowed) { SetRoleReadAccess(role.Name, allowed);
SetAccess(AccessKind.Write, "role:" + roleName, allowed); }
}
/// <summary> /// <summary>
/// Sets whether users belonging to the given role are allowed to write this object. /// Gets whether users belonging to the role with the given <paramref name="roleName"/>
/// </summary> /// are allowed to read this object. Even if this returns false, the role may still be
/// <param name="role">The role.</param> /// able to read it if a parent role has read access.
/// <param name="allowed">Whether the role has access.</param> /// </summary>
public void SetRoleWriteAccess(AVRole role, bool allowed) { /// <param name="roleName">The name of the role.</param>
SetRoleWriteAccess(role.Name, allowed); /// <returns>Whether the role has access.</returns>
} public bool GetRoleReadAccess(string roleName) {
return GetAccess(AccessKind.Read, "role:" + roleName);
}
/// <summary> /// <summary>
/// Gets whether users belonging to the role with the given <paramref name="roleName"/> /// Gets whether users belonging to the role are allowed to read this object.
/// are allowed to write this object. Even if this returns false, the role may still be /// Even if this returns false, the role may still be able to read it if a
/// able to write it if a parent role has write access. /// parent role has read access.
/// </summary> /// </summary>
/// <param name="roleName">The name of the role.</param> /// <param name="role">The name of the role.</param>
/// <returns>Whether the role has access.</returns> /// <returns>Whether the role has access.</returns>
public bool GetRoleWriteAccess(string roleName) { public bool GetRoleReadAccess(AVRole role) {
return GetAccess(AccessKind.Write, "role:" + roleName); return GetRoleReadAccess(role.Name);
} }
/// <summary> /// <summary>
/// Gets whether users belonging to the role are allowed to write this object. /// Sets whether users belonging to the role with the given <paramref name="roleName"/>
/// Even if this returns false, the role may still be able to write it if a /// are allowed to write this object.
/// parent role has write access. /// </summary>
/// </summary> /// <param name="roleName">The name of the role.</param>
/// <param name="role">The name of the role.</param> /// <param name="allowed">Whether the role has access.</param>
/// <returns>Whether the role has access.</returns> public void SetRoleWriteAccess(string roleName, bool allowed) {
public bool GetRoleWriteAccess(AVRole role) { SetAccess(AccessKind.Write, "role:" + roleName, allowed);
return GetRoleWriteAccess(role.Name); }
/// <summary>
/// Sets whether users belonging to the given role are allowed to write this object.
/// </summary>
/// <param name="role">The role.</param>
/// <param name="allowed">Whether the role has access.</param>
public void SetRoleWriteAccess(AVRole role, bool allowed) {
SetRoleWriteAccess(role.Name, allowed);
}
/// <summary>
/// Gets whether users belonging to the role with the given <paramref name="roleName"/>
/// are allowed to write this object. Even if this returns false, the role may still be
/// able to write it if a parent role has write access.
/// </summary>
/// <param name="roleName">The name of the role.</param>
/// <returns>Whether the role has access.</returns>
public bool GetRoleWriteAccess(string roleName) {
return GetAccess(AccessKind.Write, "role:" + roleName);
}
/// <summary>
/// Gets whether users belonging to the role are allowed to write this object.
/// Even if this returns false, the role may still be able to write it if a
/// parent role has write access.
/// </summary>
/// <param name="role">The name of the role.</param>
/// <returns>Whether the role has access.</returns>
public bool GetRoleWriteAccess(AVRole role) {
return GetRoleWriteAccess(role.Name);
}
} }
}
} }

View File

@ -258,7 +258,12 @@ namespace LeanCloud
/// <summary> /// <summary>
/// 手机号不合法 /// 手机号不合法
/// </summary> /// </summary>
MobilePhoneInvalid = 253 MobilePhoneInvalid = 253,
/// <summary>
/// 按条件更新/删除失败
/// </summary>
NoEffectOnUpdatingOrDeleting = 305,
} }
internal AVException(ErrorCode code, string message, Exception cause = null) internal AVException(ErrorCode code, string message, Exception cause = null)

View File

@ -790,11 +790,11 @@ string propertyName
/// Deletes this object on the server. /// Deletes this object on the server.
/// </summary> /// </summary>
/// <param name="cancellationToken">The cancellation token.</param> /// <param name="cancellationToken">The cancellation token.</param>
public virtual async Task DeleteAsync(CancellationToken cancellationToken = default) { public virtual async Task DeleteAsync(AVQuery<AVObject> query = null, CancellationToken cancellationToken = default) {
if (ObjectId == null) { if (ObjectId == null) {
return; return;
} }
await ObjectController.DeleteAsync(State, cancellationToken); await ObjectController.DeleteAsync(State, query, cancellationToken);
IsDirty = true; IsDirty = true;
} }