Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #6421: debug setting to change FxA/sync servers #6426

Merged
merged 1 commit into from
Apr 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
250 changes: 62 additions & 188 deletions Client/Frontend/Settings/AdvancedAccountSettingViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,188 +8,94 @@ import SnapKit
import FxA
import Account

fileprivate class CustomFxAContentServerEnableSetting: BoolSetting {
init(prefs: Prefs, settingDidChange: ((Bool?) -> Void)? = nil) {
super.init(
prefs: prefs, prefKey: PrefsKeys.KeyUseCustomFxAContentServer, defaultValue: false,
attributedTitleText: NSAttributedString(string: Strings.SettingsAdvancedAccountUseCustomFxAContentServerURITitle),
settingDidChange: settingDidChange
)
}
}

fileprivate class CustomSyncTokenServerEnableSetting: BoolSetting {
init(prefs: Prefs, settingDidChange: ((Bool?) -> Void)? = nil) {
super.init(
prefs: prefs, prefKey: PrefsKeys.KeyUseCustomSyncTokenServerOverride, defaultValue: false,
attributedTitleText: NSAttributedString(string: Strings.SettingsAdvancedAccountUseCustomSyncTokenServerTitle),
settingDidChange: settingDidChange
)
}
}

fileprivate class CustomURLSetting: WebPageSetting {
override init(prefs: Prefs, prefKey: String, defaultValue: String? = nil, placeholder: String, accessibilityIdentifier: String, isChecked: @escaping () -> Bool = { return false }, settingDidChange: ((String?) -> Void)? = nil) {
super.init(prefs: prefs,
prefKey: prefKey,
defaultValue: defaultValue,
placeholder: placeholder,
accessibilityIdentifier: accessibilityIdentifier,
settingDidChange: settingDidChange)
textField.clearButtonMode = .always
}
}


