Exemplo n.º 1
0
def disconnect_handler(remote, *args, **kwargs):
    """Handle unlinking of remote account.

    :param remote: The remote application.
    :returns: The HTML response.
    """
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    remote_account = RemoteAccount.get(user_id=current_user.get_id(),
                                       client_id=remote.consumer_key)
    external_method = 'github'
    external_ids = [
        i.id for i in current_user.external_identifiers
        if i.method == external_method
    ]

    if external_ids:
        oauth_unlink_external_id(
            dict(id=external_ids[0], method=external_method))
    if remote_account:
        with db.session.begin_nested():
            remote_account.delete()

    return redirect(url_for('invenio_oauthclient_settings.index'))
Exemplo n.º 2
0
def test_utilities(models_fixture):
    """Test utilities."""
    app = models_fixture
    datastore = app.extensions['invenio-accounts'].datastore
    assert obj_or_import_string('invenio_oauthclient.errors')

    # User
    existing_email = '*****@*****.**'
    user = datastore.find_user(email=existing_email)

    # Authenticate
    assert not _get_external_id({})
    assert not oauth_authenticate('dev', user, require_existing_link=True)

    _security.confirmable = True
    _security.login_without_confirmation = False
    user.confirmed_at = None
    assert not oauth_authenticate('dev', user)

    # Tokens
    t = RemoteToken.create(user.id, 'dev', 'mytoken', 'mysecret')
    assert \
        RemoteToken.get(user.id, 'dev', access_token='mytoken') == \
        RemoteToken.get_by_token('dev', 'mytoken')

    assert oauth_get_user('dev', access_token=t.access_token) == user
    assert \
        oauth_get_user('dev', account_info={
            'user': {
                'email': existing_email
            }
        }) == user

    # Link user to external id
    external_id = {'id': '123', 'method': 'test_method'}
    oauth_link_external_id(user, external_id)

    with pytest.raises(AlreadyLinkedError):
        oauth_link_external_id(user, external_id)

    assert oauth_get_user('dev',
                          account_info={
                              'external_id': external_id['id'],
                              'external_method': external_id['method']
                          }) == user

    # Cleanup
    oauth_unlink_external_id(external_id)
    acc = RemoteAccount.get(user.id, 'dev')
    acc.delete()
Exemplo n.º 3
0
def _disconnect(remote, *args, **kwargs):
    """Handle unlinking of remote account."""
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    account = RemoteAccount.get(user_id=current_user.get_id(),
                                client_id=remote.consumer_key)
    external_id = account.extra_data.get("external_id")

    if external_id:
        oauth_unlink_external_id(dict(id=external_id, method="cern_openid"))
    if account:
        with db.session.begin_nested():
            account.delete()

    disconnect_identity(g.identity)
Exemplo n.º 4
0
def disconnect_handler(remote, *args, **kwargs):
    """Handle unlinking of remote account."""
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    account = RemoteAccount.get(user_id=current_user.get_id(),
                                client_id=remote.consumer_key)
    orcid = account.extra_data.get('orcid')

    if orcid:
        oauth_unlink_external_id(dict(id=orcid, method='orcid'))
    if account:
        with db.session.begin_nested():
            account.delete()

    return redirect(url_for('invenio_oauthclient_settings.index'))
Exemplo n.º 5
0
def test_utilities(models_fixture):
    """Test utilities."""
    app = models_fixture
    datastore = app.extensions['invenio-accounts'].datastore
    assert obj_or_import_string('invenio_oauthclient.errors')

    # User
    existing_email = '*****@*****.**'
    user = datastore.find_user(email=existing_email)

    # Authenticate
    assert not _get_external_id({})
    assert not oauth_authenticate('dev', user, require_existing_link=True)

    _security.confirmable = True
    _security.login_without_confirmation = False
    user.confirmed_at = None
    assert not oauth_authenticate('dev', user)

    # Tokens
    t = RemoteToken.create(user.id, 'dev', 'mytoken', 'mysecret')
    assert \
        RemoteToken.get(user.id, 'dev', access_token='mytoken') == \
        RemoteToken.get_by_token('dev', 'mytoken')

    assert oauth_get_user('dev', access_token=t.access_token) == user
    assert \
        oauth_get_user('dev', account_info={'user': {'email': existing_email}}) == user

    # Link user to external id
    external_id = {'id': '123', 'method': 'test_method'}
    oauth_link_external_id(user, external_id)

    with pytest.raises(AlreadyLinkedError):
        oauth_link_external_id(user, external_id)

    assert oauth_get_user('dev',
                          account_info={
                              'external_id': external_id['id'],
                              'external_method': external_id['method']
                          }) == user

    # Cleanup
    oauth_unlink_external_id(external_id)
    acc = RemoteAccount.get(user.id, 'dev')
    acc.delete()
