示例#1
0
def after_login(resp):
    try:
        root = Macaroon.deserialize(flask.session.pop("macaroon_root"))
    except KeyError:
        return (
            flask.render_template("templates/_error_login.html", ),
            400,
        )

    bound = root.prepare_for_request(
        Macaroon.deserialize(resp.extensions["macaroon"].discharge))
    flask.session["authentication_token"] = binary_serialize_macaroons(
        [root, bound]).decode("utf-8")

    if not resp.nickname:
        return flask.redirect(flask.current_app.config["CANONICAL_LOGIN_URL"])

    flask.session["openid"] = {
        "identity_url": resp.identity_url,
        "nickname": resp.nickname,
        "fullname": resp.fullname,
        "image": resp.image,
        "email": resp.email,
    }

    return flask.redirect(open_id.get_next_url())
示例#2
0
 def discharge_macaroon_raw(self):
     root_macaroon = Macaroon.deserialize(self.root_macaroon_raw)
     unbound_discharge_macaroon = Macaroon.deserialize(
         self.unbound_discharge_macaroon_raw)
     discharge_macaroon = root_macaroon.prepare_for_request(
         unbound_discharge_macaroon)
     return discharge_macaroon.serialize()
def alice_server_access_service():
    macaroon_cookie = request.cookies.get('macaroonCookie')
    discharge_cookie = request.cookies.get('macaroonDischargeCookie')
    if macaroon_cookie is not None and macaroon_cookie != "" and discharge_cookie is not None and discharge_cookie != "":
        m = Macaroon.deserialize(macaroon_cookie)
        dm = Macaroon.deserialize(discharge_cookie)
        # Should be done on the client
        pm = m.prepare_for_request(dm)
        v = Verifier()
        try:
            verified = v.verify(m, alice_server_keys[m.identifier], [pm])
        except MacaroonInvalidSignatureException:
            verified = False
        if verified:
            resp = make_response(
                render_template("auth_demo.html",
                                result="Successful Authentication"))
        else:
            resp = make_response(
                render_template("auth_demo.html", result="Auth failed"))
        return resp
    else:
        resp = make_response(
            render_template(
                "auth_demo.html",
                result="Couldn't get necessary macaroons from cookies"))
        return resp
示例#4
0
def get_authorization_header(root, discharge):
    """
    Bind root and discharge macaroons and return the authorization header.
    """

    bound = Macaroon.deserialize(root).prepare_for_request(
        Macaroon.deserialize(discharge))

    return "Macaroon root={}, discharge={}".format(root, bound.serialize())
def get_authorization_header(root, discharge):
    """
    Bind root and discharge macaroons and return the authorization header.
    """

    bound = Macaroon.deserialize(root).prepare_for_request(
        Macaroon.deserialize(discharge)
    )

    return "Macaroon root={}, discharge={}".format(root, bound.serialize())
    def _get_authorization_header(self, session):
        """
        Bind root and discharge macaroons and return the authorization header.
        """
        root = session["macaroon_root"]
        discharge = session["macaroon_discharge"]

        bound = (Macaroon.deserialize(root).prepare_for_request(
            Macaroon.deserialize(discharge)).serialize())

        return {"Authorization": f"Macaroon root={root}, discharge={bound}"}
示例#7
0
 def match(self, macaroons):
     mismatch = Contains("root").match(macaroons)
     if mismatch is not None:
         return mismatch
     root_macaroon = Macaroon.deserialize(macaroons["root"])
     if "discharge" in macaroons:
         discharge_macaroons = [
             Macaroon.deserialize(macaroons["discharge"])]
     else:
         discharge_macaroons = []
     try:
         Verifier().verify(root_macaroon, self.key, discharge_macaroons)
     except Exception as e:
         return Mismatch("Macaroons do not verify: %s" % e)
示例#8
0
    def discharge_macaroon(self, macaroon, token):
        # Deserialize the macaroon with pymacaroons
        macaroon = Macaroon.deserialize(macaroon, JsonSerializer())

        # Extract the caveat we are interested in
        caveat = self._extract_caveat_to_discharge(macaroon)

        data = {"id64": caveat, "token64": token, "token-kind": "macaroon"}
        response = self._request(method="POST",
                                 url=f"{CANDID_API_URL}discharge",
                                 data=data)

        return Macaroon.deserialize(json.dumps(response.json()["Macaroon"]),
                                    JsonSerializer())
示例#9
0
def _prepare_request(method, path, data=None, session=None):
    request = Request(method=method, url=f"{API_URL}{path}")

    if session:
        root = Macaroon.deserialize(session["macaroon_root"])
        discharge = Macaroon.deserialize(session["macaroon_discharge"])
        bound = root.prepare_for_request(discharge)
        token = binary_serialize_macaroons([root, bound]).decode("utf-8")
        request.headers["Authorization"] = f"Macaroon {token}"

    if data is not None:
        request.json = data

    return request.prepare()