class AdvancedAccountSettingViewController: SettingsTableViewController {
fileprivate let SectionHeaderIdentifier = "SectionHeaderIdentifier"

fileprivate var customAutoconfigURI: String?
fileprivate var customFxAContentURI: String?
fileprivate var customSyncTokenServerURI: String?

override func viewDidLoad() {
super.viewDidLoad()
title = Strings.SettingsAdvancedAccountTitle
self.customAutoconfigURI = self.profile.prefs.stringForKey(PrefsKeys.KeyCustomSyncWeb)
self.customFxAContentURI = self.profile.prefs.stringForKey(PrefsKeys.KeyCustomFxAContentServer)
self.customSyncTokenServerURI = self.profile.prefs.stringForKey(PrefsKeys.KeyCustomSyncTokenServerOverride)
}

func clearCustomAutoconfigPrefs() {
self.profile.prefs.setBool(false, forKey: PrefsKeys.KeyUseCustomAccountAutoconfig)
self.profile.prefs.setString("", forKey: PrefsKeys.KeyCustomSyncToken)
self.profile.prefs.setString("", forKey: PrefsKeys.KeyCustomSyncProfile)
self.profile.prefs.setString("", forKey: PrefsKeys.KeyCustomSyncOauth)
self.profile.prefs.setString("", forKey: PrefsKeys.KeyCustomSyncAuth)
self.profile.prefs.setString("", forKey: PrefsKeys.KeyCustomSyncWeb)

// To help prevent the account being in a strange state, we force it to
// log out when user clears their custom server preferences.
self.profile.removeAccount()
}

func setCustomAutoconfigPrefs() {
guard let customAutoconfigURIString = self.customAutoconfigURI, let customAutoconfigURI = URL(string: customAutoconfigURIString), customAutoconfigURI.schemeIsValid, customAutoconfigURI.host != nil else {
// If the user attempts to set a nil url, clear all the custom service perferences
// and use default FxA servers.
self.displayNoAutoconfigSetAlert()
return
}

// FxA stores its server configuation under a well-known path. This attempts to download the configuration
// and save it into the users preferences.
let syncConfigureString = customAutoconfigURIString + "/.well-known/fxa-client-configuration"
guard let syncConfigureURL = URL(string: syncConfigureString) else {
return
}

URLSession.shared.dataTask(with: syncConfigureURL, completionHandler: {(data, response, error) in
guard error == nil,
let data = data,
let json = (try? JSONSerialization.jsonObject(with: data, options: .allowFragments)) as? [String: Any],
let customSyncToken = json["sync_tokenserver_base_url"] as? String,
let customSyncProfile = json["profile_server_base_url"] as? String,
let customSyncOauth = json["oauth_server_base_url"] as? String,
let customSyncAuth = json["auth_server_base_url"] as? String else {

// Something went wrong while downloading or parsing the configuration.
self.displayAutoconfigErrorAlert()
return
}

self.profile.prefs.setBool(true, forKey: PrefsKeys.KeyUseCustomAccountAutoconfig)
self.profile.prefs.setString(customSyncToken, forKey: PrefsKeys.KeyCustomSyncToken)
self.profile.prefs.setString(customSyncProfile, forKey: PrefsKeys.KeyCustomSyncProfile)
self.profile.prefs.setString(customSyncOauth, forKey: PrefsKeys.KeyCustomSyncOauth)
self.profile.prefs.setString(customSyncAuth, forKey: PrefsKeys.KeyCustomSyncAuth)
self.profile.prefs.setString(customAutoconfigURI.absoluteString, forKey: PrefsKeys.KeyCustomSyncWeb)
self.profile.removeAccount()
self.displaySuccessAlert()
}).resume()
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
RustFirefoxAccounts.reconfig()
}

func clearCustomSyncTokenServerPrefs() {
self.profile.prefs.setBool(false, forKey: PrefsKeys.KeyUseCustomSyncTokenServerOverride)
self.profile.prefs.setString("", forKey: PrefsKeys.KeyCustomSyncTokenServerOverride)
}

func setCustomSyncTokenServerPrefs() {
guard let customSyncTokenServerURIString = self.customSyncTokenServerURI, let customSyncTokenServerURI = URL(string: customSyncTokenServerURIString), customSyncTokenServerURI.schemeIsValid, customSyncTokenServerURI.host != nil else {
// If the user attempts to set a nil url, clear all the custom service perferences
// and use default FxA servers.
self.displayNoTokenServerSetAlert()
return
}

self.profile.prefs.setBool(true, forKey: PrefsKeys.KeyUseCustomSyncTokenServerOverride)
self.profile.prefs.setString(customSyncTokenServerURI.absoluteString, forKey: PrefsKeys.KeyCustomSyncTokenServerOverride)
self.displaySuccessAlert()
}

func displaySuccessAlert() {
let alertController = UIAlertController(title: "", message: Strings.SettingsAdvancedAccountUrlUpdatedAlertMessage, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: Strings.OKString, style: .default, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true)
}

func displayAutoconfigErrorAlert() {
self.profile.prefs.setBool(false, forKey: PrefsKeys.KeyUseCustomAccountAutoconfig)
DispatchQueue.main.async {
self.tableView.reloadRows(at: [IndexPath(row: 0, section: 0)], with: .automatic)
}
let alertController = UIAlertController(title: Strings.SettingsAdvancedAccountUrlErrorAlertTitle, message: Strings.SettingsAdvancedAccountUrlErrorAlertMessage, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: Strings.OKString, style: .default, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true)
}
override func generateSettings() -> [SettingSection] {
let prefs = profile.prefs

func displayNoAutoconfigSetAlert() {
self.profile.prefs.setBool(false, forKey: PrefsKeys.KeyUseCustomAccountAutoconfig)
DispatchQueue.main.async {
self.tableView.reloadRows(at: [IndexPath(row: 0, section: 0)], with: .automatic)
let useStage = BoolSetting(prefs: prefs, prefKey: PrefsKeys.UseStageServer, defaultValue: false, attributedTitleText: NSAttributedString(string: NSLocalizedString("Use stage servers", comment: "Debug option"), attributes: [NSAttributedString.Key.foregroundColor: UIColor.theme.tableView.rowText]))
{ isOn in
self.settings = self.generateSettings()
self.tableView.reloadData()
}
let alertController = UIAlertController(title: Strings.SettingsAdvancedAccountUrlErrorAlertTitle, message: Strings.SettingsAdvancedAccountEmptyAutoconfigURIErrorAlertMessage, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: Strings.OKString, style: .default, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true)
}

func displayNoTokenServerSetAlert() {
self.profile.prefs.setBool(false, forKey: PrefsKeys.KeyUseCustomSyncTokenServerOverride)
DispatchQueue.main.async {
self.tableView.reloadRows(at: [IndexPath(row: 0, section: 2)], with: .automatic)
}
let alertController = UIAlertController(title: Strings.SettingsAdvancedAccountUrlErrorAlertTitle, message: Strings.SettingsAdvancedAccountEmptyTokenServerURIErrorAlertMessage, preferredStyle: .alert)
let defaultAction = UIAlertAction(title: Strings.OKString, style: .default, handler: nil)
alertController.addAction(defaultAction)
self.present(alertController, animated: true)
}
let customFxA = CustomURLSetting(prefs: prefs,
prefKey: PrefsKeys.KeyCustomFxAContentServer,
placeholder: Strings.SettingsAdvancedAccountCustomFxAContentServerURI,
accessibilityIdentifier: "CustomFxAContentServer")

override func generateSettings() -> [SettingSection] {
let prefs = profile.prefs
let customAutoconfigURISetting = CustomURLSetting(prefs: prefs,
prefKey: PrefsKeys.KeyCustomSyncWeb,
placeholder: Strings.SettingsAdvancedAccountCustomAutoconfigURIPlaceholder,
accessibilityIdentifier: "CustomAutoconfigURISetting",
settingDidChange: { fieldText in
self.customAutoconfigURI = fieldText
if let customAutoconfigURI = self.customAutoconfigURI, customAutoconfigURI.isEmpty {
self.clearCustomAutoconfigPrefs()
return
}
})
let customSyncTokenServerURISetting = CustomURLSetting(prefs: prefs,
prefKey: PrefsKeys.KeyCustomSyncTokenServerOverride,
placeholder: Strings.SettingsAdvancedAccountCustomSyncTokenServerURIPlaceholder,
accessibilityIdentifier: "CustomSyncTokenServerURISetting",
settingDidChange: { fieldText in
self.customSyncTokenServerURI = fieldText
if let customSyncTokenServerURI = self.customSyncTokenServerURI, customSyncTokenServerURI.isEmpty {
self.clearCustomSyncTokenServerPrefs()
return
}
})
prefKey: PrefsKeys.KeyCustomSyncTokenServerOverride,
placeholder: Strings.SettingsAdvancedAccountCustomSyncTokenServerURI,
accessibilityIdentifier: "CustomSyncTokenServerURISetting")

let autoconfigSettings = [
CustomAutoconfigEnableSetting(
prefs: prefs,
settingDidChange: { result in
if result == true {
// Reload the table data to ensure that the updated value is set
self.tableView?.reloadData()
self.setCustomAutoconfigPrefs()
}
}),
customAutoconfigURISetting
CustomFxAContentServerEnableSetting(prefs: prefs) { isOn in
self.settings = self.generateSettings()
self.tableView.reloadData()
},
customFxA
]

let tokenServerSettings = [
CustomSyncTokenServerEnableSetting(
prefs: prefs,
settingDidChange: { result in
if result == true {
// Reload the table data to ensure that the updated value is set
self.tableView?.reloadData()
self.setCustomSyncTokenServerPrefs()
}
}),
CustomSyncTokenServerEnableSetting(prefs: prefs),
customSyncTokenServerURISetting
]

let settings: [SettingSection] = [
SettingSection(title: nil, children: autoconfigSettings),
SettingSection(title: NSAttributedString(string: Strings.SettingsAdvancedAccountAutoconfigSectionFooter), children: []),
SettingSection(title: nil, children: tokenServerSettings),
SettingSection(title: NSAttributedString(string: Strings.SettingsAdvancedAccountTokenServerSectionFooter), children: [])
]
var settings: [SettingSection] = [SettingSection(title:nil, children: [useStage])]

if !(prefs.boolForKey(PrefsKeys.UseStageServer) ?? false) {
settings.append(SettingSection(title: nil, children: autoconfigSettings))
settings.append(SettingSection(title: nil, children: tokenServerSettings))
}
return settings
}

Expand All @@ -208,35 +114,3 @@ class AdvancedAccountSettingViewController: SettingsTableViewController {
return headerView
}
}

class CustomAutoconfigEnableSetting: BoolSetting {
init(prefs: Prefs, settingDidChange: ((Bool?) -> Void)? = nil) {
super.init(
prefs: prefs, prefKey: PrefsKeys.KeyUseCustomAccountAutoconfig, defaultValue: false,
attributedTitleText: NSAttributedString(string: Strings.SettingsAdvancedAccountUseCustomAccountsServiceTitle),
settingDidChange: settingDidChange
)
}
}

class CustomSyncTokenServerEnableSetting: BoolSetting {
init(prefs: Prefs, settingDidChange: ((Bool?) -> Void)? = nil) {
super.init(
prefs: prefs, prefKey: PrefsKeys.KeyUseCustomSyncTokenServerOverride, defaultValue: false,
attributedTitleText: NSAttributedString(string: Strings.SettingsAdvancedAccountUseCustomSyncTokenServerTitle),
settingDidChange: settingDidChange
)
}
}

class CustomURLSetting: WebPageSetting {
override init(prefs: Prefs, prefKey: String, defaultValue: String? = nil, placeholder: String, accessibilityIdentifier: String, isChecked: @escaping () -> Bool = { return false }, settingDidChange: ((String?) -> Void)? = nil) {
super.init(prefs: prefs,
prefKey: prefKey,
defaultValue: defaultValue,
placeholder: placeholder,
accessibilityIdentifier: accessibilityIdentifier,
settingDidChange: settingDidChange)
textField.clearButtonMode = .always
}
}
48 changes: 12 additions & 36 deletions Client/Frontend/Settings/AppSettingsOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -465,10 +465,21 @@ class SlowTheDatabase: HiddenSetting {
}
}

