diff --git a/LeStorage/Codables/ApiCall.swift b/LeStorage/Codables/ApiCall.swift index d6c29a8..cd41fdd 100644 --- a/LeStorage/Codables/ApiCall.swift +++ b/LeStorage/Codables/ApiCall.swift @@ -17,7 +17,6 @@ class ApiCall: ModelObject, Storable, SomeCall { static func resourceName() -> String { return "apicalls_" + T.resourceName() } static func tokenExemptedMethods() -> [HTTPMethod] { return [] } - static func filterByStoreIdentifier() -> Bool { return false } var id: String = Store.randomId() diff --git a/LeStorage/Codables/DataAccess.swift b/LeStorage/Codables/DataAccess.swift index 64dee97..56f7399 100644 --- a/LeStorage/Codables/DataAccess.swift +++ b/LeStorage/Codables/DataAccess.swift @@ -11,7 +11,6 @@ class DataAccess: SyncedModelObject, SyncedStorable { static func tokenExemptedMethods() -> [HTTPMethod] { return [] } static func resourceName() -> String { return "data-access" } - static func filterByStoreIdentifier() -> Bool { return false } static func relationships() -> [Relationship] { return [] } var id: String = Store.randomId() diff --git a/LeStorage/Codables/DataLog.swift b/LeStorage/Codables/DataLog.swift index c9d46f0..12c4118 100644 --- a/LeStorage/Codables/DataLog.swift +++ b/LeStorage/Codables/DataLog.swift @@ -11,7 +11,6 @@ class DataLog: ModelObject, Storable { static func resourceName() -> String { return "data-logs" } static func tokenExemptedMethods() -> [HTTPMethod] { return [] } - static func filterByStoreIdentifier() -> Bool { return false } static func relationships() -> [Relationship] { return [] } var id: String = Store.randomId() diff --git a/LeStorage/Codables/FailedAPICall.swift b/LeStorage/Codables/FailedAPICall.swift index 7a8ca88..58c56f7 100644 --- a/LeStorage/Codables/FailedAPICall.swift +++ b/LeStorage/Codables/FailedAPICall.swift @@ -11,7 +11,6 @@ class FailedAPICall: SyncedModelObject, SyncedStorable { static func resourceName() -> String { return "failed-api-calls" } static func tokenExemptedMethods() -> [HTTPMethod] { return [] } - static func filterByStoreIdentifier() -> Bool { return false } static func relationships() -> [Relationship] { return [] } var id: String = Store.randomId() diff --git a/LeStorage/Codables/GetSyncData.swift b/LeStorage/Codables/GetSyncData.swift index b8d2aa7..c2de254 100644 --- a/LeStorage/Codables/GetSyncData.swift +++ b/LeStorage/Codables/GetSyncData.swift @@ -9,7 +9,6 @@ import Foundation class GetSyncData: SyncedModelObject, SyncedStorable, URLParameterConvertible { - static func filterByStoreIdentifier() -> Bool { return false } static func tokenExemptedMethods() -> [HTTPMethod] { return [] } static func resourceName() -> String { diff --git a/LeStorage/Codables/Log.swift b/LeStorage/Codables/Log.swift index ab23860..95f0be2 100644 --- a/LeStorage/Codables/Log.swift +++ b/LeStorage/Codables/Log.swift @@ -11,7 +11,6 @@ class Log: SyncedModelObject, SyncedStorable { static func resourceName() -> String { return "logs" } static func tokenExemptedMethods() -> [HTTPMethod] { return [] } - static func filterByStoreIdentifier() -> Bool { return false } static func relationships() -> [Relationship] { return [] } var id: String = Store.randomId() diff --git a/LeStorage/Services.swift b/LeStorage/Services.swift index 8666841..44e308b 100644 --- a/LeStorage/Services.swift +++ b/LeStorage/Services.swift @@ -34,8 +34,8 @@ let postDeviceTokenCall: ServiceCall = ServiceCall( path: "device-token/", method: .post, requiresToken: true) let getUserDataAccessCall: ServiceCall = ServiceCall( path: "user-data-access/", method: .get, requiresToken: true) -let userSearchCall: ServiceCall = ServiceCall( - path: "users-search/", method: .get, requiresToken: true) +let userNamesCall: ServiceCall = ServiceCall( + path: "user-names/", method: .get, requiresToken: true) /// A class used to send HTTP request to the django server public class Services { @@ -463,9 +463,8 @@ public class Services { // MARK: - Others - public func searchUsers(string: String) async throws -> [ShortUser] { - let baseRequest = try self._baseRequest(call: userSearchCall, getArguments: ["search": string]) - return try await self._runRequest(baseRequest) + public func getUserNames() async throws -> [ShortUser] { + return try await self._runRequest(serviceCall: userNamesCall) } // MARK: - Authentication diff --git a/LeStorage/Storable.swift b/LeStorage/Storable.swift index 21b7739..2c08e3e 100644 --- a/LeStorage/Storable.swift +++ b/LeStorage/Storable.swift @@ -17,11 +17,6 @@ public protocol Storable: Codable, Identifiable, NSObjectProtocol { /// Also used as the name of the local file static func resourceName() -> String - /// This method is only used if the instance store uses an identifier - /// This method should return true if the resources need to get filtered using the store identifier when performing a GET - /// Returning false won't filter the resources when performing a GET - static func filterByStoreIdentifier() -> Bool - /// A method that deletes the local dependencies of the resource /// Mimics the behavior the cascading delete on the django server /// Typically when we delete a resource, we automatically delete items that depends on it, @@ -42,7 +37,7 @@ extension Storable { } /// Returns a string id for the instance - var stringId: String { + public var stringId: String { switch self.id { case let sp as any StringProtocol: return String(sp) diff --git a/LeStorage/Store.swift b/LeStorage/Store.swift index 57af2ec..960fb93 100644 --- a/LeStorage/Store.swift +++ b/LeStorage/Store.swift @@ -243,8 +243,6 @@ final public class Store { count += collection.referenceCount(type: type, id: id) } return count -// let collection: StoredCollection = try self.collection() -// collection.revokeByStringIdNoSync(id) } // MARK: - Write @@ -292,8 +290,8 @@ final public class Store { /// Retrieves all the items on the server public func getItems() async throws -> [T] { - if T.filterByStoreIdentifier() { - return try await StoreCenter.main.getItems(identifier: self.identifier) + if let identifier = self.identifier { + return try await StoreCenter.main.getItems(identifier: identifier) } else { return try await StoreCenter.main.getItems() } diff --git a/LeStorage/StoreCenter.swift b/LeStorage/StoreCenter.swift index f89a8e8..1f6645c 100644 --- a/LeStorage/StoreCenter.swift +++ b/LeStorage/StoreCenter.swift @@ -822,39 +822,55 @@ public class StoreCenter { // MARK: - Data Access - public func giveUserAccess(_ user: String, data: T) throws { +// public func giveUserAccess(_ user: String, data: T) throws { +// guard let dataAccessCollection = self._dataAccess else { +// throw LeStorageError.dataAccessCollectionNotDefined +// } +// guard let userId = self.userId else { +// throw LeStorageError.cantCreateDataAccessBecauseUserIdIsNil +// } +// let collection: StoredCollection = try Store.main.collection() +// guard collection.findById(data.id) != nil else { +// throw LeStorageError.cantCreateDataAccessBecauseNotInMainStore +// } +// +// if let dataAccess = dataAccessCollection.first(where: { $0.modelId == data.stringId }) { +// dataAccess.sharedWith.append(user) +// dataAccessCollection.addOrUpdate(instance: dataAccess) +// } else { +// let dataAccess = DataAccess(owner: userId, sharedWith: [user], modelName: String(describing: type(of: data)), modelId: data.stringId) +// dataAccessCollection.addOrUpdate(instance: dataAccess) +// } +// } + + public func authorizedUsers(for modelId: String) -> [String] { guard let dataAccessCollection = self._dataAccess else { - throw LeStorageError.dataAccessCollectionNotDefined - } - guard let userId = self.userId else { - throw LeStorageError.cantCreateDataAccessBecauseUserIdIsNil + return [] } - let collection: StoredCollection = try Store.main.collection() - guard collection.findById(data.id) != nil else { - throw LeStorageError.cantCreateDataAccessBecauseNotInMainStore - } - - if let dataAccess = dataAccessCollection.first(where: { $0.modelId == data.stringId }) { - dataAccess.sharedWith.append(user) - dataAccessCollection.addOrUpdate(instance: dataAccess) - } else { - let dataAccess = DataAccess(owner: userId, sharedWith: [user], modelName: String(describing: type(of: data)), modelId: data.stringId) - dataAccessCollection.addOrUpdate(instance: dataAccess) + if let dataAccess = dataAccessCollection.first(where: { $0.modelId == modelId }) { + return dataAccess.sharedWith } + return [] } - public func removeUserAccess(_ user: String, data: T) { + public func setAuthorizedUsers(for instance: T, users: [String]) throws { guard let dataAccessCollection = self._dataAccess else { return } - if let dataAccess = dataAccessCollection.first(where: { $0.modelId == data.stringId }) { - dataAccess.sharedWith.removeAll(where: { $0 == user }) - - if dataAccess.sharedWith.isEmpty { + guard let userId = self.userId else { + throw LeStorageError.cantCreateDataAccessBecauseUserIdIsNil + } + + if let dataAccess = dataAccessCollection.first(where: { $0.modelId == instance.stringId }) { + if users.isEmpty { dataAccessCollection.delete(instance: dataAccess) } else { - dataAccessCollection.addOrUpdate(instance: dataAccess) + dataAccess.sharedWith.removeAll() + dataAccess.sharedWith = users } + } else { + let dataAccess = DataAccess(owner: userId, sharedWith: users, modelName: String(describing: type(of: instance)), modelId: instance.stringId) + dataAccessCollection.addOrUpdate(instance: dataAccess) } } diff --git a/LeStorageTests/CollectionsTests.swift b/LeStorageTests/CollectionsTests.swift index 93b2e79..bd95d6d 100644 --- a/LeStorageTests/CollectionsTests.swift +++ b/LeStorageTests/CollectionsTests.swift @@ -13,7 +13,6 @@ class Car: ModelObject, Storable { var id: String = Store.randomId() static func resourceName() -> String { return "car" } - static func filterByStoreIdentifier() -> Bool { return false } static var relationshipNames: [String] = [] } @@ -24,7 +23,6 @@ class Boat: ModelObject, SyncedStorable { static func tokenExemptedMethods() -> [LeStorage.HTTPMethod] { return [] } static func resourceName() -> String { return "boat" } - static func filterByStoreIdentifier() -> Bool { return false } static var relationshipNames: [String] = [] var storeId: String? { return nil } diff --git a/LeStorageTests/IdentifiableTests.swift b/LeStorageTests/IdentifiableTests.swift index 5260d78..eb49cde 100644 --- a/LeStorageTests/IdentifiableTests.swift +++ b/LeStorageTests/IdentifiableTests.swift @@ -11,7 +11,6 @@ import LeStorage class IntObject: ModelObject, Storable { static func resourceName() -> String { "int" } static func tokenExemptedMethods() -> [LeStorage.HTTPMethod] { [] } - static func filterByStoreIdentifier() -> Bool { false } static var relationshipNames: [String] = [] var id: Int @@ -26,7 +25,6 @@ class IntObject: ModelObject, Storable { class StringObject: ModelObject, Storable { static func resourceName() -> String { "string" } static func tokenExemptedMethods() -> [LeStorage.HTTPMethod] { [] } - static func filterByStoreIdentifier() -> Bool { false } static var relationshipNames: [String] = [] var id: String diff --git a/LeStorageTests/StoredCollectionTests.swift b/LeStorageTests/StoredCollectionTests.swift index c02a5b9..85cd894 100644 --- a/LeStorageTests/StoredCollectionTests.swift +++ b/LeStorageTests/StoredCollectionTests.swift @@ -100,9 +100,6 @@ class StoredCollectionTests: XCTestCase { // Mock Storable for testing purposes class MockStorable: ModelObject, Storable { - static func filterByStoreIdentifier() -> Bool { - return false - } var id: String = Store.randomId() var name: String