def validate_pypi_token(token: str) -> Tuple[bool, str]:
    """
	Returns whether the PyPI token *appears* to be valid.

	:param token:
	"""

    # TODO: perhaps use the pypitokens library?

    if not token.startswith("pypi-"):
        return False, "The token should start with 'pypi-'."

    b64string = token[5:]
    try:
        macaroon = Macaroon.deserialize(b64string)
    except Exception:
        return False, "Could not decode token."

    if macaroon.location != "pypi.org":
        return False, "The token is not for PyPI."

    caveats: List[Caveat] = macaroon.caveats

    if not macaroon.caveats:
        return False, "The decoded output does not have the expected format."

    try:
        permissions_dict = json.loads(caveats[0].caveat_id)
    except Exception:
        return False, "The decoded output does not have the expected format."

    # TODO: check the token has the required permissions.

    return True, ''
示例#11
0
def attenuate(macaroon: str, caveats: List[str]) -> str:
    m_obj = Macaroon.deserialize(macaroon)

    for caveat in caveats:
        m_obj.add_first_party_caveat(caveat)

    return str(m_obj.serialize())
示例#12
0
def _create_snap_recipe(
    snap,
    version,
    track,
    owner,
    tag,
    repo,
    dry_run,
    snap_recipe_email,
    snap_recipe_password,
):
    """ Creates an new snap recipe in Launchpad

    snap: Name of snap to create the recipe for (ie, kubectl)
    version: snap version channel apply this too (ie, Current patch is 1.13.3 but we want that to go in 1.13 snap channel)
    track: snap store version/risk/branch to publish to (ie, 1.13/edge/hotfix-LP123456)
    owner: launchpad owner of the snap recipe (ie, k8s-jenkaas-admins)
    tag: launchpad git tag to pull snapcraft instructions from (ie, git.launchpad.net/snap-kubectl)
    repo: launchpad git repo (git+ssh://[email protected]/snap-kubectl)

    # Note: this account would need access granted to the snaps it want's to publish from the snapstore dashboard
    snap_recipe_email: snapstore email for being able to publish snap recipe from launchpad to snap store
    snap_recipe_password: snapstore password for account being able to publish snap recipe from launchpad to snap store

    Usage:

    snaps-source.py builder --snap kubectl --version 1.13 --tag v1.13.2 \
      --track 1.13/edge/hotfix-LP123456 \
      --repo git+ssh://[email protected]/snap-kubectl \
      --owner k8s-jenkaas-admins \
      --snap-recipe-email [email protected] \
      --snap-recipe-password aabbccddee

    """
    _client = lp.Client(stage="production")
    _client.login()

    params = {
        "name": snap,
        "owner": owner,
        "version": version,
        "branch": tag,
        "repo": repo,
        "track": [track],
    }

    click.echo(f"  > creating recipe for {params}")
    if dry_run:
        click.echo("dry-run only, exiting.")
        sys.exit(0)
    snap_recipe = _client.create_or_update_snap_recipe(**params)
    caveat_id = snap_recipe.beginAuthorization()
    cip = idm.CanonicalIdentityProvider(email=snap_recipe_email,
                                        password=snap_recipe_password)
    discharge_macaroon = cip.get_discharge(caveat_id).json()
    discharge_macaroon = Macaroon.deserialize(
        discharge_macaroon["discharge_macaroon"])
    snap_recipe.completeAuthorization(
        discharge_macaroon=discharge_macaroon.serialize())
    snap_recipe.requestBuilds(archive=_client.archive(), pocket="Updates")
示例#13
0
def login_handler():
    is_test_backend = flask.request.args.get("test_backend", False)

    api_url = flask.current_app.config["CONTRACTS_LIVE_API_URL"]

    if is_test_backend:
        api_url = flask.current_app.config["CONTRACTS_TEST_API_URL"]

    if user_info(flask.session):
        return flask.redirect(open_id.get_next_url())

    response = session.request(method="get",
                               url=f"{api_url}/v1/canonical-sso-macaroon")
    flask.session["macaroon_root"] = response.json()["macaroon"]

    for caveat in Macaroon.deserialize(
            flask.session["macaroon_root"]).third_party_caveats():
        if caveat.location == "login.ubuntu.com":
            openid_macaroon = MacaroonRequest(caveat_id=caveat.caveat_id)
            break

    return open_id.try_login(
        flask.current_app.config["CANONICAL_LOGIN_URL"],
        ask_for=["email", "nickname", "image"],
        ask_for_optional=["fullname"],
        extensions=[openid_macaroon],
    )
