Exemplo n.º 1
0
def get_profile_config(oauth, api_base_uri,
                       profile_id):  # type: (OAuth2Session, str, str) -> str
    """
    Return a profile configuration

    args:
        oauth (requests_oauthlib.OAuth2Session): oauth2 object
        api_base_uri (str): the instance base URI
        profile_id (str):
    """
    logger.info("Retrieving profile config from {}".format(api_base_uri))
    try:
        response = oauth.get(
            api_base_uri + '/profile_config?profile_id={}'.format(profile_id))
    except InvalidGrantError as e:
        raise EduvpnAuthException(str(e))
    if response.status_code == 401:
        raise EduvpnAuthException("request returned error 401")
    elif response.status_code != 200:
        raise EduvpnException("can't create profile, error code {}".format(
            response.status_code))
    # note: this is a bit ambiguous, in case there is an error, the result is json, otherwise clear text.
    try:
        json = response.json()['profile_config']
    except Exception:
        # probably valid response
        return response.text
    else:
        if not json['ok']:
            raise EduvpnException(json['error'])
        else:
            raise EduvpnException(
                "Server error! No profile config returned but no error also.")
Exemplo n.º 2
0
def user_messages(oauth, api_base_uri):  # type: (OAuth2Session, str) -> Any
    """
    These are messages specific to the user. It can contain a message about the user being blocked, or other personal
    messages from the VPN administrator.

    args:
        oauth (requests_oauthlib.OAuth2Session): oauth2 object
        api_base_uri (str): the instance base URI
    returns:
        list: a list of dicts with date_time, message, type keys
    """
    logger.info("Retrieving user messages from {}".format(api_base_uri))
    try:
        response = oauth.get(api_base_uri + '/user_messages')
    except InvalidGrantError as e:
        raise EduvpnAuthException(str(e))
    if response.status_code == 401:
        raise EduvpnAuthException("request returned error 401")
    elif response.status_code != 200:
        raise EduvpnException(
            "can't fetch user messages, error code {}".format(
                response.status_code))
    messages = response.json()['user_messages']
    _ = messages['ok']
    data = messages['data']
    for d in data:
        yield dateutil.parser.parse(d['date_time']), d['type'], d['message']
Exemplo n.º 3
0
def create_config(oauth, api_base_uri, display_name,
                  profile_id):  # type: (OAuth2Session, str, str, str) -> str
    """
    Create a configuration for a given profile.

    args:
        oauth (requests_oauthlib.OAuth2Session): oauth2 object
        api_base_uri (str): the instance base URI
        display_name (str):
        profile_id (str):
    """
    logger.info("Creating config with name '{}' and profile '{}' at {}".format(
        display_name, profile_id, api_base_uri))
    try:
        response = oauth.post(api_base_uri + '/create_config',
                              data={
                                  'display_name': display_name,
                                  'profile_id': profile_id
                              })
    except InvalidGrantError as e:
        raise EduvpnAuthException(str(e))
    if response.status_code == 401:
        raise EduvpnAuthException("request returned error 401")
    elif response.status_code != 200:
        raise EduvpnException("can't create config, error code {}".format(
            response.status_code))
    return response.json()
Exemplo n.º 4
0
def create_keypair(
        oauth, api_base_uri):  # type: (OAuth2Session, str) -> Tuple[str, str]
    """
    Create remote keypair and return results

    args:
        oauth (requests_oauthlib.OAuth2Session): oauth2 object
        api_base_uri (str): the instance base URI
    returns:
        tuple(str, str): certificate and key
    """
    logger.info(
        "Creating and retrieving key pair from {}".format(api_base_uri))
    try:
        response = oauth.post(api_base_uri + '/create_keypair',
                              data={'display_name': 'eduVPN for Linux'})
    except InvalidGrantError as e:
        raise EduvpnAuthException(str(e))
    if response.status_code == 401:
        raise EduvpnAuthException("request returned error 401")
    elif response.status_code != 200:
        raise EduvpnException("can't create keypair, error code {}".format(
            response.status_code))
    keypair = response.json()['create_keypair']['data']
    cert = keypair['certificate']
    key = keypair['private_key']
    return cert, key
