[ABANDONED] Mastodon iOS client.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
5.2 KiB

6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
6 years ago
  1. //
  2. // AuthenticationManager.swift
  3. // elpha-ios
  4. //
  5. // Created by Dwayne Harris on 8/25/18.
  6. // Copyright © 2018 Elpha. All rights reserved.
  7. //
  8. import Alamofire
  9. import CoreData
  10. import UIKit
  11. protocol AuthenticationDelegate: class {
  12. func authenticationSuccess(_ sender: Any)
  13. func authenticationFailure(_ sender: Any, error: Error?)
  14. }
  15. class AuthenticationManager {
  16. static var authenticationState: String?
  17. static var authenticationClient: ClientMO?
  18. static weak var authenticationDelegate: AuthenticationDelegate?
  19. static var sessions: [SessionMO] {
  20. get {
  21. do {
  22. let request = NSFetchRequest<SessionMO>(entityName: "Session")
  23. return try CoreDataManager.shared.context.fetch(request)
  24. } catch {
  25. print("Error fetching Sessions \(error)")
  26. return []
  27. }
  28. }
  29. }
  30. static var session: SessionMO? {
  31. get {
  32. let request = NSFetchRequest<SessionMO>(entityName: "Session")
  33. request.predicate = NSPredicate(format: "selected = YES")
  34. do {
  35. let results = try CoreDataManager.shared.context.fetch(request)
  36. return results.first
  37. } catch {
  38. print("Error fetching Session \(error)")
  39. return nil
  40. }
  41. }
  42. }
  43. static var token: String? {
  44. get {
  45. guard let account = session?.account, let client = session?.client else {
  46. return nil
  47. }
  48. return KeychainWrapper.standard.string(forKey: "token:\(account.username!)@\(client.host!)")
  49. }
  50. }
  51. static func saveSession(client: ClientMO, account: AccountMO, token: String) -> SessionMO? {
  52. if let session = self.session {
  53. session.selected = false
  54. }
  55. let session = SessionMO(context: CoreDataManager.shared.context)
  56. session.client = client
  57. session.account = account
  58. session.order = 0
  59. session.createdAt = Date()
  60. session.selected = true
  61. CoreDataManager.shared.saveContext()
  62. KeychainWrapper.standard.set(token, forKey: "token:\(account.username!)@\(client.host!)")
  63. return session
  64. }
  65. static func deleteSelectedSession() {
  66. guard let session = self.session else {
  67. return
  68. }
  69. KeychainWrapper.standard.removeObject(forKey: "token:\(session.account!.username!)@\(session.client!.host!)")
  70. CoreDataManager.shared.context.delete(session)
  71. }
  72. static func handle(url: URL) {
  73. guard let state = authenticationState, let client = authenticationClient else {
  74. return
  75. }
  76. if let components = URLComponents(url: url, resolvingAgainstBaseURL: false), let queryItems = components.queryItems {
  77. var code: String?
  78. for item in queryItems {
  79. switch item.name.lowercased() {
  80. case "code":
  81. code = item.value
  82. case "state":
  83. if item.value != state {
  84. self.authenticationDelegate?.authenticationFailure(self, error: nil)
  85. return
  86. }
  87. default:
  88. continue
  89. }
  90. }
  91. let parameters: Parameters = [
  92. "client_id": client.clientID!,
  93. "client_secret": client.clientSecret!,
  94. "grant_type": "authorization_code",
  95. "code": code!,
  96. "redirect_uri": Config.clientRedirectURI,
  97. ]
  98. Alamofire.request(
  99. "https://\(client.host!)/oauth/token",
  100. method: .post,
  101. parameters: parameters,
  102. encoding: URLEncoding.default
  103. ).validate().responseJSON { response in
  104. switch response.result {
  105. case .success(let data):
  106. let serverURL = URL(string: "https://\(client.host!)")
  107. if let json = data as? [String: Any], let token = json["access_token"] as? String {
  108. MastodonAPI.currentUser(token: token, serverURL: serverURL!) { data, error in
  109. guard let data = data, error == nil else {
  110. AlertManager.shared.show(message: error!.localizedDescription, category: .error)
  111. return
  112. }
  113. let account = MastodonDataManager.upsertAccount(data)
  114. _ = AuthenticationManager.saveSession(client: client, account: account!, token: token)
  115. self.authenticationDelegate?.authenticationSuccess(self)
  116. }
  117. }
  118. case .failure(let error):
  119. self.authenticationDelegate?.authenticationFailure(self, error: error)
  120. }
  121. }
  122. }
  123. }
  124. }