Beispiel #1
0
    def sign_in(self, email=None, password=None):
        print colored("Authenticating user...", "blue")

        # If no login credentials were provided
        if not email or not password:
            raise Exception(
                HamperError(
                    HamperError.HECodeLogInError,
                    "Either the email and/or password wasn't provided. Call 'hamper auth login' with the login credentials."
                ))

        # Grab the HamperDriver singleton
        driver = HamperDriver()

        # Open the profile URL. This will forward to the sign in page if session is invalid
        driver.get("https://developer.apple.com/account/ios/profile/")

        email_element = driver.find_element_by_name("appleId")
        email_element.send_keys(email)

        password_element = driver.find_element_by_name("accountPassword")
        password_element.send_keys(password)

        driver.find_element_by_id("submitButton2").click()

        if len(driver.find_elements_by_class_name("dserror")) > 0:
            raise Exception(
                HamperError(
                    HamperError.HECodeLogInError,
                    driver.find_element_by_class_name("dserror").get_attribute(
                        "innerHTML")))
        else:
            print colored("User successfully authenticated.", "green")
Beispiel #2
0
    def pick_distribution_signing_certificate(self, date):
        print colored("Picking distribution certfificate...", "blue")

        # Grab the HamperDriver singleton
        driver = HamperDriver()

        time.sleep(0.2)

        # Select the table containing the available certificates
        certificates_table = driver.find_element_by_css_selector(
            '.form.table.distribution')

        # Grab the container of the actual certificates
        rows_div = certificates_table.find_element_by_class_name("rows")

        # Use the xpath to grab all the child elements of rows_div
        # The structure of the contents is like this: gist.github.com/KiranPanesar/a0221c00390b5bdaf5af
        # Where <div class="status">May 22, 2015</div> is the example of an expiration date.
        #
        # We parse out all of the contents so for each certificate there are two divs. One containing the radio button,
        # one for the expiration date.
        available_certificates = rows_div.find_elements_by_xpath("./*")

        # Create a radio_button in the general method scope
        radio_button = None

        if date:
            # Store the stringified version of the date, so it isn't generated on every loop iteration
            date_string = date.readable_date()

            # Loop through the rows in the table
            for i in available_certificates:
                # Check if the current row has the provided expiration date
                if i.get_attribute("innerHTML") == date_string:
                    # If it does, get the element ABOVE the current one.
                    # Refer back to the structure of the contents (gist.github.com/KiranPanesar/a0221c00390b5bdaf5af)
                    current_date_index = available_certificates.index(i)

                    # Set the radio button to the above element
                    radio_button = available_certificates[
                        current_date_index -
                        1].find_element_by_xpath("./input")

        else:
            # Set the radio button to the above element
            radio_button = available_certificates[0].find_element_by_xpath(
                "./input")

        # If the radio button is None, i.e. no certificate was selected/found, throw an error
        try:
            radio_button.click()
        except Exception, e:
            raise Exception(
                HamperError(
                    HamperError.HECodeInvalidCertificateExpirationDate,
                    "We could not find a distribution certificate with the specified date ("
                    + date.readable_date() + ") to sign the profile."))
Beispiel #3
0
	def sign_in(self, email=None, password=None):
		print colored("Authenticating user...", "blue")
		
		# If no login credentials were provided
		if not email or not password:
			raise Exception(HamperError(HamperError.HECodeLogInError, "Either the email and/or password wasn't provided. Call 'hamper auth login' with the login credentials."))

		# Grab the HamperDriver singleton
		driver = HamperDriver()

		# Open the profile URL. This will forward to the sign in page if session is invalid
		driver.get("https://developer.apple.com/account/ios/profile/")

		email_element = driver.find_element_by_name("appleId")
		email_element.send_keys(email)

		password_element = driver.find_element_by_name("accountPassword")
		password_element.send_keys(password)

		driver.find_element_by_id("submitButton2").click()

		if len(driver.find_elements_by_class_name("dserror")) > 0:
			raise Exception(HamperError(HamperError.HECodeLogInError, driver.find_element_by_class_name("dserror").get_attribute("innerHTML"))) 
		else:
			print colored("User successfully authenticated.", "green")