Exemplo n.º 5
0
def user_info(oauth, api_base_uri):  # type: (OAuth2Session, str) -> dict
    """
    returns the user information

    args:
        oauth (requests_oauthlib.OAuth2Session): oauth2 object
        api_base_uri (str): the instance base URI
    """
    logger.info("Retrieving user info from {}".format(api_base_uri))
    try:
        response = oauth.get(api_base_uri + '/user_info')
    except InvalidGrantError as e:
        raise EduvpnAuthException(str(e))
    if response.status_code == 401:
        raise EduvpnAuthException("request returned error 401")
    elif response.status_code != 200:
        raise EduvpnException("can't retrieve user info, error code {}".format(
            response.status_code))
    data = response.json()['user_info']['data']
    assert ("is_disabled" in data)
    assert ("two_factor_enrolled" in data)
    if data["two_factor_enrolled"]:
        assert ("two_factor_enrolled_with" in data)
    assert ("user_id" in data)
    return data
Exemplo n.º 6
0
def two_factor_enroll_yubi(oauth, api_base_uri, yubi_key_otp):
    # type : (OAuth2Session, str, str) -> None
    try:
        response = oauth.post(api_base_uri + '/two_factor_enroll_yubi', data={'yubi_key_otp': yubi_key_otp})
    except InvalidGrantError as e:
        raise EduvpnAuthException(str(e))
    if response.status_code == 401:
        raise EduvpnAuthException("request returned error 401")
    elif response.status_code != 200:
        raise EduvpnException("can't retrieve user info, error code {}".format(response.status_code))
    data = response.json()['two_factor_enroll_yubi']
    if not data['ok']:
        raise EduvpnException(data['error'])
Exemplo n.º 7
0
def list_profiles(oauth, api_base_uri):
    """
    List profiles on instance

    args:
        oauth (requests_oauthlib.OAuth2Session): oauth2 object
        api_base_uri (str): the instance base URI

    returns:
        list: of available profiles on the instance (display_name, profile_id, two_factor)
    """
    logger.info("Retrieving profile list from {}".format(api_base_uri))
    response = oauth.get(api_base_uri + '/profile_list')
    if response.status_code == 401:
        raise EduvpnAuthException("request returned error 401")
    elif response.status_code != 200:
        raise Exception("can't list profiles, error code {}".format(
            response.status_code))
    data = response.json()['profile_list']['data']
    profiles = []
    for profile in data:
        display_name = translate_display_name(profile["display_name"])
        profile_id = profile["profile_id"]
        two_factor = profile["two_factor"]
        profiles.append((display_name, profile_id, two_factor))
    return profiles
Exemplo n.º 8
0
def two_factor_enroll_totp(oauth, api_base_uri, secret, key):
    # type : (OAuth2Session, str, secret, str) -> None
    prefix = '/two_factor_enroll_totp'
    url = api_base_uri + prefix
    logger.info("2fa totp enroling on {} with secret={} and key={}".format(url, secret, key))
    try:
        response = oauth.post(url, data={'totp_secret': secret, 'totp_key': key})
    except InvalidGrantError as e:
        raise EduvpnAuthException(str(e))
    if response.status_code == 401:
        raise EduvpnAuthException("request returned error 401")
    elif response.status_code != 200:
        logger.error(str(response.content))
        raise EduvpnException("can't enable 2fa otp, error code {} response {}".format(response.status_code,
                                                                                       response.content))
    data = response.json()['two_factor_enroll_totp']
    if not data['ok']:
        raise EduvpnException(data['error'])
Exemplo n.º 9
0
def check_certificate(oauth, api_base_uri, common_name):
    # type : (OAuth2Session, str, common_name) -> dict
    prefix = '/check_certificate'
    url = api_base_uri + prefix
    logger.info("checking client certificate on {} with common_name={}".format(url, common_name))
    try:
        response = oauth.get("{}?common_name={}".format(url, common_name))
    except InvalidGrantError as e:
        raise EduvpnAuthException(str(e))
    if response.status_code == 401:
        raise EduvpnAuthException("request returned error 401")
    elif response.status_code != 200:
        logger.error(str(response.content))
        raise EduvpnException("can't check client certificate, error code {} response {}".format(response.status_code,
                                                                                                 response.content))
    parsed = response.json()['check_certificate']
    if not parsed['ok']:
        raise EduvpnException(parsed['error'])
    return parsed['data']
Exemplo n.º 10
0
def system_messages(oauth, api_base_uri):
    """
    Return all system messages

    args:
        oauth (requests_oauthlib.OAuth2Session): oauth2 object
        api_base_uri (str): the instance base URI
    """
    logger.info("Retrieving system messages from {}".format(api_base_uri))
    try:
        response = oauth.get(api_base_uri + '/system_messages')
    except InvalidGrantError as e:
        raise EduvpnAuthException(str(e))
    if response.status_code == 401:
        raise EduvpnAuthException("request returned error 401")
    elif response.status_code != 200:
        raise EduvpnException("can't fetch system messages, error code {}".format(response.status_code))
    messages = response.json()['system_messages']
    _ = messages['ok']
    data = messages['data']
    for d in data:
        yield dateutil.parser.parse(d['date_time']), d['type'], d['message']