示例#14
0
    def get_login_url(self, macaroon, callback_url, state):
        """
        To initiate the login redirect the user's browser to the URL
        specified in the LoginURL parameter. The redirect must be a GET
        request and must include a "return_to" query parameter which must
        be whitelisted in the candid server.

        The redirect should also specify a "state" query parameter. This is
        an opaque value that will be sent back to the relaying party in the
        callback. This can be useful to verify that a login attempt was
        started by the relaying party and can help guard against CSRF
        attacks.
        """
        # Deserialize the macaroon with pymacaroons
        macaroon = Macaroon.deserialize(macaroon, JsonSerializer())

        # Extract the caveat we are interested in
        caveat = self._extract_caveat_to_discharge(macaroon)

        response = self._request(
            method="POST",
            url=f"{CANDID_API_URL}discharge",
            data={"id64": caveat},
        )

        data = response.json(
        )["Info"]["InteractionMethods"]["browser-redirect"]

        return f"{data['LoginURL']}?return_to={callback_url}&state={state}"
 def test_serializing_deserializing_macaroon(self, key_id, loc, key):
     assume(key_id and loc and key)
     macaroon = Macaroon(location=loc, identifier=key_id, key=key)
     deserialized = Macaroon.deserialize(macaroon.serialize())
     assert_equal(macaroon.identifier, deserialized.identifier)
     assert_equal(macaroon.location, deserialized.location)
     assert_equal(macaroon.signature, deserialized.signature)
示例#16
0
def deserialize(json_macaroon):
    '''Deserialize a JSON macaroon into a macaroon object from pymacaroons.

    @param the JSON macaroon to deserialize as a dict.
    @return the deserialized macaroon object.
    '''
    return Macaroon.deserialize(json.dumps(json_macaroon),
                                json_serializer.JsonSerializer())
示例#17
0
 def test_deserializing_json_v2(self):
     m = Macaroon.deserialize(
         '{"l": "http://mybank/", "i": "we used our secret key", "s": '
         '"197bac7a044af33332"'
         ', "c": [{"l": null, "i": "test = caveat", "v": null}]}',
         serializer=JsonSerializer())
     assert_equal(m.signature_bytes,
                  binascii.hexlify(b'197bac7a044af33332'))
示例#18
0
 def test_deserializing_accepts_padding(self):
     m = Macaroon.deserialize(
         ('MDAxY2xvY2F0aW9uIGh0dHA6Ly9teWJhbmsvCjAwMjZpZGVudGlmaWVyIHdlIHVz'
          'ZWQgb3VyIHNlY3JldCBrZXkKMDAxN2NpZCB0ZXN0ID0gYWNhdmVhdAowMDJmc2ln'
          'bmF0dXJlIJRJ_V3WNJQnqlVq5eez7spnltwU_AXs8NIRY739sHooCg=='))
     assert_equal(
         m.signature,
         '9449fd5dd6349427aa556ae5e7b3eeca6796dc14fc05ecf0d21163bdfdb07a28')
示例#19
0
 def test_serializing_deserializing_json(self):
     m = Macaroon(location='http://test/',
                  identifier='first',
                  key='secret_key_1')
     m.add_first_party_caveat('test = caveat')
     n = Macaroon.deserialize(m.serialize(serializer=JsonSerializer()),
                              serializer=JsonSerializer())
     assert_equal(m.signature, n.signature)
示例#20
0
    def test_deserializing(self):
        m = Macaroon.deserialize(
            'MDAxY2xvY2F0aW9uIGh0dHA6Ly9teWJhbmsvCjAwMjZpZGVudGlmaW\
VyIHdlIHVzZWQgb3VyIHNlY3JldCBrZXkKMDAxNmNpZCB0ZXN0ID0gY2F2ZWF0CjAwMmZzaWduYXR1\
cmUgGXusegRK8zMyhluSZuJtSTvdZopmDkTYjOGpmMI9vWcK')
        assert_equal(
            m.signature,
            '197bac7a044af33332865b9266e26d493bdd668a660e44d88ce1a998c23dbd67')
