示例#1
0
def _login(store, packages=None, acls=None, channels=None, save=True):
    print('Enter your Ubuntu One SSO credentials.')
    email = input('Email: ')
    password = getpass.getpass('Password: '******'Second-factor auth: ')
            store.login(
                email, password, one_time_password=one_time_password,
                acls=acls, packages=packages, channels=channels,
                save=save)

        # Continue if agreement and namespace conditions are met.
        _check_dev_agreement_and_namespace_statuses(store)

    except storeapi.errors.InvalidCredentialsError:
        return _fail_login(storeapi.constants.INVALID_CREDENTIALS)
    except storeapi.errors.StoreAuthenticationError:
        return _fail_login(storeapi.constants.AUTHENTICATION_ERROR)
    except storeapi.errors.StoreAccountInformationError:
        return _fail_login(storeapi.constants.ACCOUNT_INFORMATION_ERROR)
    except storeapi.errors.NeedTermsSignedError as e:
        return _fail_login(e.message)
    else:
        print()
        echo.info('Login successful.')
        return True
示例#2
0
def validate(
    snap_name: str,
    validations: List[str],
    revoke: bool = False,
    key: Optional[str] = None,
):
    """Generate, sign and upload validation assertions."""
    # Check validations format
    _check_validations(validations)

    # Need the ID of the logged in user.
    store_client = StoreClientCLI()
    account_info = store_client.get_account_information()
    authority_id = account_info["account_id"]

    # Get data for the gating snap
    try:
        snap_id = account_info["snaps"][DEFAULT_SERIES][snap_name]["snap-id"]
    except KeyError:
        raise storeapi.errors.SnapNotFoundError(snap_name=snap_name)

    # Then, for each requested validation, generate assertion
    for validation in validations:
        gated_snap, rev = validation.split("=", 1)
        echo.info(f"Getting details for {gated_snap}")
        # The Info API is not authed, so it cannot see private snaps.
        try:
            approved_data = store_client.cpi.get_info(gated_snap)
            approved_snap_id = approved_data.snap_id
        except storeapi.errors.SnapNotFoundError:
            approved_snap_id = gated_snap

        assertion_payload = {
            "type": "validation",
            "authority-id": authority_id,
            "series": DEFAULT_SERIES,
            "snap-id": snap_id,
            "approved-snap-id": approved_snap_id,
            "approved-snap-revision": rev,
            "timestamp": datetime.utcnow().isoformat() + "Z",
            "revoked": "false",
        }
        if revoke:
            assertion_payload["revoked"] = "true"

        assertion = _sign_assertion(validation, assertion_payload, key,
                                    "validations")

        # Save assertion to a properly named file
        fname = f"{snap_name}-{gated_snap}-r{rev}.assertion"
        with open(fname, "wb") as f:
            f.write(assertion)

        store_client.push_assertion(snap_id, assertion, endpoint="validations")
示例#3
0
def _sign_assertion(snap_name, assertion, key, endpoint):
    cmdline = ['snap', 'sign']
    if key:
        cmdline += ['-k', key]
    snap_sign = Popen(
        cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
        stderr=subprocess.PIPE)
    data = json.dumps(assertion).encode('utf8')
    echo.info('Signing {} assertion for {}'.format(endpoint, snap_name))
    assertion, err = snap_sign.communicate(input=data)
    if snap_sign.returncode != 0:
        err = err.decode()
        raise storeapi.errors.StoreAssertionError(
            endpoint=endpoint, snap_name=snap_name, error=err)

    return assertion
示例#4
0
def _sign_assertion(snap_name, assertion, key, endpoint):
    cmdline = ['snap', 'sign']
    if key:
        cmdline += ['-k', key]
    snap_sign = Popen(
        cmdline, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
        stderr=subprocess.PIPE)
    data = json.dumps(assertion).encode('utf8')
    echo.info('Signing {} assertion for {}'.format(endpoint, snap_name))
    assertion, err = snap_sign.communicate(input=data)
    if snap_sign.returncode != 0:
        err = err.decode('ascii', errors='replace')
        raise storeapi.errors.StoreAssertionError(
            endpoint=endpoint, snap_name=snap_name, error=err)

    return assertion
示例#5
0
def validate(snap_name, validations, revoke=False, key=None):
    """Generate, sign and upload validation assertions."""
    # Check validations format
    _check_validations(validations)

    store = storeapi.StoreClient()

    # Need the ID of the logged in user.
    with _requires_login():
        account_info = store.get_account_information()
    authority_id = account_info["account_id"]

    # Get data for the gating snap
    release = storeapi.constants.DEFAULT_SERIES
    try:
        snap_id = account_info["snaps"][release][snap_name]["snap-id"]
    except KeyError:
        raise storeapi.errors.SnapNotFoundError(snap_name)

    # Then, for each requested validation, generate assertion
    for validation in validations:
        gated_name, rev = validation.split("=", 1)
        echo.info("Getting details for {}".format(gated_name))
        approved_data = store.cpi.get_info(gated_name)
        assertion = {
            "type": "validation",
            "authority-id": authority_id,
            "series": release,
            "snap-id": snap_id,
            "approved-snap-id": approved_data.snap_id,
            "approved-snap-revision": rev,
            "timestamp": datetime.utcnow().isoformat() + "Z",
            "revoked": "false",
        }
        if revoke:
            assertion["revoked"] = "true"

        assertion = _sign_assertion(validation, assertion, key, "validations")

        # Save assertion to a properly named file
        fname = "{}-{}-r{}.assertion".format(snap_name, gated_name, rev)
        with open(fname, "wb") as f:
            f.write(assertion)

        store.push_assertion(snap_id, assertion, endpoint="validations")
