[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.

151 lines
5.2 KiB

//
// AuthenticateViewController.swift
// elpha-ios
//
// Created by Dwayne Harris on 8/26/18.
// Copyright © 2018 Elpha. All rights reserved.
//
import Alamofire
import CoreData
import OAuthSwift
import UIKit
class AuthenticateViewController: UIViewController {
@IBOutlet var signInButton: UIButton!
@IBOutlet var instanceTextField: UITextField!
var oauthswift: OAuthSwift?
let defaultInstanceName = "mastodon.social"
override func viewDidLoad() {
super.viewDidLoad()
signInButton.layer.cornerRadius = 10
signInButton.clipsToBounds = true
randomInstanceName { instance in
self.instanceTextField.attributedPlaceholder = NSAttributedString(string: instance, attributes: [NSAttributedString.Key.foregroundColor: UIColor.init(red: 0.9, green: 0.9, blue: 0.9, alpha: 1)])
}
}
override open var shouldAutorotate: Bool {
return false
}
func randomInstanceName(completion: @escaping (String) -> Void) {
let requestURL = "\(Config.instancesServiceURL)\(Config.instancesServiceRandomEndpoint)?count=1"
let headers: HTTPHeaders = ["Authorization": "Bearer \(Config.instancesServiceSecret)"]
Alamofire.request(requestURL, headers: headers).validate().responseJSON { response in
switch response.result {
case .success(let value):
guard let result = value as? [String: Any],
let instances = result["instances"] as? [Any],
let instance = instances.first as? [String: Any],
let name = instance["name"] as? String else {
completion(self.defaultInstanceName)
return
}
completion(name)
case .failure(let error):
print("\(error)")
completion(self.defaultInstanceName)
}
}
}
func authorize(client: ClientMO) {
let oauthswift = OAuth2Swift(
consumerKey: client.clientID!,
consumerSecret: client.clientSecret!,
authorizeUrl: "https://\(client.host!)/oauth/authorize",
accessTokenUrl: "https://\(client.host!)/oauth/token",
responseType: "code"
)
oauthswift.authorizeURLHandler = OAuthSwiftOpenURLExternally.sharedInstance
self.oauthswift = oauthswift
let _ = oauthswift.authorize(
withCallbackURL: URL(string: "elpha://oauth")!,
scope: "read write follow",
state: NSUUID().uuidString,
success: { credential, _, _ in
let token = credential.oauthToken
let serverURL = URL(string: "https://\(client.host!)")
MastodonAPI.currentUser(token: token, serverURL: serverURL!) { data, error in
guard let data = data, error == nil else {
print("\(String(describing: error))")
return
}
let account = MastodonDataManager.upsertAccount(data)
_ = AuthenticationManager.saveSession(client: client, account: account!, token: credential.oauthToken)
self.dismiss(animated: true)
}
},
failure: { error in
print("\(error)")
}
)
}
@IBAction func signIn(_ sender: Any) {
guard var host = instanceTextField.text, !host.isEmpty else {
return
}
if host.contains("@") {
if let urlPart = host.split(separator: "@").last {
host = String(urlPart)
} else {
return
}
}
if host.starts(with: "https://") {
host = String(host.dropFirst(8))
}
if host.starts(with: "http://") {
host = String(host.dropFirst(7))
}
signInButton.isEnabled = false
defer {
signInButton.isEnabled = true
}
let request = NSFetchRequest<ClientMO>(entityName: "Client")
request.predicate = NSPredicate(format: "host == %@", host)
do {
let response = try CoreDataManager.shared.context.fetch(request)
if let client = response.first {
self.authorize(client: client)
} else {
MastodonAPI.registerApp(serverURL: URL(string: "https://\(host)")!) { data, error in
guard let data = data, error == nil else {
print("\(String(describing: error))")
return
}
let client = MastodonDataManager.saveClient(
id: data["id"] as! String,
clientID: data["client_id"] as! String,
clientSecret: data["client_secret"] as! String,
host: host
)
self.authorize(client: client)
}
}
} catch {
print("\(error)")
}
}
}