summaryrefslogtreecommitdiff
path: root/Hutch/Networking/RepositoryACLService.swift
diff options
context:
space:
mode:
Diffstat (limited to 'Hutch/Networking/RepositoryACLService.swift')
-rw-r--r--Hutch/Networking/RepositoryACLService.swift106
1 files changed, 106 insertions, 0 deletions
diff --git a/Hutch/Networking/RepositoryACLService.swift b/Hutch/Networking/RepositoryACLService.swift
new file mode 100644
index 0000000..82a7a38
--- /dev/null
+++ b/Hutch/Networking/RepositoryACLService.swift
@@ -0,0 +1,106 @@
+import Foundation
+
+protocol RepositoryACLServicing {
+ func fetchACLs(repositoryRid: String) async throws -> [RepositoryACLEntry]
+ func upsertACL(repositoryId: Int, entity: String, mode: AccessMode) async throws -> RepositoryACLEntry
+ func deleteACL(entryId: Int) async throws
+}
+
+private struct RepositoryACLQueryResponse: Decodable, Sendable {
+ let repository: RepositoryACLQueryRepository?
+}
+
+private struct RepositoryACLQueryRepository: Decodable, Sendable {
+ let acls: RepositoryACLPage
+}
+
+private struct RepositoryACLPage: Decodable, Sendable {
+ let results: [RepositoryACLEntry]
+}
+
+private struct RepositoryACLMutationResponse: Decodable, Sendable {
+ let updateACL: RepositoryACLEntry
+}
+
+private struct RepositoryACLDeleteResponse: Decodable, Sendable {
+ let deleteACL: RepositoryACLDeletedEntry
+}
+
+private struct RepositoryACLDeletedEntry: Decodable, Sendable {
+ let id: Int
+}
+
+struct RepositoryACLService: RepositoryACLServicing {
+ private let client: SRHTClient
+ private let service: SRHTService
+
+ init(client: SRHTClient, service: SRHTService) {
+ self.client = client
+ self.service = service
+ }
+
+ func fetchACLs(repositoryRid: String) async throws -> [RepositoryACLEntry] {
+ let response = try await client.execute(
+ service: service,
+ query: Self.aclsQuery,
+ variables: ["rid": repositoryRid],
+ responseType: RepositoryACLQueryResponse.self
+ )
+ return response.repository?.acls.results ?? []
+ }
+
+ func upsertACL(repositoryId: Int, entity: String, mode: AccessMode) async throws -> RepositoryACLEntry {
+ let response = try await client.execute(
+ service: service,
+ query: Self.upsertACLMutation,
+ variables: [
+ "repoId": repositoryId,
+ "entity": entity,
+ "mode": mode.rawValue
+ ],
+ responseType: RepositoryACLMutationResponse.self
+ )
+ return response.updateACL
+ }
+
+ func deleteACL(entryId: Int) async throws {
+ _ = try await client.execute(
+ service: service,
+ query: Self.deleteACLMutation,
+ variables: ["id": entryId],
+ responseType: RepositoryACLDeleteResponse.self
+ )
+ }
+}
+
+private extension RepositoryACLService {
+ static let aclsQuery = """
+ query repositoryACLs($rid: ID!) {
+ repository(rid: $rid) {
+ acls {
+ results {
+ id
+ mode
+ entity { canonicalName }
+ }
+ }
+ }
+ }
+ """
+
+ static let upsertACLMutation = """
+ mutation updateACL($repoId: Int!, $mode: AccessMode!, $entity: String!) {
+ updateACL(repoId: $repoId, mode: $mode, entity: $entity) {
+ id
+ mode
+ entity { canonicalName }
+ }
+ }
+ """
+
+ static let deleteACLMutation = """
+ mutation deleteACL($id: Int!) {
+ deleteACL(id: $id) { id }
+ }
+ """
+}