Search code examples
bashpdfapplescriptpassword-protection

Save PDF document with Password protection for copying + opening from terminal


I want to convert this AppleScript to something less prone to breaking (with every OS update). This Apple script takes 4 variables a fixed and a variable password for not being able to copy or open the document respectively, as well as the "exam" number and the "session" number and outputs a password protected PDF. How can I do the same from a bash shell?

set FixedPassword to "nocopy"    
set exam to "2"
set session to "6"
set VarPassword to "time"

set outpath to "/Users/username/Exam" & " " & exam & " " & "Session" & " " & session & "/E" & exam & "S" & session & ".pdf"

set SaveFolder to "/Users/username/Exam" & " " & exam & " " & "Session" & " " & session

set FileName to "E" & exam & "S" & session & " " & "(Password" & " - " & VarPassword & ").pdf"


tell application "Preview"
    activate
    open outpath
end tell


activate application "Preview"
tell application "System Events"
    tell process "Preview"
        keystroke "p" using command down
        delay 0.5
        tell front window
            repeat until exists sheet 1
                delay 1
            end repeat
            tell sheet 1
                tell splitter group 1
                    click pop up button 3
                    click menu item "MyLayout 216 by 279 mm" of menu 1 of pop up button 3
                end tell
                tell splitter group 1
                    click menu button "PDF"
                    repeat until exists menu 1 of menu button "PDF"
                        delay 0.02
                    end repeat
                    click menu item "Save as PDF" of menu 1 of menu button "PDF"
                end tell
            end tell
        end tell
        
        repeat until exists sheet 1 of sheet 1 of front window
            delay 5
        end repeat
                    
        tell sheet 1 of sheet 1 of front window
            click button "Security Options…"
        end tell
        
        tell window "PDF Security Options"
            set selected to true
            set focused to true
            (* click the checkbox to on *)
            tell checkbox "Require password to open document"
                click
            end tell
            (* add the password and confirm *)
            keystroke VarPassword
            keystroke (ASCII character 9)
            keystroke VarPassword
            
            tell its checkbox "Require password to copy text, images and other content"
                click
            end tell
            (* add the password and confirm *)
            keystroke FixedPassword
            keystroke (ASCII character 9)
            keystroke FixedPassword
            
            click button "OK"
        end tell
        
        repeat until exists sheet 1 of sheet 1 of front window
            delay 0.2
        end repeat
        
        keystroke "g" using {command down, shift down}
        repeat until exists sheet of sheet 1 of sheet 1 of front window
            delay 0.2
        end repeat
        
        delay 0.5
        keystroke SaveFolder
        delay 0.5
        
        keystroke return
        
        set value of text field 1 of sheet 1 of sheet 1 of front window to FileName
        
        click button "Save" of sheet 1 of sheet 1 of front window
        
    end tell
end tell

Solution

  • Here is AsObjC solution to do this. I recommend to do not include your user password in the encrypted PDF's name (for security reasons).

    The script works with PDFs selected in the Finder & creates encrypted copies of them in the same directory.

    use framework "Foundation"
    use framework "CoreFoundation"
    use framework "PDFKit"
    use AppleScript version "2.4"
    use scripting additions
    
    property this : a reference to current application
    property NSString : a reference to NSString of this
    property NSURL : a reference to NSURL of this
    property PDFDocument : a reference to PDFDocument of this
    property NSDictionary : a reference to NSDictionary of this
    property QuartzFilter : a reference to QuartzFilter of this
    property CFString : a reference to CFString of this
    property kCGPDFContextAllowsCopying : a reference to kCGPDFContextAllowsCopying of this
    
    -- set the password. "pw"
    -- NOTE: here, I set the User password and Owner password as same,
    ---------- you can set different passwords (pw1, pw2) as well
    set theReturnedItems to (display dialog "What is the Password?" default answer "Example" buttons {"Quit", "OK"} default button 2)
    if the button returned of the result is "Quit" then return
    set pw to (the text returned of theReturnedItems) as «class utf8»
    set pw to (NSString's stringWithString:pw)
    
    tell application "Finder" to set theAliases to (get selection as alias list)
    
    repeat with anAlias in theAliases
        if (anAlias as text) ends with ".pdf" then
            set thePDFpath to POSIX path of anAlias
            set aURL to (NSURL's fileURLWithPath:thePDFpath)
            set origPDFdoc to (PDFDocument's alloc()'s initWithURL:aURL)
            -- construct output file names -- Viking OSX. 
            set ws_file to (NSString's stringWithString:thePDFpath)
            set ws_ext to ws_file's pathExtension()
            set ws_base to ws_file's stringByDeletingPathExtension()
            set bPOSIX to ((ws_base's stringByAppendingString:"_enCrypted")'s stringByAppendingPathExtension:ws_ext)
            -- Create options for the document
            set aDict to (NSDictionary's dictionaryWithObjects:{CFString's noCopy, pw, pw} forKeys:{kCGPDFContextAllowsCopying, "kCGPDFContextUserPassword", "kCGPDFContextOwnerPassword"})
            -- save password protected file
            (origPDFdoc's writeToFile:(bPOSIX) withOptions:(aDict))
        end if
    end repeat