示例#21
0
    def test_from_go_macaroon_json_v2(self):
        # The following macaroon have been generated with
        # https://github.com/go-macaroon/macaroon
        # to test the deserialization.
        json_v1 = '{"caveats":[{"cid":"fp caveat"},{"cid":"tp caveat",' \
                  '"vid":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp_MgxHrfLnfvNuYDo' \
                  'zNKWTlRPPx6VemasWnPpJdAWE6FWmOuFX4sB4-a1oAURDp",' \
                  '"cl":"tp location"}],"location":"my location",' \
                  '"identifier":"my identifier",' \
                  '"signature":"483b3881c9990e5099cb6695da3164daa64da60417b' \
                  'caf9e9dc4c0a9968f6636"}'
        json_v1_discharge = '{"caveats":[],"location":"tp location",' \
                            '"identifier":"tp caveat",' \
                            '"signature":"8506007f69ae3e6a654e0b9769f20dd9da5' \
                            'd2af7860070d6776c15989fb7dea6"}'
        m = Macaroon.deserialize(json_v1, serializer=JsonSerializer())
        discharge = Macaroon.deserialize(json_v1_discharge,
                                         serializer=JsonSerializer())
        assert_macaroon(m, discharge, MACAROON_V1)

        binary_v1 = 'MDAxOWxvY2F0aW9uIG15IGxvY2F0aW9uCjAwMWRpZGVudGlmaWVyIG1' \
                    '5IGlkZW50aWZpZXIKMDAxMmNpZCBmcCBjYXZlYXQKMDAxMmNpZCB0cC' \
                    'BjYXZlYXQKMDA1MXZpZCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACn' \
                    '8yDEet8ud+825gOjM0pZOVE8/HpV6Zqxac+kl0BYToVaY64VfiwHj5r' \
                    'WgBREOkKMDAxM2NsIHRwIGxvY2F0aW9uCjAwMmZzaWduYXR1cmUgSDs' \
                    '4gcmZDlCZy2aV2jFk2qZNpgQXvK+encTAqZaPZjYK'
        binary_v1_discharge = 'MDAxOWxvY2F0aW9uIHRwIGxvY2F0aW9uCjAwMTlpZGVud' \
                              'GlmaWVyIHRwIGNhdmVhdAowMDJmc2lnbmF0dXJlIIUGAH' \
                              '9prj5qZU4Ll2nyDdnaXSr3hgBw1ndsFZift96mCg'
        m = Macaroon.deserialize(binary_v1)
        discharge = Macaroon.deserialize(binary_v1_discharge)
        assert_macaroon(m, discharge, MACAROON_V1)

        json_v2 = '{"c":[{"i":"fp caveat"},{"i":"tp caveat",' \
                  '"v64":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp_MgxHrfLnfvNuYDoz' \
                  'NKWTlRPPx6VemasWnPpJdAWE6FWmOuFX4sB4-a1oAURDp",' \
                  '"l":"tp location"}],"l":"my location","i":"my identifier",' \
                  '"s64":"SDs4gcmZDlCZy2aV2jFk2qZNpgQXvK-encTAqZaPZjY"}'
        json_v2_discharge = '{"l":"tp location","i":"tp caveat","s64":"hQYAf2' \
                            'muPmplTguXafIN2dpdKveGAHDWd2wVmJ-33qY"}'
        m = Macaroon.deserialize(json_v2, serializer=JsonSerializer())
        discharge = Macaroon.deserialize(json_v2_discharge,
                                         serializer=JsonSerializer())
        assert_macaroon(m, discharge, MACAROON_V2)

        binary_v2 = 'AgELbXkgbG9jYXRpb24CDW15IGlkZW50aWZpZXIAAglmcCBjYXZlYXQ' \
                    'AAQt0cCBsb2NhdGlvbgIJdHAgY2F2ZWF0BEgAAAAAAAAAAAAAAAAAAA' \
                    'AAAAAAAAAAAAACn8yDEet8ud+825gOjM0pZOVE8/HpV6Zqxac+kl0BY' \
                    'ToVaY64VfiwHj5rWgBREOkAAAYgSDs4gcmZDlCZy2aV2jFk2qZNpgQX' \
                    'vK+encTAqZaPZjY'
        binary_v2_discharge = 'AgELdHAgbG9jYXRpb24CCXRwIGNhdmVhdAAABiCFBgB/a' \
                              'a4+amVOC5dp8g3Z2l0q94YAcNZ3bBWYn7fepg'
        m = Macaroon.deserialize(binary_v2)
        discharge = Macaroon.deserialize(binary_v2_discharge)
        assert_macaroon(m, discharge, MACAROON_V2)