Beispiel #4
0
    def select_app_id(self, app_id):
        print colored("Selecting app ID...", "blue")

        # Grab the HamperDriver singleton
        driver = HamperDriver()

        # ---------
        #	Browser is now at this page:
        #	i.imgur.com/coJMLtm.png
        # ---------

        time.sleep(0.2)

        # Wait until the dropdown is clickable
        wait = WebDriverWait(driver, 20)
        wait.until(lambda driver: driver.find_element_by_name("appIdId"))

        # Select the dropdown list
        select_app_id_dropdown = driver.find_element_by_name("appIdId")

        # Use the xpath to select all the child nodes of the appID dropdown list
        options_list = select_app_id_dropdown.find_elements_by_xpath("./*")

        # Initialise the selected_option
        selected_option = None

        # Loop through the options, check whether the provided appID is
        # in the dropdown. If it is, set selected_option to that HTML element.
        for option in options_list:
            if app_id in option.text:
                selected_option = option
                break

        # Check whether the option was found (i.e. the selected_option class is of the same type as the selected_app_id_dropdown class)
        if type(selected_option) != type(select_app_id_dropdown):
            # If it wasn't found, throw an exception
            raise Exception(
                HamperError(
                    HamperError.HECodeInvalidAppID, "The app ID provided (" +
                    app_id + ") could not be found."))

        # If the app ID exists in the list, select it from the dropdown menu
        selected_option.click()

        # Locate the Continue button on the page
        continue_button_element = driver.find_element_by_css_selector(
            ".button.small.blue.right.submit")

        # Click the continue button
        continue_button_element.click()
Beispiel #5
0
    def enter_profile_name(self, profile_name):
        print colored("Naming provisioning profile...", "blue")

        # Grab the HamperDriver singleton
        driver = HamperDriver()

        time.sleep(0.2)

        profile_name_element = driver.find_element_by_name(
            "provisioningProfileName")
        profile_name_element.send_keys(profile_name)

        # Locate the Continue button on the page
        continue_button_element = driver.find_element_by_css_selector(
            ".button.small.blue.right.submit")

        # Click the continue button
        continue_button_element.click()
Beispiel #6
0
    def generate_certificate(self,
                             certificate_type=HCCertificateTypeDistribution,
                             app_id="",
                             csr_path="",
                             certificate_path=""):

        print colored("Generating certificate...", "blue")

        # Grab the HamperDriver singleton
        current_driver = HamperDriver()

        print colored("Picking certificate type...", "blue")

        # Set the certificate_type property
        self.pick_certificate_type(current_driver, certificate_type)

        # If we're going to generate a push certificate, we need to specify an app ID.
        # This is an extra step in the Provisioning Profile process
        if certificate_type == HamperCertifier.HCCertificateTypeDevelopmentPush or certificate_type == HamperCertifier.HCCertificateTypeDistributionPush:
            print colored("Selecting application ID...", "blue")
            self.select_app_id(current_driver, app_id)

        print colored("Confirming CSR instructions...", "blue")

        # Confirm the CSR generation instructions
        self.confirm_csr_instructions(current_driver)

        print colored("Generating certificate (this could take a minute)...",
                      "blue")

        # Generate, wait, and download the actual certificate. Return the URL.
        download_url = self.confirm_certificate_generation(
            current_driver, csr_path)

        if download_url and len(download_url) > 0:
            print colored("Certificate successfully generated.", "green")

            print colored(
                "Downloading certificate (this could take a minute)...",
                "blue")

            # Download the certificate to the user-defined path
            self.download_certificate(current_driver, download_url,
                                      certificate_path)

            print colored(
                "Certificate successfully downloaded (" + certificate_path +
                ").", "green")

        else:
            raise Exception(
                HamperError(
                    1,
                    "Could not generate certificate and/or certificate download URL."
                ))
Beispiel #7
0
    def pick_profile_type(self, profile_type):
        print colored("Picking profile type...", "blue")

        # Grab the HamperDriver singleton
        driver = HamperDriver()

        # This will trigger the provisioning portal to load this page: i.imgur.com/tAz1lHH.png
        driver.get(
            "https://developer.apple.com/account/ios/profile/profileCreate.action"
        )

        # Create a var to store the radio button's ID in (will depend on the cert type being requested)
        button_id = ""

        # Check the cert type parameter, set the button's ID accordingly
        if profile_type == HamperProvisioner.HPProfileTypeDevelopment:
            button_id = "type-development"
        elif profile_type == HamperProvisioner.HPProfileTypeAppStore:
            button_id = "type-production"
        elif profile_type == HamperProvisioner.HPProfileTypeAdHoc:
            button_id = "type-adhoc"

        # Find the radio button to select (based on the button_id)
        radio_button = driver.find_element_by_id(button_id)

        # Click the radio button
        radio_button.click()

        # Locate the submit button on the page
        submit_button_element = driver.find_element_by_class_name("submit")

        # Click the submit button
        submit_button_element.click()
Beispiel #8
0
    def download_provisioning_profile(self, file_path):
        print colored(
            "Waiting for Apple to generate profile (this could take a minute)...",
            "blue")

        # Grab the HamperDriver singleton
        driver = HamperDriver()

        # Have the browser wait until the downloadForm is visible (this contains the download button & link)
        wait = WebDriverWait(driver, 30)
        wait.until(
            lambda driver: driver.find_element_by_class_name("downloadForm"))

        # Find the download button, grab the download URL
        download_button_element = driver.find_element_by_css_selector(
            ".button.small.blue")
        download_url = download_button_element.get_attribute("href")

        print colored("Provisioning profile successfully generated.", "green")

        print colored("Downloading provisioning profile...", "blue")

        # Create a URLOpener object
        opener = urllib.URLopener()

        # Grab all the cookies from Selenium
        all_cookies = driver.get_cookies()

        # Loop through each cookie
        for cookie in all_cookies:
            # Add the cookie to the URLOpener instance
            opener.addheaders.append(
                ('Cookie', cookie['name'] + "=" + cookie['value']))

        # Save the profile file into the user-defined path
        opener.retrieve(download_url, file_path)

        print colored("Profile successfully downloaded (" + file_path + ").",
                      "green")
