krz/hutch
an ios client for sourcehut
clone: git clone https://gitbay.org/krz/hutch.git
remove-splash-highlighter: Hutch/Networking/RepositoryACLService.swift · raw
1import Foundation
2
3protocol RepositoryACLServicing {
4 func fetchACLs(repositoryRid: String) async throws -> [RepositoryACLEntry]
5 func upsertACL(repositoryId: Int, entity: String, mode: AccessMode) async throws -> RepositoryACLEntry
6 func deleteACL(entryId: Int) async throws
7}
8
9private struct RepositoryACLQueryResponse: Decodable, Sendable {
10 let repository: RepositoryACLQueryRepository?
11}
12
13private struct RepositoryACLQueryRepository: Decodable, Sendable {
14 let acls: RepositoryACLPage
15}
16
17private struct RepositoryACLPage: Decodable, Sendable {
18 let results: [RepositoryACLEntry]
19}
20
21private struct RepositoryACLMutationResponse: Decodable, Sendable {
22 let updateACL: RepositoryACLEntry
23}
24
25private struct RepositoryACLDeleteResponse: Decodable, Sendable {
26 let deleteACL: RepositoryACLDeletedEntry
27}
28
29private struct RepositoryACLDeletedEntry: Decodable, Sendable {
30 let id: Int
31}
32
33struct RepositoryACLService: RepositoryACLServicing {
34 private let client: SRHTClient
35 private let service: SRHTService
36
37 init(client: SRHTClient, service: SRHTService) {
38 self.client = client
39 self.service = service
40 }
41
42 func fetchACLs(repositoryRid: String) async throws -> [RepositoryACLEntry] {
43 let response = try await client.execute(
44 service: service,
45 query: Self.aclsQuery,
46 variables: ["rid": repositoryRid],
47 responseType: RepositoryACLQueryResponse.self
48 )
49 return response.repository?.acls.results ?? []
50 }
51
52 func upsertACL(repositoryId: Int, entity: String, mode: AccessMode) async throws -> RepositoryACLEntry {
53 let response = try await client.execute(
54 service: service,
55 query: Self.upsertACLMutation,
56 variables: [
57 "repoId": repositoryId,
58 "entity": entity,
59 "mode": mode.rawValue
60 ],
61 responseType: RepositoryACLMutationResponse.self
62 )
63 return response.updateACL
64 }
65
66 func deleteACL(entryId: Int) async throws {
67 _ = try await client.execute(
68 service: service,
69 query: Self.deleteACLMutation,
70 variables: ["id": entryId],
71 responseType: RepositoryACLDeleteResponse.self
72 )
73 }
74}
75
76private extension RepositoryACLService {
77 static let aclsQuery = """
78 query repositoryACLs($rid: ID!) {
79 repository(rid: $rid) {
80 acls {
81 results {
82 id
83 mode
84 entity { canonicalName }
85 }
86 }
87 }
88 }
89 """
90
91 static let upsertACLMutation = """
92 mutation updateACL($repoId: Int!, $mode: AccessMode!, $entity: String!) {
93 updateACL(repoId: $repoId, mode: $mode, entity: $entity) {
94 id
95 mode
96 entity { canonicalName }
97 }
98 }
99 """
100
101 static let deleteACLMutation = """
102 mutation deleteACL($id: Int!) {
103 deleteACL(id: $id) { id }
104 }
105 """
106}