示例#22
0
    def test_from_go_macaroon_json_v2(self):
        # The following macaroon have been generated with
        # https://github.com/go-macaroon/macaroon
        # to test the deserialization.
        json_v1 = '{"caveats":[{"cid":"fp caveat"},{"cid":"tp caveat",' \
                  '"vid":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp_MgxHrfLnfvNuYDo' \
                  'zNKWTlRPPx6VemasWnPpJdAWE6FWmOuFX4sB4-a1oAURDp",' \
                  '"cl":"tp location"}],"location":"my location",' \
                  '"identifier":"my identifier",' \
                  '"signature":"483b3881c9990e5099cb6695da3164daa64da60417b' \
                  'caf9e9dc4c0a9968f6636"}'
        json_v1_discharge = '{"caveats":[],"location":"tp location",' \
                            '"identifier":"tp caveat",' \
                            '"signature":"8506007f69ae3e6a654e0b9769f20dd9da5' \
                            'd2af7860070d6776c15989fb7dea6"}'
        m = Macaroon.deserialize(json_v1, serializer=JsonSerializer())
        discharge = Macaroon.deserialize(json_v1_discharge,
                                         serializer=JsonSerializer())
        assert_macaroon(m, discharge, MACAROON_V1)

        binary_v1 = 'MDAxOWxvY2F0aW9uIG15IGxvY2F0aW9uCjAwMWRpZGVudGlmaWVyIG1' \
                    '5IGlkZW50aWZpZXIKMDAxMmNpZCBmcCBjYXZlYXQKMDAxMmNpZCB0cC' \
                    'BjYXZlYXQKMDA1MXZpZCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACn' \
                    '8yDEet8ud+825gOjM0pZOVE8/HpV6Zqxac+kl0BYToVaY64VfiwHj5r' \
                    'WgBREOkKMDAxM2NsIHRwIGxvY2F0aW9uCjAwMmZzaWduYXR1cmUgSDs' \
                    '4gcmZDlCZy2aV2jFk2qZNpgQXvK+encTAqZaPZjYK'
        binary_v1_discharge = 'MDAxOWxvY2F0aW9uIHRwIGxvY2F0aW9uCjAwMTlpZGVud' \
                              'GlmaWVyIHRwIGNhdmVhdAowMDJmc2lnbmF0dXJlIIUGAH' \
                              '9prj5qZU4Ll2nyDdnaXSr3hgBw1ndsFZift96mCg'
        m = Macaroon.deserialize(binary_v1)
        discharge = Macaroon.deserialize(binary_v1_discharge)
        assert_macaroon(m, discharge, MACAROON_V1)

        json_v2 = '{"c":[{"i":"fp caveat"},{"i":"tp caveat",' \
                  '"v64":"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAp_MgxHrfLnfvNuYDoz' \
                  'NKWTlRPPx6VemasWnPpJdAWE6FWmOuFX4sB4-a1oAURDp",' \
                  '"l":"tp location"}],"l":"my location","i":"my identifier",' \
                  '"s64":"SDs4gcmZDlCZy2aV2jFk2qZNpgQXvK-encTAqZaPZjY"}'
        json_v2_discharge = '{"l":"tp location","i":"tp caveat","s64":"hQYAf2' \
                            'muPmplTguXafIN2dpdKveGAHDWd2wVmJ-33qY"}'
        m = Macaroon.deserialize(json_v2, serializer=JsonSerializer())
        discharge = Macaroon.deserialize(json_v2_discharge,
                                         serializer=JsonSerializer())
        assert_macaroon(m, discharge, MACAROON_V2)

        binary_v2 = 'AgELbXkgbG9jYXRpb24CDW15IGlkZW50aWZpZXIAAglmcCBjYXZlYXQ' \
                    'AAQt0cCBsb2NhdGlvbgIJdHAgY2F2ZWF0BEgAAAAAAAAAAAAAAAAAAA' \
                    'AAAAAAAAAAAAACn8yDEet8ud+825gOjM0pZOVE8/HpV6Zqxac+kl0BY' \
                    'ToVaY64VfiwHj5rWgBREOkAAAYgSDs4gcmZDlCZy2aV2jFk2qZNpgQX' \
                    'vK+encTAqZaPZjY'
        binary_v2_discharge = 'AgELdHAgbG9jYXRpb24CCXRwIGNhdmVhdAAABiCFBgB/a' \
                              'a4+amVOC5dp8g3Z2l0q94YAcNZ3bBWYn7fepg'
        m = Macaroon.deserialize(binary_v2)
        discharge = Macaroon.deserialize(binary_v2_discharge)
        assert_macaroon(m, discharge, MACAROON_V2)
示例#23
0
def macaroon_from_dict(json_macaroon):
    '''Return a pymacaroons.Macaroon object from the given
    JSON-deserialized dict.

    @param JSON-encoded macaroon as dict
    @return the deserialized macaroon object.
    '''
    return Macaroon.deserialize(json.dumps(json_macaroon),
                                json_serializer.JsonSerializer())
示例#24
0
    def test_deserializing_json(self):
        m = Macaroon.deserialize(
            '{"location": "http://mybank/", "identifier": "we used our secret \
key", "signature": "197bac7a044af33332865b9266e26d493bdd668a660e44d88ce1a998c2\
3dbd67", "caveats": [{"cl": null, "cid": "test = caveat", "vid": null}]}',
            serializer=JsonSerializer())
        assert_equal(
            m.signature,
            '197bac7a044af33332865b9266e26d493bdd668a660e44d88ce1a998c23dbd67')
示例#25
0
def get_store_authorization(
        email, permissions=None, channels=None, store_env=None,
        allowed_stores=None, snaps=None):
    """Return the serialised root and discharge macaroon.

    Get a permissions macaroon from SCA and discharge it in SSO.
    """
    headers = DEFAULT_HEADERS.copy()
    # Request a SCA root macaroon with hard expiration in 180 days.
    sca_data = {
        'permissions': permissions or ['package_access'],
        'expires': (
            datetime.date.today() + datetime.timedelta(days=180)
            ).strftime('%Y-%m-%d 00:00:00')
    }
    if channels:
        sca_data['channels'] = channels
    if allowed_stores:
        sca_data['store_ids'] = allowed_stores
    if snaps:
        sca_data['packages'] = [{'name': snap} for snap in snaps]

    response = requests.request(
        url='{}/dev/api/acl/'.format(CONSTANTS[store_env]['sca_base_url']),
        method='POST', json=sca_data, headers=headers)
    if response.status_code != 200:
        error = response.json()['title']
        raise CliError("Error {}: {}".format(response.status_code, error))
    root = response.json()['macaroon']

    caveat, = [
        c for c in Macaroon.deserialize(root).third_party_caveats()
        if c.location == CONSTANTS[store_env]['sso_location']
    ]
    # Request a SSO discharge macaroon.
    sso_data = {
        'email': email,
        'password': getpass.getpass('Password for {}: '.format(email)),
        'caveat_id': caveat.caveat_id,
    }
    response = requests.request(
        url='{}/api/v2/tokens/discharge'.format(
            CONSTANTS[store_env]['sso_base_url']),
        method='POST', json=sso_data, headers=headers)
    # OTP/2FA is optional.
    if (response.status_code == 401 and
            response.json().get('code') == 'TWOFACTOR_REQUIRED'):
        sys.stderr.write('Second-factor auth for {}: '.format(store_env))
        sso_data.update({'otp': input()})
        response = requests.request(
            url='{}/api/v2/tokens/discharge'.format(
                CONSTANTS[store_env]['sso_base_url']),
            method='POST', json=sso_data, headers=headers)
    discharge = response.json()['discharge_macaroon']

    return root, discharge
