From 464712888856d312120970e616277f6a459be764 Mon Sep 17 00:00:00 2001 From: oneRain Date: Wed, 27 May 2020 15:29:55 +0800 Subject: [PATCH] * ACLTest.cs: * LCDecoder.cs: * LCEncoder.cs: * LCObjectData.cs: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * LCACL.cs: chore: 调整 ACL 逻辑;支持 ACL 反序列化 --- Storage/Storage.Test/ACLTest.cs | 5 +- Storage/Storage/Internal/Codec/LCDecoder.cs | 20 +++++- Storage/Storage/Internal/Codec/LCEncoder.cs | 29 ++++---- .../Storage/Internal/Object/LCObjectData.cs | 7 +- Storage/Storage/LCACL.cs | 66 ++++++++----------- 5 files changed, 75 insertions(+), 52 deletions(-) diff --git a/Storage/Storage.Test/ACLTest.cs b/Storage/Storage.Test/ACLTest.cs index 11fa5df..733cd02 100644 --- a/Storage/Storage.Test/ACLTest.cs +++ b/Storage/Storage.Test/ACLTest.cs @@ -78,12 +78,15 @@ namespace Storage.Test { [Test] public async Task Serialization() { + await LCUser.Login("hello", "world"); LCQuery query = new LCQuery("Account") { IncludeACL = true }; + query.OrderByDescending("createdAt"); ReadOnlyCollection accounts = await query.Find(); foreach (LCObject account in accounts) { - TestContext.WriteLine(account); + TestContext.WriteLine($"public read access: {account.ACL.PublicReadAccess}"); + TestContext.WriteLine($"public write access: {account.ACL.PublicWriteAccess}"); } } } diff --git a/Storage/Storage/Internal/Codec/LCDecoder.cs b/Storage/Storage/Internal/Codec/LCDecoder.cs index f9dd00a..ae920a0 100644 --- a/Storage/Storage/Internal/Codec/LCDecoder.cs +++ b/Storage/Storage/Internal/Codec/LCDecoder.cs @@ -68,10 +68,26 @@ namespace LeanCloud.Storage.Internal.Codec { } public static LCGeoPoint DecodeGeoPoint(IDictionary data) { - double latitude = double.Parse(data["latitude"].ToString()); - double longitude = double.Parse(data["longitude"].ToString()); + double latitude = Convert.ToDouble(data["latitude"]); + double longitude = Convert.ToDouble(data["longitude"]); LCGeoPoint geoPoint = new LCGeoPoint(latitude, longitude); return geoPoint; } + + public static LCACL DecodeACL(Dictionary dict) { + Console.WriteLine($"count: {dict.Count}"); + LCACL acl = new LCACL(); + foreach (KeyValuePair kv in dict) { + string key = kv.Key; + Dictionary access = kv.Value as Dictionary; + if (access.TryGetValue("read", out object ra)) { + acl.readAccess[key] = Convert.ToBoolean(ra); + } + if (access.TryGetValue("write", out object wa)) { + acl.writeAccess[key] = Convert.ToBoolean(wa); + } + } + return acl; + } } } diff --git a/Storage/Storage/Internal/Codec/LCEncoder.cs b/Storage/Storage/Internal/Codec/LCEncoder.cs index 383247b..a216200 100644 --- a/Storage/Storage/Internal/Codec/LCEncoder.cs +++ b/Storage/Storage/Internal/Codec/LCEncoder.cs @@ -83,18 +83,25 @@ namespace LeanCloud.Storage.Internal.Codec { } public static object EncodeACL(LCACL acl) { - HashSet readers = acl.readers; - HashSet writers = acl.writers; - HashSet union = new HashSet(readers); - union.UnionWith(writers); - Dictionary dict = new Dictionary(); - foreach (string k in union) { - dict[k] = new Dictionary { - { "read", readers.Contains(k) }, - { "write", writers.Contains(k) } - }; + HashSet keys = new HashSet(); + if (acl.readAccess.Count > 0) { + keys.UnionWith(acl.readAccess.Keys); } - return dict; + if (acl.writeAccess.Count > 0) { + keys.UnionWith(acl.writeAccess.Keys); + } + Dictionary result = new Dictionary(); + foreach (string key in keys) { + Dictionary access = new Dictionary(); + if (acl.readAccess.TryGetValue(key, out bool ra)) { + access["read"] = ra; + } + if (acl.writeAccess.TryGetValue(key, out bool wa)) { + access["write"] = wa; + } + result[key] = access; + } + return result; } public static object EncodeRelation(LCRelation relation) { diff --git a/Storage/Storage/Internal/Object/LCObjectData.cs b/Storage/Storage/Internal/Object/LCObjectData.cs index eb8c09a..bc5e90d 100644 --- a/Storage/Storage/Internal/Object/LCObjectData.cs +++ b/Storage/Storage/Internal/Object/LCObjectData.cs @@ -44,7 +44,12 @@ namespace LeanCloud.Storage.Internal.Object { } else if (key == "updatedAt" && DateTime.TryParse(value.ToString(), out DateTime updatedAt)) { objectData.UpdatedAt = updatedAt.ToLocalTime(); } else { - objectData.CustomPropertyDict[key] = LCDecoder.Decode(value); + if (key == "ACL" && + value is Dictionary dic) { + objectData.CustomPropertyDict[key] = LCDecoder.DecodeACL(dic); + } else { + objectData.CustomPropertyDict[key] = LCDecoder.Decode(value); + } } } return objectData; diff --git a/Storage/Storage/LCACL.cs b/Storage/Storage/LCACL.cs index b7b6664..024c48f 100644 --- a/Storage/Storage/LCACL.cs +++ b/Storage/Storage/LCACL.cs @@ -10,22 +10,32 @@ namespace LeanCloud.Storage { const string RoleKeyPrefix = "role:"; - internal HashSet readers; - internal HashSet writers; + internal Dictionary readAccess = new Dictionary(); + internal Dictionary writeAccess = new Dictionary(); + + public static LCACL CreateWithOwner(LCUser owner) { + if (owner == null) { + throw new ArgumentNullException(nameof(owner)); + } + LCACL acl = new LCACL(); + acl.SetUserReadAccess(owner, true); + acl.SetUserWriteAccess(owner, true); + return acl; + } public bool PublicReadAccess { get { - return GetAccess(readers, PublicKey); + return GetAccess(readAccess, PublicKey); } set { - SetAccess(readers, PublicKey, value); + SetAccess(readAccess, PublicKey, value); } } public bool PublicWriteAccess { get { - return GetAccess(writers, PublicKey); + return GetAccess(writeAccess, PublicKey); } set { - SetAccess(writers, PublicKey, value); + SetAccess(writeAccess, PublicKey, value); } } @@ -33,28 +43,28 @@ namespace LeanCloud.Storage { if (string.IsNullOrEmpty(userId)) { throw new ArgumentNullException(nameof(userId)); } - return GetAccess(readers, userId); + return GetAccess(readAccess, userId); } public void SetUserIdReadAccess(string userId, bool value) { if (string.IsNullOrEmpty(userId)) { throw new ArgumentNullException(nameof(userId)); } - SetAccess(readers, userId, value); + SetAccess(readAccess, userId, value); } public bool GetUserIdWriteAccess(string userId) { if (string.IsNullOrEmpty(userId)) { throw new ArgumentNullException(nameof(userId)); } - return GetAccess(writers, userId); + return GetAccess(writeAccess, userId); } public void SetUserIdWriteAccess(string userId, bool value) { if (string.IsNullOrEmpty(userId)) { throw new ArgumentNullException(nameof(userId)); } - SetAccess(writers, userId, value); + SetAccess(writeAccess, userId, value); } public bool GetUserReadAccess(LCUser user) { @@ -90,7 +100,7 @@ namespace LeanCloud.Storage { throw new ArgumentNullException(nameof(role)); } string roleKey = $"{RoleKeyPrefix}{role.ObjectId}"; - return GetAccess(readers, roleKey); + return GetAccess(readAccess, roleKey); } public void SetRoleReadAccess(LCRole role, bool value) { @@ -98,7 +108,7 @@ namespace LeanCloud.Storage { throw new ArgumentNullException(nameof(role)); } string roleKey = $"{RoleKeyPrefix}{role.ObjectId}"; - SetAccess(readers, roleKey, value); + SetAccess(readAccess, roleKey, value); } public bool GetRoleWriteAccess(LCRole role) { @@ -106,7 +116,7 @@ namespace LeanCloud.Storage { throw new ArgumentNullException(nameof(role)); } string roleKey = $"{RoleKeyPrefix}{role.ObjectId}"; - return GetAccess(writers, roleKey); + return GetAccess(writeAccess, roleKey); } public void SetRoleWriteAccess(LCRole role, bool value) { @@ -114,34 +124,16 @@ namespace LeanCloud.Storage { throw new ArgumentNullException(nameof(role)); } string roleKey = $"{RoleKeyPrefix}{role.ObjectId}"; - SetAccess(writers, roleKey, value); + SetAccess(writeAccess, roleKey, value); } - public LCACL() { - readers = new HashSet(); - writers = new HashSet(); + bool GetAccess(Dictionary access, string key) { + return access.ContainsKey(key) ? + access[key] : false; } - public static LCACL CreateWithOwner(LCUser owner) { - if (owner == null) { - throw new ArgumentNullException(nameof(owner)); - } - LCACL acl = new LCACL(); - acl.SetUserReadAccess(owner, true); - acl.SetUserWriteAccess(owner, true); - return acl; - } - - bool GetAccess(HashSet set, string key) { - return set.Contains(key); - } - - void SetAccess(HashSet set, string key, bool value) { - if (value) { - set.Add(key); - } else { - set.Remove(key); - } + void SetAccess(Dictionary access, string key, bool value) { + access[key] = value; } } }