Beispiel #9
0
    def pick_provisioned_devices(self):
        print colored("Selecting provisioned devices...", "blue")

        # Grab the HamperDriver singleton
        driver = HamperDriver()

        time.sleep(0.2)

        # Select the column containing the 'select all' checkbox
        select_all_column = driver.find_element_by_css_selector('.selectAll')

        # Use the xpath to find the input element inside of that column
        select_all_checkbox = select_all_column.find_element_by_xpath(
            './input')

        # Click the select all checkbox
        select_all_checkbox.click()

        # Locate the Continue button on the page
        continue_button_element = driver.find_element_by_css_selector(
            ".button.small.blue.right.submit")

        # Click the continue button
        continue_button_element.click()
Beispiel #10
0
    def __init__(self):
        super(HamperIdentifier, self).__init__()

        self.driver = HamperDriver()
Beispiel #11
0
class HamperIdentifier(object):

    #
    # The enabled services constants. Taken from the 'name' of each item in the provisioning portal.
    #
    HIServiceAppGroups = "APG3427HIY"
    HIServiceAssociatedDomains = "SKC3T5S89Y"
    HIServiceDataProtection = "dataProtectionPermission"
    HIServiceHealthKit = "HK421J6T7P"
    HIServiceHomeKit = "homeKit"
    HIServiceWirelessAccessory = "WC421J6T7P"
    HIServiceiCloud = "iCloud"
    HIServiceInterAppAudio = "IAD53UNK2F"
    HIServicePassbook = "pass"
    HIServicePushNotifications = "push"
    HIServiceVPNConfiguration = "V66P55NK2I"

    def __init__(self):
        super(HamperIdentifier, self).__init__()

        self.driver = HamperDriver()

    #
    # Public method to be called to generate an app ID
    #
    def generate_app_id(self, name, bundle_id, app_services=[]):
        print colored("Generating app ID...", "blue")

        # Point the driver to the creation page
        self.driver.get(
            "https://developer.apple.com/account/ios/identifiers/bundle/bundleCreate.action"
        )

        # Call the internal methods to fill out the options
        self.enter_app_name(name)
        self.enter_bundle_identifier(bundle_id)
        self.select_enabled_app_services(app_services)

        # Click the continue button
        self.click_continue_button()

        # Confirm the app ID creation
        self.click_submit_button()

        print colored("App ID successfully generated.", "green")

    # ------
    # Internal methods to process the app ID flow
    # ------

    # Method to fill out the app's name
    def enter_app_name(self, name):
        app_name_element = self.driver.find_element_by_name("appIdName")
        app_name_element.send_keys(name)

    # Method to fill out the app's bundle ID
    def enter_bundle_identifier(self, bundle_id):
        bundle_id_element = self.driver.find_element_by_name(
            "explicitIdentifier")
        bundle_id_element.send_keys(bundle_id)

    # Method to select the enabled services
    def select_enabled_app_services(self, services):
        for service in services:
            self.driver.find_element_by_name(service).click()

    # Method to click the continue 'button' to move to the confirmation step
    def click_continue_button(self):
        current_url = self.driver.current_url
        continue_button = self.driver.find_element_by_class_name("submit")
        continue_button.click()

        # Wait until all page content has been added
        time.sleep(0.2)

        # If we're still stuck on the same page, scan it for errors.
        if current_url == self.driver.current_url:
            # Load the error form elements from the page
            error_elements = self.driver.find_elements_by_class_name(
                "form-error")

            # Are there any error elements? If so, fetch them and return them.
            # If there aren't any errors, we can assume the page moved on successfully.
            if len(error_elements) > 0:
                # Create a list to store the actual errors
                # (some errors might be in the page but not visible to the user, so they haven't been shown yet)
                errors_list = []

                # Loop through the elements to see which ones are on-screen
                for element in error_elements:

                    # The hackiest way to check error visibility
                    # Check whether the style of the component is visible
                    if "display: none" not in element.get_attribute("style"):

                        # If it is visible, append the error message
                        errors_list.append(element.get_attribute("innerHTML"))

                # Were there any actual errors?
                if len(errors_list) > 0:
                    # Raise an exception with the error codes
                    raise Exception(HamperError(1, str(errors_list)))

    # Confirm the creation of the app ID
    def click_submit_button(self):
        time.sleep(0.5)

        submit_button = self.driver.find_element_by_css_selector(
            ".button.small.blue.right.submit")
        submit_button.click()