* AVACL.cs:
* ObjectTest.cs: * AVObject.cs: * AVException.cs: * ObjectControllerTests.cs: * AVObjectController.cs: chore: AVObject 增加符合条件删除
parent
d118935f21
commit
68a047ba1e
|
@ -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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -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]
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue