Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 11
Follow OrgRules to forbid backups keys#376
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
Uh oh!
There was an error while loading. Please reload this page.
Changes from all commits
85b4d29dec96d6d08dd2af1bba06474ca4258ea373a3c6a6c20b1ec9File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -53,19 +53,22 @@ final class SetupInitialViewController: TableNodeViewController { | ||
| private let user: UserId | ||
| private let router: GlobalRouterType | ||
| private let decorator: SetupViewDecorator | ||
| private let organisationalRules: OrganisationalRules | ||
| private lazy var logger = Logger.nested(in: Self.self, with: .setup) | ||
| init( | ||
| user: UserId, | ||
| backupService: BackupServiceType = BackupService(), | ||
| router: GlobalRouterType = GlobalRouter(), | ||
| decorator: SetupViewDecorator = SetupViewDecorator() | ||
| decorator: SetupViewDecorator = SetupViewDecorator(), | ||
| organisationalRulesService: OrganisationalRulesServiceType = OrganisationalRulesService() | ||
| ) { | ||
| self.user = user | ||
| self.backupService = backupService | ||
| self.router = router | ||
| self.decorator = decorator | ||
| self.organisationalRules = organisationalRulesService.getSavedOrganisationalRulesForCurrentUser() | ||
ekievsky marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| super.init(node: TableNode()) | ||
| } | ||
| @@ -103,6 +106,12 @@ extension SetupInitialViewController { | ||
| } | ||
| private func searchBackups() { | ||
| if !organisationalRules.canBackupKeys { | ||
| logger.logInfo("Skipping backups searching because canBackupKeys == false") | ||
| proceedToSetupWith(keys: []) | ||
| return | ||
| } | ||
| logger.logInfo("Searching for backups in inbox") | ||
| backupService.fetchBackupsFromInbox(for: user) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -113,12 +113,15 @@ extension EncryptedStorage: LogOutHandler { | ||
| .filter { keys.map(\.primaryLongid).contains($0.longid) } | ||
| let sessions = storage.objects(SessionObject.self) | ||
| .filter { $0.email == email } | ||
| let clientConfigurations = storage.objects(ClientConfigurationObject.self) | ||
| .filter { $0.userEmail == email } | ||
| try storage.write { | ||
| storage.delete(keys) | ||
| storage.delete(sessions) | ||
| storage.delete(passPhrases) | ||
| storage.delete(userToDelete) | ||
| storage.delete(clientConfigurations) | ||
Comment on lines
123
to
+124
Collaborator There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Kharchevskyi does the order of items matter here? If there are some foreign keys then we probably need to delete the user last? Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think in this case - yes. | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -12,8 +12,21 @@ protocol EnterpriseServerApiType { | ||
| func getActiveFesUrl(for email: String) -> Promise<String?> | ||
Collaborator There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Changes in this file are very good, thanks | ||
| func getActiveFesUrlForCurrentUser() -> Promise<String?> | ||
| func getClientConfiguration(for email: String) -> Promise<ClientConfiguration?> | ||
| func getClientConfigurationForCurrentUser() -> Promise<ClientConfiguration?> | ||
| func getClientConfiguration(for email: String) -> Promise<ClientConfiguration> | ||
| func getClientConfigurationForCurrentUser() -> Promise<ClientConfiguration> | ||
| } | ||
| enum EnterpriseServerApiError: Error { | ||
| case parse | ||
| case emailFormat | ||
| } | ||
| extension EnterpriseServerApiError: LocalizedError { | ||
| var errorDescription: String? { | ||
| switch self { | ||
| case .parse: return "organisational_rules_parse_error_description".localized | ||
| case .emailFormat: return "organisational_rules_email_format_error_description".localized | ||
| } | ||
| } | ||
| } | ||
| class EnterpriseServerApi: EnterpriseServerApiType { | ||
| @@ -71,11 +84,14 @@ class EnterpriseServerApi: EnterpriseServerApiType { | ||
| .recoverFromTimeOut(result: nil) | ||
| } | ||
| func getClientConfiguration(for email: String) -> Promise<ClientConfiguration?> { | ||
| Promise<ClientConfiguration?> { resolve, _ in | ||
| guard let userDomain = email.recipientDomain, | ||
| !Configuration.publicEmailProviderDomains.contains(userDomain) else { | ||
| resolve(nil) | ||
| func getClientConfiguration(for email: String) -> Promise<ClientConfiguration> { | ||
| Promise<ClientConfiguration> { resolve, reject in | ||
| guard let userDomain = email.recipientDomain else { | ||
| reject(EnterpriseServerApiError.emailFormat) | ||
| return | ||
| } | ||
| if Configuration.publicEmailProviderDomains.contains(userDomain) { | ||
| resolve(.empty) | ||
| return | ||
| } | ||
| let request = URLRequest.urlRequest( | ||
| @@ -93,17 +109,18 @@ class EnterpriseServerApi: EnterpriseServerApiType { | ||
| from: safeReponse.data | ||
| ))?.clientConfiguration | ||
| else { | ||
| resolve(nil) | ||
| reject(EnterpriseServerApiError.parse) | ||
| return | ||
| } | ||
| resolve(clientConfiguration) | ||
| } | ||
| } | ||
| func getClientConfigurationForCurrentUser() -> Promise<ClientConfiguration?> { | ||
| func getClientConfigurationForCurrentUser() -> Promise<ClientConfiguration> { | ||
| guard let email = DataService.shared.currentUser?.email else { | ||
| return Promise<ClientConfiguration?> { resolve, _ in | ||
| resolve(nil) | ||
| return Promise<ClientConfiguration> { _, reject in | ||
| assertionFailure("User has to be set while getting client configuration") | ||
| reject(AppErr.user("currentUser == nil")) | ||
| } | ||
| } | ||
| return getClientConfiguration(for: email) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -12,6 +12,8 @@ import Promises | ||
| protocol OrganisationalRulesServiceType { | ||
| func fetchOrganisationalRulesForCurrentUser() -> Promise<OrganisationalRules> | ||
| func fetchOrganisationalRules(for email: String) -> Promise<OrganisationalRules> | ||
| func getSavedOrganisationalRulesForCurrentUser() -> OrganisationalRules | ||
| } | ||
| final class OrganisationalRulesService { | ||
| @@ -41,26 +43,36 @@ extension OrganisationalRulesService: OrganisationalRulesServiceType { | ||
| } | ||
| func fetchOrganisationalRules(for email: String) -> Promise<OrganisationalRules> { | ||
| Promise<OrganisationalRules> { [weak self] resolve, reject in | ||
| Promise<OrganisationalRules> { [weak self] resolve, _ in | ||
| guard let self = self else { throw AppErr.nilSelf } | ||
| guard let clientConfigurationResponse = try awaitPromise( | ||
| self.enterpriseServerApi.getClientConfiguration(for: email) | ||
| ) else { | ||
| reject(OrganisationalRulesServiceError.parse) | ||
| return | ||
| } | ||
| guard let organisationalRules = OrganisationalRules( | ||
| clientConfiguration: clientConfigurationResponse, | ||
| email: email | ||
| ) else { | ||
| reject(OrganisationalRulesServiceError.emailFormat) | ||
| return | ||
| } | ||
| let clientConfigurationResponse = try awaitPromise( | ||
| self.enterpriseServerApi.getClientConfiguration(for: email) | ||
| ) | ||
| let organisationalRules = OrganisationalRules( | ||
| clientConfiguration: clientConfigurationResponse | ||
| ) | ||
| self.clientConfigurationProvider.save(clientConfiguration: clientConfigurationResponse) | ||
| resolve(organisationalRules) | ||
| } | ||
| .recover { [weak self] error -> OrganisationalRules in | ||
| guard let self = self else { throw AppErr.nilSelf } | ||
| guard let clientConfig = self.clientConfigurationProvider.fetch() else { | ||
| throw error | ||
| } | ||
| return OrganisationalRules(clientConfiguration: clientConfig) | ||
| } | ||
| } | ||
| func getSavedOrganisationalRulesForCurrentUser() -> OrganisationalRules { | ||
| guard let configuration = self.clientConfigurationProvider.fetch() else { | ||
| assertionFailure("There should not be a user without OrganisationalRules") | ||
Collaborator There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does | ||
| return OrganisationalRules(clientConfiguration: .empty) | ||
| } | ||
| return OrganisationalRules(clientConfiguration: configuration) | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -20,6 +20,13 @@ enum ClientConfigurationFlag: String, Codable { | ||
| case useLegacyAttesterSubmit = "USE_LEGACY_ATTESTER_SUBMIT" | ||
| case defaultRememberPassphrase = "DEFAULT_REMEMBER_PASS_PHRASE" | ||
| case hideArmorMeta = "HIDE_ARMOR_META" | ||
| case forbidStoringPassphrase = "FORBID_STORING_PASS_PHRASE" | ||
| case unknown | ||
tomholub marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| init(from decoder: Decoder) throws { | ||
| self = try ClientConfigurationFlag(rawValue: decoder.singleValueContainer().decode(RawValue.self)) ?? .unknown | ||
| } | ||
| } | ||
| struct ClientConfiguration: Codable, Equatable { | ||
| @@ -32,6 +39,20 @@ struct ClientConfiguration: Codable, Equatable { | ||
| let enforceKeygenExpireMonths: Int? | ||
| } | ||
| // MARK: - Empty model | ||
| extension ClientConfiguration { | ||
| static var empty: ClientConfiguration { | ||
| return ClientConfiguration( | ||
| flags: [], | ||
| customKeyserverUrl: nil, | ||
| keyManagerUrl: nil, | ||
| disallowAttesterSearchForDomains: nil, | ||
| enforceKeygenAlgo: nil, | ||
| enforceKeygenExpireMonths: nil | ||
| ) | ||
| } | ||
| } | ||
| // MARK: - Map from realm model | ||
| extension ClientConfiguration { | ||
| init?(_ object: ClientConfigurationObject?) { | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.