Exemplo n.º 6
0
def _disconnect(remote, *args, **kwargs):
    """Handle unlinking of remote account.

    :param remote: The remote application.
    """
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    account = RemoteAccount.get(user_id=current_user.get_id(),
                                client_id=remote.consumer_key)
    orcid = account.extra_data.get('orcid')

    if orcid:
        oauth_unlink_external_id({'id': orcid, 'method': 'orcid'})
    if account:
        with db.session.begin_nested():
            account.delete()
Exemplo n.º 7
0
def disconnect_handler(remote, *args, **kwargs):
    """Handle unlinking of remote account."""
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    account = RemoteAccount.get(user_id=current_user.get_id(),
                                client_id=remote.consumer_key)
    external_id = account.extra_data.get('external_id')

    if external_id:
        oauth_unlink_external_id(dict(id=external_id, method='cern'))
    if account:
        with db.session.begin_nested():
            account.delete()

    disconnect_identity(g.identity)

    return redirect(url_for('invenio_oauthclient_settings.index'))
Exemplo n.º 8
0
def _disconnect(remote, *args, **kwargs):
    """Common logic for handling disconnection of remote accounts."""
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    account = RemoteAccount.get(user_id=current_user.get_id(),
                                client_id=remote.consumer_key)

    keycloak_id = account.extra_data.get("keycloak_id")

    if keycloak_id:
        external_id = {"id": keycloak_id, "method": remote.name}

        oauth_unlink_external_id(external_id)

    if account:
        with db.session.begin_nested():
            account.delete()
Exemplo n.º 9
0
def disconnect_handler(remote, *args, **kwargs):
    """Handle unlinking of remote account."""
    from invenio_oauthclient.utils import oauth_unlink_external_id
    from invenio_oauthclient.models import RemoteAccount

    if not current_user.is_authenticated():
        return current_app.login_manager.unauthorized()

    account = RemoteAccount.get(user_id=current_user.get_id(),
                                client_id=remote.consumer_key)
    orcid = account.extra_data.get('orcid')

    if orcid:
        oauth_unlink_external_id(dict(id=orcid, method='orcid'))
    if account:
        account.delete()

    return redirect(url_for('oauthclient_settings.index'))
Exemplo n.º 10
0
def disconnect_handler(remote, *args, **kwargs):
    """Handle unlinking of remote account."""
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    remote_account = RemoteAccount.get(user_id=current_user.get_id(),
                                       client_id=remote.consumer_key)
    external_method = 'github'
    external_ids = [i.id for i in current_user.external_identifiers
                    if i.method == external_method]

    if external_ids:
        oauth_unlink_external_id(dict(id=external_ids[0],
                                      method=external_method))
    if remote_account:
        with db.session.begin_nested():
            remote_account.delete()

    return redirect(url_for('invenio_oauthclient_settings.index'))
Exemplo n.º 11
0
    def handle_disconnect(self, remote, *args, **kwargs):
        """Handle unlinking of remote account.

        :param remote: The remote application.
        """
        if not current_user.is_authenticated:
            return current_app.login_manager.unauthorized()

        account = RemoteAccount.get(user_id=current_user.get_id(),
                                    client_id=remote.consumer_key)
        sub = account.extra_data.get('sub')

        if sub:
            oauth_unlink_external_id({'id': sub, 'method': self.name})
        if account:
            with db.session.begin_nested():
                account.delete()

        return redirect(url_for('invenio_oauthclient_settings.index'))
Exemplo n.º 12
0
def test_utilities(models_fixture):
    """Test utilities."""
    app = models_fixture
    datastore = app.extensions["invenio-accounts"].datastore
    assert obj_or_import_string("invenio_oauthclient.errors")

    # User
    existing_email = "*****@*****.**"
    user = datastore.find_user(email=existing_email)

    # Authenticate
    assert not _get_external_id({})
    assert not oauth_authenticate("dev", user, require_existing_link=True)

    _security.confirmable = True
    _security.login_without_confirmation = False
    user.confirmed_at = None
    assert not oauth_authenticate("dev", user)

    # Tokens
    t = RemoteToken.create(user.id, "dev", "mytoken", "mysecret")
    assert RemoteToken.get(user.id, "dev", access_token="mytoken") == RemoteToken.get_by_token("dev", "mytoken")

    assert oauth_get_user("dev", access_token=t.access_token) == user
    assert oauth_get_user("dev", account_info={"user": {"email": existing_email}}) == user

    # Link user to external id
    external_id = {"id": "123", "method": "test_method"}
    oauth_link_external_id(user, external_id)

    with pytest.raises(AlreadyLinkedError):
        oauth_link_external_id(user, external_id)

    assert (
        oauth_get_user("dev", account_info={"external_id": external_id["id"], "external_method": external_id["method"]})
        == user
    )

    # Cleanup
    oauth_unlink_external_id(external_id)
    acc = RemoteAccount.get(user.id, "dev")
    acc.delete()
