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

[feature/flat-mdm-settings] Support for MDM setting hierarchies with flat keys #904

Merged
merged 2 commits into from
Mar 1, 2021
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
49 changes: 41 additions & 8 deletions ownCloud/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -153,17 +153,19 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
return true
}

// If the app was re-installed, make sure to wipe keychain data. Since iOS 10.3 keychain entries are not deleted if the app is deleted, but since everything else is lost,
// it might lead to some inconsistency in the app state. Nevertheless we shall be careful here and consider that prior versions of the app didn't have the flag created upon
// very first app launch in UserDefaults. Thus we will check few more factors: no bookmarks configured and no passcode is set
if OCBookmarkManager.shared.bookmarks.count == 0 && AppLockManager.shared.lockEnabled == false {
VendorServices.shared.onFirstLaunch {
OCAppIdentity.shared.keychain?.wipe()
}
}
// If the app was re-installed, make sure to wipe keychain data. Since iOS 10.3 keychain entries are not deleted if the app is deleted, but since everything else is lost,
// it might lead to some inconsistency in the app state. Nevertheless we shall be careful here and consider that prior versions of the app didn't have the flag created upon
// very first app launch in UserDefaults. Thus we will check few more factors: no bookmarks configured and no passcode is set
if OCBookmarkManager.shared.bookmarks.count == 0 && AppLockManager.shared.lockEnabled == false {
VendorServices.shared.onFirstLaunch {
OCAppIdentity.shared.keychain?.wipe()
}
}

setupAndHandleCrashReports()

setupMDMPushRelaunch()

return true
}

Expand Down Expand Up @@ -271,3 +273,34 @@ extension AppDelegate {
crashReporter.enable()
}
}

extension AppDelegate : NotificationResponseHandler {
func setupMDMPushRelaunch() {
NotificationCenter.default.addObserver(self, selector: #selector(offerRelaunchAfterMDMPush), name: .OCClassSettingsManagedSettingsChanged, object: nil)
}

@objc func offerRelaunchAfterMDMPush() {
NotificationManager.shared.requestAuthorization(options: [.alert, .sound], completionHandler: { (granted, _) in
if granted {
let content = UNMutableNotificationContent()

content.title = "New settings received from MDM".localized
content.body = "Tap to quit the app.".localized

let request = UNNotificationRequest(identifier: NotificationManagerComposeIdentifier(AppDelegate.self, "terminate-app"), content: content, trigger: nil)

NotificationManager.shared.add(request, withCompletionHandler: { (_) in })
}
})
}

static func handle(_ center: UNUserNotificationCenter, response: UNNotificationResponse, identifier: String, completionHandler: @escaping () -> Void) {
if identifier == "terminate-app", response.actionIdentifier == UNNotificationDefaultActionIdentifier {
UNUserNotificationCenter.postLocalNotification(with: "mdm-relaunch", title: "Tap to launch the app.".localized, body: nil, after: 0.1) { (error) in
if error == nil {
exit(0)
}
}
}
}
}
5 changes: 5 additions & 0 deletions ownCloud/Resources/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -846,3 +846,8 @@
"Limited Photo Access" = "Limited Photo Access";
"Access for the media selected for upload is limited" = "Access for the media selected for upload is limited";
"No Access to the media selected for upload" = "No Access to the media selected for upload";

/* MDM settings push */
"New settings received from MDM" = "New settings received from MDM";
"Tap to quit the app." = "Tap to quit the app.";
"Tap to launch the app." = "Tap to launch the app.";
23 changes: 13 additions & 10 deletions ownCloud/Tasks/UNUserNotificationCenter+Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,29 @@
//

/*
* Copyright (C) 2020, ownCloud GmbH.
*
* This code is covered by the GNU Public License Version 3.
*
* For distribution utilizing Apple mechanisms please see https://owncloud.org/contribute/iOS-license-exception/
* You should have received a copy of this license along with this program. If not, see <http://www.gnu.org/licenses/gpl-3.0.en.html>.
*
*/
* Copyright (C) 2020, ownCloud GmbH.
*
* This code is covered by the GNU Public License Version 3.
*
* For distribution utilizing Apple mechanisms please see https://owncloud.org/contribute/iOS-license-exception/
* You should have received a copy of this license along with this program. If not, see <http://www.gnu.org/licenses/gpl-3.0.en.html>.
*
*/

import UserNotifications
import ownCloudApp

extension UNUserNotificationCenter {
class func postLocalNotification(with identifier:String, title:String, body:String, after:TimeInterval = 0.5, completion:((Error?) -> Void)? = nil) {
class func postLocalNotification(with identifier:String, title:String, body:String?, after:TimeInterval = 0.5, completion:((Error?) -> Void)? = nil) {
NotificationManager.shared.getNotificationSettings(completionHandler: { (settings) in
if settings.authorizationStatus == .authorized {
let content = UNMutableNotificationContent()

content.title = title
content.body = body

if let body = body {
content.body = body
}

let trigger = UNTimeIntervalNotificationTrigger(timeInterval: after, repeats: false)

Expand Down
3 changes: 2 additions & 1 deletion ownCloudAppFramework/Notifications/NotificationManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ NS_ASSUME_NONNULL_BEGIN
- (void)requestAuthorizationWithOptions:(UNAuthorizationOptions)options completionHandler:(void (^)(BOOL granted, NSError *__nullable error))completionHandler;
@end

#define ComposeNotificationIdentifier(aClass,identifier) [NSStringFromClass(aClass.class) stringByAppendingFormat:@":%@", identifier]
NSString *NotificationManagerComposeIdentifier(Class aClass, NSString *identifier);
#define ComposeNotificationIdentifier(aClass,identifier) NotificationManagerComposeIdentifier(aClass.class, identifier)

@protocol NotificationResponseHandler <NSObject>
+ (void)handleNotificationCenter:(UNUserNotificationCenter *)center response:(UNNotificationResponse *)response identifier:(NSString *)identifier completionHandler:(dispatch_block_t)completionHandler;
Expand Down
5 changes: 5 additions & 0 deletions ownCloudAppFramework/Notifications/NotificationManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,8 @@ - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNoti
}

@end

NSString *NotificationManagerComposeIdentifier(Class aClass, NSString *identifier)
{
return ([NSStringFromClass(aClass) stringByAppendingFormat:@":%@", identifier]);
}