From 7095d556704fb3c148d3e5240808dbc0fb9dc490 Mon Sep 17 00:00:00 2001 From: Michael Starke Date: Mon, 21 Sep 2020 17:44:15 +0200 Subject: [PATCH] Adjusted checks for auto-type permissions We do not need to check for screen recording permissions, if auto-type is executed. Only global auto-type requires screen recording permissions and should check for them. --- MacPass/MPAutotypeDaemon.m | 17 +++++++++-------- MacPass/MPAutotypeDoctor.h | 6 +++++- MacPass/MPAutotypeDoctor.m | 17 ++++++++++------- MacPass/MPAutotypeEnvironment.h | 10 ++++++++-- MacPass/MPAutotypeEnvironment.m | 4 ++++ MacPass/MPIntegrationPreferencesController.m | 2 +- 6 files changed, 37 insertions(+), 19 deletions(-) diff --git a/MacPass/MPAutotypeDaemon.m b/MacPass/MPAutotypeDaemon.m index 0fbce36c..f16bb7d1 100644 --- a/MacPass/MPAutotypeDaemon.m +++ b/MacPass/MPAutotypeDaemon.m @@ -55,7 +55,6 @@ @property (strong) NSRunningApplication *previousApplication; // The application that was active before we got invoked @property (assign) NSTimeInterval userActionRequested; @property (strong) id applicationActivationObserver; -@property (nonatomic, readonly) BOOL hasNecessaryAutotypePermissions; @end @implementation MPAutotypeDaemon @@ -131,10 +130,6 @@ static MPAutotypeDaemon *_sharedInstance; } } -- (BOOL)hasNecessaryAutotypePermissions { - return MPAutotypeDoctor.defaultDoctor.hasNecessaryAutotypePermissions; -} - #pragma mark - #pragma mark Autotype Invocation - (void)performAutotypeForEntry:(KPKEntry *)entry { @@ -149,7 +144,7 @@ static MPAutotypeDaemon *_sharedInstance; } - (void)_didPressHotKey { - MPAutotypeEnvironment *env = [MPAutotypeEnvironment environmentWithTargetApplication:NSWorkspace.sharedWorkspace.frontmostApplication entry:nil overrideSequence:nil]; + MPAutotypeEnvironment *env = [MPAutotypeEnvironment environmentWithTargetApplication:nil entry:nil overrideSequence:nil]; [self _runAutotypeWithEnvironment:env]; } @@ -193,8 +188,14 @@ static MPAutotypeDaemon *_sharedInstance; if(env.isSelfTargeting) { return; // we do not want to target ourselves } - - if(!self.hasNecessaryAutotypePermissions) { + BOOL hasNeededPermissions = NO; + if(env.globalAutotype) { + hasNeededPermissions = [MPAutotypeDoctor.defaultDoctor hasNecessaryPermissionForTask:MPAutotypeTaskGlobalAutotype]; + } + else { + hasNeededPermissions = [MPAutotypeDoctor.defaultDoctor hasNecessaryPermissionForTask:MPAutotypeTaskAutotype]; + } + if(!hasNeededPermissions) { NSUserNotification *notification = [[NSUserNotification alloc] init]; notification.title = NSLocalizedString(@"AUTOTYPE_NOTIFICATION_PERMISSIONS_MISSING_TITLE", "Title for autotype feedback on missing permissions"); notification.informativeText = NSLocalizedString(@"AUTOTYPE_NOTIFICATION_MACPASS_IS_MISSING_PERMISSIONS", "Notification: Autotype failed, MacPass has not enough permissions to perform autotype"); diff --git a/MacPass/MPAutotypeDoctor.h b/MacPass/MPAutotypeDoctor.h index 55d02a3b..b2edc5a1 100644 --- a/MacPass/MPAutotypeDoctor.h +++ b/MacPass/MPAutotypeDoctor.h @@ -12,10 +12,14 @@ NS_ASSUME_NONNULL_BEGIN @interface MPAutotypeDoctor : NSObject +typedef NS_ENUM(NSUInteger, MPAutotypeTask) { + MPAutotypeTaskAutotype, + MPAutotypeTaskGlobalAutotype +}; @property (class, readonly, strong) MPAutotypeDoctor *defaultDoctor; -@property (nonatomic, readonly) BOOL hasNecessaryAutotypePermissions; // MacPass has all the permissions it needs to run autotype on the current system +- (BOOL)hasNecessaryPermissionForTask:(MPAutotypeTask)task; - (BOOL)hasScreenRecordingPermissions:(NSError *__autoreleasing*)error; - (BOOL)hasAccessibiltyPermissions:(NSError *__autoreleasing*)error; diff --git a/MacPass/MPAutotypeDoctor.m b/MacPass/MPAutotypeDoctor.m index 4ab90555..32407258 100644 --- a/MacPass/MPAutotypeDoctor.m +++ b/MacPass/MPAutotypeDoctor.m @@ -51,14 +51,17 @@ return instance; } -- (BOOL)hasNecessaryAutotypePermissions { - if(![self hasAccessibiltyPermissions:NULL]) { - return NO; +- (BOOL)hasNecessaryPermissionForTask:(MPAutotypeTask)task { + BOOL permissionsOK = YES; + switch(task) { + case MPAutotypeTaskGlobalAutotype: + permissionsOK &= [self hasScreenRecordingPermissions:NULL]; + // fallthrough! + case MPAutotypeTaskAutotype: + permissionsOK &= [self hasAccessibiltyPermissions:NULL]; + break; } - if(![self hasScreenRecordingPermissions:NULL]) { - return NO; - } - return YES; + return permissionsOK; } - (BOOL)hasScreenRecordingPermissions:(NSError *__autoreleasing*)error { diff --git a/MacPass/MPAutotypeEnvironment.h b/MacPass/MPAutotypeEnvironment.h index c805327c..2b033c3b 100644 --- a/MacPass/MPAutotypeEnvironment.h +++ b/MacPass/MPAutotypeEnvironment.h @@ -25,9 +25,15 @@ NS_ASSUME_NONNULL_BEGIN @property (readonly) BOOL hidden; /// If set to YES, MacPass was hidden when autotype was initiated @property (readonly) BOOL isSelfTargeting; /// If MacPass should autotype to itself, YES, otherwise NO @property (readonly) NSString *overrideSequence; /// If set, this sequence is used for running the command regardless of the matched one +@property (readonly) BOOL globalAutotype; -+ (instancetype)environmentWithTargetApplication:(NSRunningApplication *)targetApplication entry:(KPKEntry * _Nullable)entry overrideSequence:(NSString * _Nullable)overrideSequence; -- (instancetype)initWithTargetApplication:(NSRunningApplication *)targetApplication entry:(KPKEntry * _Nullable)entry overrideSequence:(NSString * _Nullable)overrdieSequence NS_DESIGNATED_INITIALIZER; ++ (instancetype)environmentWithTargetApplication:(NSRunningApplication * _Nullable)targetApplication entry:(KPKEntry * _Nullable)entry overrideSequence:(NSString * _Nullable)overrideSequence; + +/// Create a environment for the autotype execution capturing the current exection context +/// @param targetApplication the application to target, supply nil to use the front most application (for e.g. Global Autotype) +/// @param entry the entry to use, if one is preferred (e.g. when being invoked via Perform Autotype) +/// @param overrdieSequence a custom sequence that should take precedence over any provided by the entry +- (instancetype)initWithTargetApplication:(NSRunningApplication * _Nullable)targetApplication entry:(KPKEntry * _Nullable)entry overrideSequence:(NSString * _Nullable)overrdieSequence NS_DESIGNATED_INITIALIZER; - (instancetype)init NS_UNAVAILABLE; @end diff --git a/MacPass/MPAutotypeEnvironment.m b/MacPass/MPAutotypeEnvironment.m index dd91af80..934cf1f1 100644 --- a/MacPass/MPAutotypeEnvironment.m +++ b/MacPass/MPAutotypeEnvironment.m @@ -23,6 +23,10 @@ _preferredEntry = entry; _hidden = NSRunningApplication.currentApplication.isHidden; _overrideSequence = [overrdieSequence copy]; + /* capture the front most application if no one was supplied */ + if(nil == targetApplication) { + targetApplication = NSWorkspace.sharedWorkspace.frontmostApplication; + } if(!targetApplication) { _pid = -1; _windowTitle = @""; diff --git a/MacPass/MPIntegrationPreferencesController.m b/MacPass/MPIntegrationPreferencesController.m index c4ccdfbc..0ba1ba97 100644 --- a/MacPass/MPIntegrationPreferencesController.m +++ b/MacPass/MPIntegrationPreferencesController.m @@ -106,7 +106,7 @@ - (void)_updateAccessabilityWarning { - BOOL hasAutotypeSupport = MPAutotypeDoctor.defaultDoctor.hasNecessaryAutotypePermissions; + BOOL hasAutotypeSupport = [MPAutotypeDoctor.defaultDoctor hasNecessaryPermissionForTask:MPAutotypeTaskGlobalAutotype]; if(hasAutotypeSupport) { [self.autotypeStackView setVisibilityPriority:NSStackViewVisibilityPriorityNotVisible forView:self.autotypeWarningTextField];