Exemplo n.º 11
0
def list_profiles(oauth, api_base_uri):  # type (OAuth2Session, str) -> dict
    """
    List profiles on instance

    args:
        oauth (requests_oauthlib.OAuth2Session): oauth2 object
        api_base_uri (str): the instance base URI

    returns:
        list: of available profiles on the instance (display_name, profile_id, two_factor)
    """
    logger.info("Retrieving profile list from {}".format(api_base_uri))
    try:
        response = oauth.get(api_base_uri + '/profile_list')
    except InvalidGrantError as e:
        raise EduvpnAuthException(str(e))
    if response.status_code == 401:
        raise EduvpnAuthException("request returned error 401")
    elif response.status_code != 200:
        raise EduvpnException("can't list profiles, error code {}".format(
            response.status_code))
    data = response.json()['profile_list']['data']
    profiles = []
    for profile in data:
        display_name = translate_display_name(profile["display_name"])
        profile_id = profile["profile_id"]
        two_factor = profile["two_factor"]
        if two_factor:
            if "two_factor_method" in profile:
                two_factor_method = profile["two_factor_method"]
            else:
                two_factor_method = ["yubi", "totp"]
        else:
            two_factor_method = []
        # we load this into a GtkListModel which doesnt support lists, so we concat them with ,
        profiles.append((display_name, profile_id, two_factor,
                         ",".join(two_factor_method)))
    return profiles
Exemplo n.º 12
0
def user_info(oauth, api_base_uri):
    """
    returns the user information

    args:
        oauth (requests_oauthlib.OAuth2Session): oauth2 object
        api_base_uri (str): the instance base URI
    """
    logger.info("Retrieving user info from {}".format(api_base_uri))
    response = oauth.get(api_base_uri + '/user_info')
    if response.status_code == 401:
        raise EduvpnAuthException("request returned error 401")
    elif response.status_code != 200:
        raise Exception("can't retrieve user info, error code {}".format(
            response.status_code))
    data = response.json()['user_info']['data']
    return data
Exemplo n.º 13
0
def disable_2fa(user, password, totp_secret, base_url):
    prefix = "/vpn-admin-portal"
    admin_url = base_url + prefix
    browser = mechanicalsoup.StatefulBrowser(raise_on_404=True)
    logger.info("opening auth_url")
    response = browser.open(admin_url)
    assert response.ok
    browser.select_form()
    browser["userName"] = user
    browser["userPass"] = password
    logger.info("logging in")
    response = browser.submit_selected()
    assert response.ok
    form = browser.select_form()
    if form.form.attrs['action'] != prefix + '/_two_factor/auth/verify/totp':
        logger.warning("2fa not enabled")
        return

    # redirected to totp screen
    totp = TOTP(totp_secret)
    browser['_two_factor_auth_totp_key'] = totp.now()
    logger.info("submitting totp key")
    response = browser.submit_selected()
    assert response.ok

    form = browser.select_form()
    if form.form.attrs['action'] == prefix + '/_two_factor/auth/verify/totp':
        error = browser.get_current_page().findAll(
            "p", {"class": "error"})[0].contents[0].strip()
        raise EduvpnAuthException(error)

    response = browser.open("{}/user?user_id={}".format(admin_url, user))
    assert response.ok
    form = browser.select_form()
    button = form.form.select('button[value="deleteTotpSecret"]')
    if button:
        response = browser.submit_selected()
        assert (response.ok)
    else:
        logger.error(form.form)
        logger.error("2fa not enabled, but had to supply otp during login")
Exemplo n.º 14
0
def authorize(auth_url, user, password):
    browser = mechanicalsoup.StatefulBrowser(raise_on_404=True)
    logger.info("opening auth_url")
    response = browser.open(auth_url)
    assert (response.ok)
    browser.select_form('form[action="/vpn-user-portal/_form/auth/verify"]')
    browser["userName"] = user
    browser["userPass"] = password
    logger.info("logging in")
    response = browser.submit_selected()
    assert (response.ok)
    form = browser.select_form()
    if 'action' in form.form.attrs and form.form.attrs[
            'action'] == '/vpn-user-portal/_two_factor/auth/verify/totp':
        raise EduvpnAuthException("otp enabled")
    assert (urlparse(
        browser.get_url()).path == "/vpn-user-portal/_oauth/authorize"
            )  # make sure is the right page
    form = browser.select_form()
    form.form.select('button[value="yes"]')
    logger.info("authorising app")
    response = browser.submit_selected()
    assert (response.ok)