Request to /api/mobile/register/hebe

This commit is contained in:
Pengwius 2021-03-02 11:05:42 +01:00
parent 5b2bda83f8
commit 4a7319aab8
8 changed files with 132 additions and 7 deletions

View file

@ -0,0 +1,50 @@
//
// getSignatures.swift
//
//
// Created by Tomasz on 02/03/2021.
//
import Foundation
import KeychainAccess
@available (iOS 14, macOS 11, watchOS 7, tvOS 14, *)
func getSignatures(request: URLRequest, certificate: X509) -> String {
guard let urlString = request.url?.absoluteString else {
return "\(Sdk.APIError.urlError)"
}
// Get private key
guard let privateKeyRawData = certificate.getPrivateKeyData(format: .DER),
let privateKeyString = String(data: privateKeyRawData, encoding: .utf8)?
.split(separator: "\n")
.dropFirst()
.dropLast()
.joined()
.data(using: .utf8) else {
return "\(Sdk.APIError.noPrivateKey)"
}
// Create SecKey
let attributes = [
kSecAttrKeyType: kSecAttrKeyTypeRSA,
kSecAttrKeyClass: kSecAttrKeyClassPrivate,
]
guard let privateKeyData = Data(base64Encoded: privateKeyString),
let secKey = SecKeyCreateWithData(privateKeyData as NSData, attributes as NSDictionary, nil) else {
return "\(Sdk.APIError.noPrivateKey)"
}
// Get fingerprint
guard let signatureValues = Sdk.Signer.getSignatureValues(body: request.httpBody, url: urlString, privateKey: secKey, fingerprint: certificate.getCertificateFingerprint().lowercased()) else {
return "\(Sdk.APIError.noPrivateKey)"
}
// Headers
let keychain = Keychain()
let fingerprint: String! = keychain["keyFingerprint"]
let signature = "\(signatureValues.signature.replacingOccurrences(of: "nil", with: fingerprint))"
return signature
}

View file

@ -9,6 +9,7 @@
import Foundation
import Combine
import os
import KeychainAccess
@available (iOS 14, macOS 11, watchOS 7, tvOS 14, *)
public class Sdk {
@ -17,6 +18,9 @@ public class Sdk {
private let loggerSubsystem: String = "com.wulkanowy-ios.Sdk"
private var cancellables: Set<AnyCancellable> = []
var firebaseToken: String!
var endpointURL: String!
public let certificate: X509
// MARK: - Init
@ -136,6 +140,7 @@ public class Sdk {
let parsedError = self.parseResponse(response) {
completionHandler(parsedError)
} else {
self.getStudents(symbol: symbol, deviceModel: deviceModel)
completionHandler(nil)
}
})
@ -155,6 +160,8 @@ public class Sdk {
/// - Throws: Error
/// - Returns: URLSession.DataTaskPublisher
private func registerDevice(endpointURL: String, firebaseToken: String, token: String, symbol: String, pin: String, deviceModel: String) throws -> URLSession.DataTaskPublisher {
self.endpointURL = endpointURL
self.firebaseToken = firebaseToken
guard let keyFingerprint = certificate.getPrivateKeyFingerprint(format: .PEM)?.replacingOccurrences(of: ":", with: "").lowercased(),
let keyData = certificate.getPublicKeyData(),
let keyBase64 = String(data: keyData, encoding: .utf8)?
@ -179,7 +186,10 @@ public class Sdk {
return dateFormatter.string(from: now)
}
let keychain = Keychain()
keychain[string: "keyFingerprint"] = keyFingerprint
// Body
let body: [String: Encodable?] = [
"AppName": "DzienniczekPlus 2.0",
@ -201,7 +211,7 @@ public class Sdk {
"Timestamp": now.millisecondsSince1970,
"TimestampFormatted": "\(timestampFormatted) GMT"
]
request.httpBody = try? JSONSerialization.data(withJSONObject: body)
request.allHTTPHeaderFields = [
@ -211,9 +221,54 @@ public class Sdk {
]
let signedRequest = try request.signed(with: certificate)
return URLSession.shared.dataTaskPublisher(for: signedRequest)
}
private func getStudents(symbol: String, deviceModel: String) {
let url = "\(self.endpointURL!)/\(symbol)/api/mobile/register/hebe"
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "GET"
let now = Date()
var vDate: String {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
dateFormatter.timeZone = TimeZone(secondsFromGMT: 0)
return "\(dateFormatter.string(from: now)) GMT"
}
let signatures = getSignatures(request: request, certificate: certificate)
request.setValue("\(signatures)", forHTTPHeaderField: "Signature")
request.allHTTPHeaderFields = [
"User-Agent": "wulkanowy/1 CFNetwork/1220.1 Darwin/20.1.0",
"vOS": "iOS",
"vDeviceModel": deviceModel,
"vAPI": "1",
"vDate": vDate,
"vCanonicalUrl": "api%2fmobile%2fregister%2fhebe"
]
let session = URLSession.shared
let task = session.dataTask(with: request) { (data, response, error) in
if let error = error {
// Handle HTTP request error
print(error)
} else if let data = data {
// Handle HTTP request response
print(String(data: data, encoding: String.Encoding.utf8) as Any)
} else {
// Handle unexpected error
}
}
task.resume()
}
// MARK: - Helper functions
/// Parses the response

View file

@ -0,0 +1,12 @@
//
// luckyNumber.swift
//
//
// Created by Tomasz on 27/02/2021.
//
import Foundation
public func getLuckyNumber() -> Int {
return 7
}

View file

@ -7,6 +7,7 @@
import Foundation
import CryptoKit
import KeychainAccess
@available (iOS 14, macOS 11, watchOS 7, tvOS 14, *)
public extension Sdk {

View file

@ -6,8 +6,19 @@
//
import SwiftUI
import KeychainAccess
import Sdk
struct DashboardView: View {
init() {
let keychain = Keychain()
let key = keychain["privateKey"]
let luckyNumber = getLuckyNumber()
print(luckyNumber)
}
var body: some View {
NavigationView {
VStack {

View file

@ -55,7 +55,6 @@ struct LoginView: View {
}
} else {
print("success")
}
}

View file

@ -52,9 +52,6 @@ final class VulcanStore: ObservableObject {
if let base64Encoded = utf8str?.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0)) {
let keychain = Keychain()
keychain[string: "privateKey"] = base64Encoded
let key = keychain["privateKey"]
print("Encoded: \(String(describing: key))")
}
}
@ -62,4 +59,3 @@ final class VulcanStore: ObservableObject {
}
}
}

View file

@ -8,6 +8,7 @@
import XCTest
@testable import wulkanowy
@available (iOS 14, macOS 11, watchOS 7, tvOS 14, *)
class wulkanowyTests: XCTestCase {
override func setUpWithError() throws {