class ForgetSyncAuthStateDebugSetting: HiddenSetting {
override var title: NSAttributedString? {
return NSAttributedString(string: NSLocalizedString("Debug: forget Sync auth state", comment: "Debug option"), attributes: [NSAttributedString.Key.foregroundColor: UIColor.theme.tableView.rowText])
}

override func onClick(_ navigationController: UINavigationController?) {
settings.profile.rustFxA.syncAuthState.invalidate()
settings.tableView.reloadData()
}
}

class SentryIDSetting: HiddenSetting {
let deviceAppHash = UserDefaults(suiteName: AppInfo.sharedContainerIdentifier)?.string(forKey: "SentryDeviceAppHash") ?? "0000000000000000000000000000000000000000"
override var title: NSAttributedString? {
return NSAttributedString(string: "Debug: \(deviceAppHash)", attributes: [NSAttributedString.Key.foregroundColor: UIColor.theme.tableView.rowText, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 10)])
return NSAttributedString(string: "Sentry ID: \(deviceAppHash)", attributes: [NSAttributedString.Key.foregroundColor: UIColor.theme.tableView.rowText, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 10)])
}

override func onClick(_ navigationController: UINavigationController?) {
Expand Down Expand Up @@ -846,41 +857,6 @@ class ChinaSyncServiceSetting: WithoutAccountSetting {
}
}

class StageSyncServiceDebugSetting: WithoutAccountSetting {
override var accessoryType: UITableViewCell.AccessoryType { return .none }
var prefs: Prefs { return settings.profile.prefs }

var prefKey: String = "useStageSyncService"

override var accessibilityIdentifier: String? { return "DebugStageSync" }

override var hidden: Bool {
if !ShowDebugSettings {
return true
}
return false
}

override var title: NSAttributedString? {
return NSAttributedString(string: NSLocalizedString("Debug: use stage servers", comment: "Debug option"), attributes: [NSAttributedString.Key.foregroundColor: UIColor.theme.tableView.rowText])
}

override func onConfigureCell(_ cell: UITableViewCell) {
super.onConfigureCell(cell)
let control = UISwitchThemed()
control.onTintColor = UIColor.theme.tableView.controlTint
control.addTarget(self, action: #selector(switchValueChanged), for: .valueChanged)
control.isOn = prefs.boolForKey(prefKey) ?? false
cell.accessoryView = control
cell.selectionStyle = .none
}

@objc func switchValueChanged(_ toggle: UISwitch) {
prefs.setObject(toggle.isOn, forKey: prefKey)
settings.tableView.reloadData()
}
}

class NewTabPageSetting: Setting {
let profile: Profile

Expand Down
8 changes: 2 additions & 6 deletions Client/Frontend/Settings/AppSettingsTableViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,6 @@ class AppSettingsTableViewController: SettingsTableViewController {
var settings = [SettingSection]()

let privacyTitle = NSLocalizedString("Privacy", comment: "Privacy section title")
let accountDebugSettings = [
// Debug settings:
//ForgetSyncAuthStateDebugSetting(settings: self),
StageSyncServiceDebugSetting(settings: self),
]

let prefs = profile.prefs
var generalSettings: [Setting] = [
Expand Down Expand Up @@ -95,7 +90,7 @@ class AppSettingsTableViewController: SettingsTableViewController {
// With a Firefox Account:
AccountStatusSetting(settings: self),
SyncNowSetting(settings: self)
] + accountChinaSyncSetting + accountDebugSettings)]
] + accountChinaSyncSetting )]

settings += [ SettingSection(title: NSAttributedString(string: Strings.SettingsGeneralSectionTitle), children: generalSettings)]

Expand Down Expand Up @@ -136,6 +131,7 @@ class AppSettingsTableViewController: SettingsTableViewController {
DeleteExportedDataSetting(settings: self),
ForceCrashSetting(settings: self),
SlowTheDatabase(settings: self),
ForgetSyncAuthStateDebugSetting(settings: self),
SentryIDSetting(settings: self),
])]

Expand Down
Loading