示例#26
0
 def test_deserializing_accepts_padding(self):
     m = Macaroon.deserialize(
         ('MDAxY2xvY2F0aW9uIGh0dHA6Ly9teWJhbmsvCjAwMjZpZGVudGlmaWVyIHdlIHVz'
          'ZWQgb3VyIHNlY3JldCBrZXkKMDAxN2NpZCB0ZXN0ID0gYWNhdmVhdAowMDJmc2ln'
          'bmF0dXJlIJRJ_V3WNJQnqlVq5eez7spnltwU_AXs8NIRY739sHooCg==')
     )
     assert_equal(
         m.signature,
         '9449fd5dd6349427aa556ae5e7b3eeca6796dc14fc05ecf0d21163bdfdb07a28'
     )
示例#27
0
    def test_deserializing(self):
        m = Macaroon.deserialize(
            'MDAxY2xvY2F0aW9uIGh0dHA6Ly9teWJhbmsvCjAwMjZpZGVudGlmaW\
VyIHdlIHVzZWQgb3VyIHNlY3JldCBrZXkKMDAxNmNpZCB0ZXN0ID0gY2F2ZWF0CjAwMmZzaWduYXR1\
cmUgGXusegRK8zMyhluSZuJtSTvdZopmDkTYjOGpmMI9vWcK'
        )
        assert_equal(
            m.signature,
            '197bac7a044af33332865b9266e26d493bdd668a660e44d88ce1a998c23dbd67'
        )
示例#28
0
def login_device(macaroon, manufacturer, channel_id):
    m = Macaroon(location='localhost',
                 identifier=manufacturer,
                 key=keys[manufacturer])
    m1 = Macaroon.deserialize(macaroon)
    channels = []
    for caveat in m1.caveats:
        m.add_first_party_caveat(caveat.to_dict()['cid'])
        channels.append(caveat.to_dict()['cid'])
    return m1.signature == m.signature and channel_id in channels[2:]
示例#29
0
def r_feed_item(obj, info, *_):
    m = Macaroon.deserialize(
        info.context["request"].headers["Authorization"].replace(
            "Bearer ", ""))
    if isinstance(obj, Invoice):
        if m.identifier == obj.payee:
            return "UserInvoice"
        if m.identifier == obj.payer:
            return "PaidInvoice"
    return "Deposit"
示例#30
0
def get_caveat_id(root):
    """
    Returns the caveat_id generated by the SSO
    """
    caveat, = [
        c for c in Macaroon.deserialize(root).third_party_caveats()
        if c.location == 'login.ubuntu.com'
    ]

    return caveat.caveat_id
示例#31
0
 def test_serializing_v2(self):
     m = Macaroon(
         location='http://mybank/',
         identifier='we used our secret key',
         key='this is our super secret key; only we should know it',
         version=MACAROON_V2)
     m.add_first_party_caveat('test = caveat')
     n = Macaroon.deserialize(m.serialize())
     assert_equal(m.identifier_bytes, n.identifier_bytes)
     assert_equal(m.version, n.version)