示例#6
0
def validate(snap_name, validations, revoke=False, key=None):
    """Generate, sign and upload validation assertions."""
    # Check validations format
    _check_validations(validations)

    store = storeapi.StoreClient()

    # Need the ID of the logged in user.
    with _requires_login():
        account_info = store.get_account_information()
    authority_id = account_info['account_id']

    # Get data for the gating snap
    release = storeapi.constants.DEFAULT_SERIES
    try:
        snap_id = account_info['snaps'][release][snap_name]['snap-id']
    except KeyError:
        raise storeapi.errors.SnapNotFoundError(snap_name)

    # Then, for each requested validation, generate assertion
    for validation in validations:
        gated_name, rev = validation.split('=', 1)
        echo.info('Getting details for {}'.format(gated_name))
        approved_data = store.cpi.get_package(gated_name, 'stable')
        assertion = {
            'type': 'validation',
            'authority-id': authority_id,
            'series': release,
            'snap-id': snap_id,
            'approved-snap-id': approved_data['snap_id'],
            'approved-snap-revision': rev,
            'timestamp': datetime.utcnow().isoformat() + 'Z',
            'revoked': "false"
        }
        if revoke:
            assertion['revoked'] = "true"

        assertion = _sign_assertion(validation, assertion, key, 'validations')

        # Save assertion to a properly named file
        fname = '{}-{}-r{}.assertion'.format(snap_name, gated_name, rev)
        with open(fname, 'wb') as f:
            f.write(assertion)

        store.push_assertion(snap_id, assertion, endpoint='validations')
示例#7
0
def validate(snap_name, validations, revoke=False, key=None):
    """Generate, sign and upload validation assertions."""
    # Check validations format
    _check_validations(validations)

    store = storeapi.StoreClient()

    # Need the ID of the logged in user.
    with _requires_login():
        account_info = store.get_account_information()
    authority_id = account_info['account_id']

    # Get data for the gating snap
    release = storeapi.constants.DEFAULT_SERIES
    try:
        snap_id = account_info['snaps'][release][snap_name]['snap-id']
    except KeyError:
        raise storeapi.errors.SnapNotFoundError(snap_name)

    # Then, for each requested validation, generate assertion
    for validation in validations:
        gated_name, rev = validation.split('=', 1)
        echo.info('Getting details for {}'.format(gated_name))
        approved_data = store.cpi.get_package(gated_name, 'stable')
        assertion = {
            'type': 'validation',
            'authority-id': authority_id,
            'series': release,
            'snap-id': snap_id,
            'approved-snap-id': approved_data['snap_id'],
            'approved-snap-revision': rev,
            'timestamp': datetime.utcnow().isoformat() + 'Z',
            'revoked': "false"
        }
        if revoke:
            assertion['revoked'] = "true"

        assertion = _sign_assertion(validation, assertion, key, 'validations')

        # Save assertion to a properly named file
        fname = '{}-{}-r{}.assertion'.format(snap_name, gated_name, rev)
        with open(fname, 'wb') as f:
            f.write(assertion)

        store.push_assertion(snap_id, assertion, endpoint='validations')
示例#8
0
def _login(store, packages=None, acls=None, channels=None, save=True):
    print('Enter your Ubuntu One e-mail address and password.\n'
          'If you do not have an Ubuntu One account, you can create one at '
          'https://dashboard.snapcraft.io/openid/login')
    email = input('Email: ')
    password = getpass.getpass('Password: '******'Second-factor auth: ')
            store.login(email,
                        password,
                        one_time_password=one_time_password,
                        acls=acls,
                        packages=packages,
                        channels=channels,
                        save=save)

        # Continue if agreement and namespace conditions are met.
        _check_dev_agreement_and_namespace_statuses(store)

    except storeapi.errors.InvalidCredentialsError:
        return _fail_login(storeapi.constants.INVALID_CREDENTIALS)
    except storeapi.errors.StoreAuthenticationError:
        return _fail_login(storeapi.constants.AUTHENTICATION_ERROR)
    except storeapi.errors.StoreAccountInformationError:
        return _fail_login(storeapi.constants.ACCOUNT_INFORMATION_ERROR)
    except storeapi.errors.NeedTermsSignedError as e:
        return _fail_login(e.message)
    else:
        print()
        echo.info('Login successful.')
        return True