Exemplo n.º 13
0
def disconnect(remote):
    """Disconnect callback handler for GitHub."""
    # User must be authenticated
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    external_method = 'github'
    external_ids = [i.id for i in current_user.external_identifiers
                    if i.method == external_method]
    if external_ids:
        oauth_unlink_external_id(dict(id=external_ids[0],
                                      method=external_method))

    user_id = int(current_user.get_id())
    token = RemoteToken.get(user_id, remote.consumer_key)
    if token:
        extra_data = token.remote_account.extra_data

        # Delete the token that we issued for GitHub to deliver webhooks
        webhook_token_id = extra_data.get('tokens', {}).get('webhook')
        ProviderToken.query.filter_by(id=webhook_token_id).delete()

        # Disable GitHub webhooks from our side
        db_repos = Repository.query.filter_by(user_id=user_id).all()
        # Keep repositories with hooks to pass to the celery task later on
        repos_with_hooks = [(r.github_id, r.hook) for r in db_repos if r.hook]
        for repo in db_repos:
            try:
                Repository.disable(user_id=user_id,
                                   github_id=repo.github_id,
                                   name=repo.name)
            except NoResultFound:
                # If the repository doesn't exist, no action is necessary
                pass
        db.session.commit()

        # Send Celery task for webhooks removal and token revocation
        disconnect_github.delay(token.access_token, repos_with_hooks)
        # Delete the RemoteAccount (along with the associated RemoteToken)
        token.remote_account.delete()

    return redirect(url_for('invenio_oauthclient_settings.index'))
Exemplo n.º 14
0
def disconnect(remote):
    """Disconnect callback handler for GitHub."""
    # User must be authenticated
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    external_method = 'github'
    external_ids = [i.id for i in current_user.external_identifiers
                    if i.method == external_method]
    if external_ids:
        oauth_unlink_external_id(dict(id=external_ids[0],
                                      method=external_method))

    user_id = current_user.get_id()
    token = RemoteToken.get(user_id, remote.consumer_key)
    if token:
        extra_data = token.remote_account.extra_data

        # Delete the token that we issued for GitHub to deliver webhooks
        webhook_token_id = extra_data.get('tokens', {}).get('webhook')
        ProviderToken.query.filter_by(id=webhook_token_id).delete()

        # Disable GitHub webhooks from our side
        db_repos = Repository.query.filter_by(user_id=user_id).all()
        # Keep repositories with hooks to pass to the celery task later on
        repos_with_hooks = [(r.github_id, r.hook) for r in db_repos if r.hook]
        for repo in db_repos:
            try:
                Repository.disable(user_id=user_id,
                                   github_id=repo.github_id,
                                   name=repo.name)
            except NoResultFound:
                # If the repository doesn't exist, no action is necessary
                pass
        db.session.commit()

        # Send Celery task for webhooks removal and token revocation
        disconnect_github.delay(token.access_token, repos_with_hooks)
        # Delete the RemoteAccount (along with the associated RemoteToken)
        token.remote_account.delete()

    return redirect(url_for('invenio_oauthclient_settings.index'))
Exemplo n.º 15
0
def _disconnect(remote, *args, **kwargs):
    """Handle unlinking of remote account.

    :param remote: The remote application.
    """
    if not current_user.is_authenticated:
        return current_app.login_manager.unauthorized()

    remote_account = RemoteAccount.get(user_id=current_user.get_id(),
                                       client_id=remote.consumer_key)
    external_method = 'openaire_aai'
    external_ids = [
        i.id for i in current_user.external_identifiers
        if i.method == external_method
    ]

    if external_ids:
        oauth_unlink_external_id(
            dict(id=external_ids[0], method=external_method))
    if remote_account:
        with db.session.begin_nested():
            remote_account.delete()