示例#32
0
    async def check_auth(self,
                         info) -> Union[User, Tuple[LSAT, Macaroon], Error]:
        """Function to check authentication of user"""
        # check if auth header is present
        serial_macaroon, preimage = self.get_auth(info)
        if not serial_macaroon:
            return Error("NoCredentials",
                         "No token sent. You are not logged in")
        # attempt to deserialize macaroon
        try:
            macaroon = Macaroon.deserialize(serial_macaroon)
        except MacaroonDeserializationException:
            return Error("AuthenticationError", "Invalid token sent")

        # define types needed
        macaroon_key: bytes
        payload: Union[User, Tuple[LSAT, Macaroon]]
        # times token has been used. Only important with lsats
        used = 0
        # determine if auth is an lsat
        if "LSAT" in self.args.get("kind"):
            lsat: Optional[LSAT] = await LSAT.get(macaroon.identifier)
            if not lsat:
                return Error("AuthenticationError", "Could not find lsat")
            self.logger.critical(f"comparing {preimage} with {lsat.preimage}")
            if not preimage or preimage != lsat.preimage:
                return Error("AuthenticationError", "Invalid preimage")
            used = lsat.used
            macaroon_key = lsat.key
            payload = lsat

        # auth is standard macaroon
        else:
            # lookup user by identifier
            db_user: Optional[User] = await User.get(macaroon.identifier)
            if not db_user:
                return Error("AuthenticationError", "Could not find user")
            macaroon_key = db_user.key
            payload = db_user

        # verify macaroon against directive arguments
        try:
            verify(
                macaroon=macaroon,
                key=macaroon_key,
                roles=self.args.get("roles"),
                caveats=self.args.get("caveats"),
                used=used,
                req=info.context["request"],
            )
        except MacaroonInvalidSignatureException:
            return Error("AuthenticationError",
                         "Macaroon caveats not satisfied")

        return payload
示例#33
0
 def test_deserializing_json_v2(self):
     m = Macaroon.deserialize(
         '{"l": "http://mybank/", "i": "we used our secret key", "s": '
         '"197bac7a044af33332"'
         ', "c": [{"l": null, "i": "test = caveat", "v": null}]}',
         serializer=JsonSerializer()
     )
     assert_equal(
         m.signature_bytes,
         binascii.hexlify(b'197bac7a044af33332')
     )
示例#34
0
 def test_serializing_v2(self):
     m = Macaroon(
         location='http://mybank/',
         identifier='we used our secret key',
         key='this is our super secret key; only we should know it',
         version=MACAROON_V2
     )
     m.add_first_party_caveat('test = caveat')
     n = Macaroon.deserialize(m.serialize())
     assert_equal(m.identifier_bytes, n.identifier_bytes)
     assert_equal(m.version, n.version)
示例#35
0
def get_store_authorization(session: Session,
                            email: str,
                            password: str,
                            environment: str,
                            permissions: Optional[List[str]] = None,
                            channels: Optional[List[str]] = None):
    """Return the serialised root and discharge macaroon.

    Get a permissions macaroon from SCA and discharge it in SSO.
    """
    headers = DEFAULT_HEADERS.copy()
    # Request a SCA root macaroon with hard expiration in 180 days.
    sca_data = {
        'permissions':
        permissions or ['package_access'],
        'expires': (datetime.date.today() +
                    datetime.timedelta(days=180)).strftime('%Y-%m-%d 00:00:00')
    }
    if channels:
        sca_data.update({'channels': channels})
    response = session.request(url='{}/dev/api/acl/'.format(
        CONSTANTS[environment]['sca_base_url']),
                               method='POST',
                               json=sca_data,
                               headers=headers)
    root = response.json()['macaroon']

    caveat, = [
        c for c in Macaroon.deserialize(root).third_party_caveats()
        if c.location == CONSTANTS[environment]['sso_location']
    ]
    # Request a SSO discharge macaroon.
    sso_data = {
        'email': email,
        'password': password,
        'caveat_id': caveat.caveat_id,
    }
    response = session.request(url='{}/api/v2/tokens/discharge'.format(
        CONSTANTS[environment]['sso_base_url']),
                               method='POST',
                               json=sso_data,
                               headers=headers)
    # OTP/2FA is optional.
    if (response.status_code == 401
            and response.json().get('code') == 'TWOFACTOR_REQUIRED'):
        sys.stderr.write('Second-factor auth for {}: '.format(environment))
        sso_data.update({'otp': input()})
        response = session.request(url='{}/api/v2/tokens/discharge'.format(
            CONSTANTS[environment]['sso_base_url']),
                                   method='POST',
                                   json=sso_data,
                                   headers=headers)
    discharge = response.json()['discharge_macaroon']
    return root, discharge
示例#36
0
    def test_deserializing_json(self):
        m = Macaroon.deserialize(
            '{"location": "http://mybank/", "identifier": "we used our secret \
key", "signature": "197bac7a044af33332865b9266e26d493bdd668a660e44d88ce1a998c2\
3dbd67", "caveats": [{"cl": null, "cid": "test = caveat", "vid": null}]}',
            serializer=JsonSerializer()
        )
        assert_equal(
            m.signature,
            '197bac7a044af33332865b9266e26d493bdd668a660e44d88ce1a998c23dbd67'
        )
