def __init__(self, preferences_file=None): """Create a preferences object. This JSSPrefs object can be used as an argument for a new JSS. By default and with no arguments, it uses the preference domain "com.github.sheagcraig.python-jss.plist". However, alternate configurations can be supplied to the __init__ method to use something else. If no preferences file is specified, an interactive config method will run to help set up python-jss. See the JSSPrefs __doc__ for information on supported preferences. Args: preferences_file: String path to an alternate location to look for preferences. Defaults base on OS: OS X: "~/Library/Preferences/com.github.sheagcraig.python-jss.plist" Linux: "~/.com.github.sheagcraig.python-jss.plist" Raises: JSSError if using an unsupported OS. """ if preferences_file is None: plist_name = "com.github.sheagcraig.python-jss.plist" if is_osx(): preferences_file = os.path.join("~", "Library", "Preferences", plist_name) elif is_linux(): preferences_file = os.path.join("~", "." + plist_name) else: raise JSSError("Unsupported OS.") self.preferences_file = os.path.expanduser(preferences_file) if os.path.exists(self.preferences_file): self.parse_plist(self.preferences_file) else: self.configure() if not os.path.exists(self.preferences_file): raise JSSPrefsMissingFileError("Preferences file not found!") else: jss.JSSPrefs.__init__(self, preferences_file=self.preferences_file) # pylint: disable=non-parent-init-called
def parse_plist(self, preferences_file): """Try to reset preferences from preference_file.""" preferences_file = os.path.expanduser(preferences_file) # Try to open using FoundationPlist. If it's not available, # fall back to plistlib and hope it's not binary encoded. try: prefs = FoundationPlist.readPlist(preferences_file) except NameError: try: prefs = plistlib.readPlist(preferences_file) except ExpatError: # If we're on OSX, try to convert using another # tool. if is_osx(): subprocess.call( ["plutil", "-convert", "xml1", preferences_file]) prefs = plistlib.readPlist(preferences_file) self.preferences_file = preferences_file self.user = prefs.get("jss_user") self.url = prefs.get("jss_url") plain_password = prefs.get("jss_pass") # Previous versions might have left a plaintext password in # a preferences file. Offer to move it to the keychain and # bail if the user refuses: this is, after all, the 'K'JSSPrefs # class. if self.url and self.user and plain_password: answer = None question = ( "Warning: we found a plaintext password in the " "prefs file, and you didn't specify '--no-keychain'.\n" "git2jss can remove the plaintext password " "from the file and move it to the keychain for you. \n" "This is almost certainly a good idea unless you really " "know what you are doing, and just forgot the --no-keychain " "flag.\n") print(question) while answer not in ['y', 'n']: answer = input( 'Do you want to move the password out of the plist file? (y|n)' ) if answer == 'y': store_creds_in_keychain(self.url, self.user, plain_password) prefs.pop("jss_pass") self.write_plist_from_dict(prefs) print("Password moved into keychain") else: print(("OK, on your own head be it.\n" "You can use the --no-keychain flag to continue with " "the plaintext password.")) raise JSSError("Plaintext password without --no-keychain") # This will throw an exception if the password is missing self.password = get_creds_from_keychain(self.url, self.user) if not all([self.user, self.password, self.url]): raise JSSPrefsMissingKeyError( "Some preferences are missing. Please " "delete %s and try again." % self.preferences_file) # Optional file repository array. Defaults to empty list. self.repos = [] for repo in prefs.get("repos", []): self.repos.append(dict(repo)) self.verify = prefs.get("verify", True) self.suppress_warnings = prefs.get("suppress_warnings", True)
from xml.etree import ElementTree from xml.parsers.expat import ExpatError from six.moves import input import keyring import jss from jss.exceptions import (JSSError, JSSPrefsMissingKeyError, JSSPrefsMissingFileError) from jss.tools import (is_osx, is_linux, loop_until_valid_response) try: from jss.contrib import FoundationPlist except ImportError as err: # If using OSX, FoundationPlist will need Foundation/PyObjC # available, or it won't import. if is_osx(): print("Warning: Import of FoundationPlist failed:", err) print("See README for information on this issue.") import plistlib class KJSSPrefs(jss.JSSPrefs): """ This is a subclass of the JSSPrefs class which stores passwords in the system keychain, rather than in plaintext in a preference file. """ def __init__(self, preferences_file=None): """Create a preferences object. This JSSPrefs object can be used as an argument for a new JSS. By default and with no arguments, it uses the preference domain "com.github.sheagcraig.python-jss.plist". However, alternate configurations can be supplied to the __init__ method to use