diff --git a/Sources/NextcloudKit/Models/NKTermsOfService.swift b/Sources/NextcloudKit/Models/NKTermsOfService.swift new file mode 100644 index 0000000..5d8b41f --- /dev/null +++ b/Sources/NextcloudKit/Models/NKTermsOfService.swift @@ -0,0 +1,72 @@ +// SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: 2024 Marino Faggiana +// SPDX-License-Identifier: GPL-3.0-or-later + +import Foundation + +public class NKTermsOfService: NSObject { + public var meta: Meta? + public var data: OCSData? + + public override init() { + super.init() + } + + public func loadFromJSON(_ jsonData: Data) -> Bool { + do { + let decodedResponse = try JSONDecoder().decode(OCSResponse.self, from: jsonData) + self.meta = decodedResponse.ocs.meta + self.data = decodedResponse.ocs.data + return true + } catch { + print("decode error:", error) + return false + } + } + + public func getTerms() -> [Term]? { + return data?.terms + } + + public func getLanguages() -> [String: String]? { + return data?.languages + } + + public func hasUserSigned() -> Bool { + return data?.hasSigned ?? false + } + + public func getMeta() -> Meta? { + return meta + } + + // MARK: - Codable + private class OCSResponse: Codable { + let ocs: OCS + } + + private class OCS: Codable { + let meta: Meta + let data: OCSData + } + + public class Meta: Codable { + public let status: String + public let statuscode: Int + public let message: String + } + + public class OCSData: Codable { + public let terms: [Term] + public let languages: [String: String] + public let hasSigned: Bool + } + + public class Term: Codable { + public let id: Int + public let countryCode: String + public let languageCode: String + public let body: String + public let renderedBody: String + } +} diff --git a/Sources/NextcloudKit/NextcloudKit+TermsOfService.swift b/Sources/NextcloudKit/NextcloudKit+TermsOfService.swift new file mode 100644 index 0000000..1ea602e --- /dev/null +++ b/Sources/NextcloudKit/NextcloudKit+TermsOfService.swift @@ -0,0 +1,89 @@ +// SPDX-FileCopyrightText: Nextcloud GmbH +// SPDX-FileCopyrightText: 2024 Marino Faggiana +// SPDX-License-Identifier: GPL-3.0-or-later + +import Foundation +import Alamofire +import SwiftyJSON + +public extension NextcloudKit { + func getTermsOfService(account: String, + options: NKRequestOptions = NKRequestOptions(), + request: @escaping (DataRequest?) -> Void = { _ in }, + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ tos: NKTermsOfService?, _ responseData: AFDataResponse?, _ error: NKError) -> Void) { + let endpoint = "ocs/v2.php/apps/terms_of_service/terms" + guard let nkSession = nkCommonInstance.getSession(account: account), + let url = nkCommonInstance.createStandardUrl(serverUrl: nkSession.urlBase, endpoint: endpoint, options: options), + let headers = nkCommonInstance.getStandardHeaders(account: account, options: options) else { + return options.queue.async { completion(account, nil, nil, .urlError) } + } + + let tosRequest = nkSession.sessionData.request(url, method: .get, encoding: URLEncoding.default, headers: headers, interceptor: nil).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in + task.taskDescription = options.taskDescription + taskHandler(task) + }.responseData(queue: self.nkCommonInstance.backgroundQueue) { response in + if self.nkCommonInstance.levelLog > 0 { + debugPrint(response) + } + switch response.result { + case .success(let jsonData): + let tos = NKTermsOfService() + if tos.loadFromJSON(jsonData), let meta = tos.getMeta() { + if meta.statuscode == 200 { + options.queue.async { completion(account, tos, response, .success) } + } else { + options.queue.async { completion(account, tos, response, NKError(errorCode: meta.statuscode, errorDescription: meta.message, responseData: jsonData)) } + } + } else { + options.queue.async { completion(account, nil, response, .invalidData) } + } + case .failure(let error): + let error = NKError(error: error, afResponse: response, responseData: response.data) + options.queue.async { completion(account, nil, response, error) } + } + } + options.queue.async { request(tosRequest) } + } + + func signTermsOfService(termId: String, + account: String, + options: NKRequestOptions = NKRequestOptions(), + taskHandler: @escaping (_ task: URLSessionTask) -> Void = { _ in }, + completion: @escaping (_ account: String, _ responseData: AFDataResponse?, _ error: NKError) -> Void) { + let endpoint = "ocs/v2.php/apps/terms_of_service/sign" + var urlRequest: URLRequest + /// + options.contentType = "application/json" + /// + guard let nkSession = nkCommonInstance.getSession(account: account), + let url = nkCommonInstance.createStandardUrl(serverUrl: nkSession.urlBase, endpoint: endpoint, options: options), + let headers = nkCommonInstance.getStandardHeaders(account: account, options: options) else { + return options.queue.async { completion(account, nil, .urlError) } + } + + do { + try urlRequest = URLRequest(url: url, method: .post, headers: headers) + let parameters = "{\"termId\":\"" + termId + "\"}" + urlRequest.httpBody = parameters.data(using: .utf8) + } catch { + return options.queue.async { completion(account, nil, NKError(error: error)) } + } + + nkSession.sessionData.request(urlRequest).validate(statusCode: 200..<300).onURLSessionTaskCreation { task in + task.taskDescription = options.taskDescription + taskHandler(task) + }.responseData(queue: self.nkCommonInstance.backgroundQueue) { response in + if self.nkCommonInstance.levelLog > 0 { + debugPrint(response) + } + switch response.result { + case .failure(let error): + let error = NKError(error: error, afResponse: response, responseData: response.data) + options.queue.async { completion(account, response, error) } + case .success: + options.queue.async { completion(account, response, .success) } + } + } + } +}