示例#37
0
def main():
    #---- Read arguments--------------------------------------------------------
    args = parse_args()
    url = args.source
    if not "https" in url:
        print("ERROR: URL has to start with https")
        sys.exit(1)
    #---------------------------------------------------------------------------

    #----- Config --------------------------------------------------------------
    # Set the logging level
    if args.verbose:
        logging.basicConfig(level=logging.DEBUG,
                            format='%(asctime)s  %(levelname)s - %(message)s',
                            datefmt='%Y%m%d %H:%M:%S')
    else:
        logging.basicConfig(level=logging.INFO,
                            format='%(asctime)s  %(levelname)s - %(message)s',
                            datefmt='%Y%m%d %H:%M:%S')

    # Check that the configuration file exists
    if os.path.isfile(".config"):
        configParser = configparser.RawConfigParser()
        configParser.read(".config")

        curl_debug = configParser.getint('all', 'curl_debug')
        proxy = configParser.get('all', 'proxy')
        timeout = configParser.getint('all', 'timeout')
    else:
        # If the .config file doesn't exist, set the defaults
        curl_debug = 1
        proxy = "/tmp/x509up_u0"
        timeout = 120

    #---------------------------------------------------------------------------

    tpc_util = TPC_util(log, timeout, curl_debug, proxy)
    caveats = "UPLOAD,DOWNLOAD,LIST,READ_METADATA"
    #caveats="DOWNLOAD,LIST"
    if args.ipv4:
        macaroon = tpc_util.request_macaroon(url, caveats, "-4")
    elif args.ipv6:
        macaroon = tpc_util.request_macaroon(url, caveats, "-6")
    else:
        macaroon = tpc_util.request_macaroon(url, caveats)
    if macaroon:
        log.info("Macaroon:\n" + macaroon)
        try:
            n = Macaroon.deserialize(macaroon)
            log.info("Macaroon deserialized:\n" + n.inspect())
        except:
            log.info("Cannot deserialize the macaroon")
    else:
        log.error("Cannot get the macaroon")
示例#38
0
def get_caveat_id(root):
    """
    Returns the caveat_id generated by the SSO
    """
    location = urlparse(LOGIN_URL).hostname
    (caveat, ) = [
        c for c in Macaroon.deserialize(root).third_party_caveats()
        if c.location == location
    ]

    return caveat.caveat_id
 def test_serializing_deserializing_macaroon(self, key_id, loc, key):
     assume(key_id and loc and key)
     macaroon = Macaroon(
         location=loc,
         identifier=key_id,
         key=key
     )
     deserialized = Macaroon.deserialize(macaroon.serialize())
     assert_equal(macaroon.identifier, deserialized.identifier)
     assert_equal(macaroon.location, deserialized.location)
     assert_equal(macaroon.signature, deserialized.signature)
def get_caveat_id(root):
    """
    Returns the caveat_id generated by the SSO
    """
    location = urlparse(LOGIN_URL).hostname
    caveat, = [
        c
        for c in Macaroon.deserialize(root).third_party_caveats()
        if c.location == location
    ]

    return caveat.caveat_id
示例#41
0
 def test_serializing_with_binary_v2(self):
     identifier = base64.b64decode('AK2o+q0Aq9+bONkXw7ky7HAuhCLO9hhaMMc==')
     m = Macaroon(
         location='http://mybank/',
         identifier=identifier,
         key='this is our super secret key; only we should know it',
         version=MACAROON_V2
     )
     m.add_first_party_caveat('test = caveat')
     n = Macaroon.deserialize(m.serialize())
     assert_equal(m.identifier_bytes, n.identifier_bytes)
     assert_equal(m.version, n.version)
示例#42
0
 def test_serializing_deserializing_json(self):
     m = Macaroon(
         location='http://test/',
         identifier='first',
         key='secret_key_1'
     )
     m.add_first_party_caveat('test = caveat')
     n = Macaroon.deserialize(
         m.serialize(serializer=JsonSerializer()),
         serializer=JsonSerializer()
     )
     assert_equal(m.signature, n.signature)
示例#43
0
 def test_serializing_json_v2_with_binary(self):
     id = base64.b64decode('AK2o+q0Aq9+bONkXw7ky7HAuhCLO9hhaMMc==')
     m = Macaroon(
         location='http://mybank/',
         identifier=id,
         key='this is our super secret key; only we should know it',
         version=MACAROON_V2
     )
     assert_equal(
         json.loads(m.serialize(serializer=JsonSerializer()))['i64'],
         "AK2o-q0Aq9-bONkXw7ky7HAuhCLO9hhaMMc"
     )
     n = Macaroon.deserialize(
         m.serialize(serializer=JsonSerializer()),
         serializer=JsonSerializer()
     )
     assert_equal(m.identifier_bytes, n.identifier_bytes)
示例#44
0
    def test_serializing_macaroon_with_first_and_third_caveats(self):
        m = Macaroon(
            location='http://mybank/',
            identifier='we used our other secret key',
            key='this is a different super-secret key; \
never use the same secret twice'
        )
        m.add_first_party_caveat('account = 3735928559')
        caveat_key = '4; guaranteed random by a fair toss of the dice'
        identifier = 'this was how we remind auth of key/pred'
        m.add_third_party_caveat('http://auth.mybank/', caveat_key, identifier)

        n = Macaroon.deserialize(m.serialize())

        assert_equal(
            m.signature,
            n.signature
        )
示例#45
0
 def test_deserializing_invalid(self):
     with assert_raises(MacaroonDeserializationException) as cm:
         Macaroon.deserialize("QA")