Exemple #1
0
def add_user_account(username, **_):
    """
    Add a user to the system
    
    Variables: 
    username    => Name of the user to add
    
    Arguments: 
    None
    
    Data Block:
    {                        
     "name": "Test user",        # Name of the user
     "is_active": true,          # Is the user active?
     "classification": "",            # Max classification for user
     "uname": "usertest",        # Username
     "is_admin": false,          # Is the user admin?
     "avatar": null,             # Avatar of the user
     "groups": ["TEST"]          # Groups the user is member of
    } 
    
    Result example:
    {
     "success": true             # Saving the user info succeded 
    }
    """

    data = request.json

    if "{" in username or "}" in username:
        return make_api_response({"success": False},
                                 "You can't use '{}' in the username", 412)

    if not STORAGE.get_user_account(username):
        new_pass = data.pop('new_pass', None)
        if new_pass:
            if not check_password_requirements(
                    new_pass, strict=config.auth.internal.strict_requirements):
                if config.auth.internal.strict_requirements:
                    error_msg = "Password needs to be 8 characters with at least an uppercase, " \
                                "a lowercase, a number and a special character."
                else:
                    error_msg = "Password needs to be 8 alphanumeric characters."
                return make_api_response({"success": False}, error_msg, 469)
            data['password'] = get_password_hash(new_pass)

        STORAGE.save_user(
            username,
            validate_settings(data,
                              ACCOUNT_DEFAULT,
                              exceptions=[
                                  'avatar', 'agrees_with_tos', 'dn',
                                  'password', 'otp_sk', 'u2f_devices'
                              ]))
        return make_api_response({"success": True})
    else:
        return make_api_response(
            {"success": False},
            "The username you are trying to add already exists.", 400)
Exemple #2
0
def list_submissions_for_user(username, **kwargs):
    """
    List all submissions of a given user.
    
    Variables:
    None
    
    Arguments: 
    offset       => Offset at which we start giving submissions
    length       => Numbers of submissions to return
    filter       => Filter to apply to the submission list
    
    Data Block:
    None
    
    Result example:
    {"total": 201,                # Total results found
     "offset": 0,                 # Offset in the result list
     "count": 100,                # Number of results returned
     "items": [                   # List of submissions
       {"submission": {             # Submission Block
          "description": "",          # Description of the submission
          "sid": "ad2...234",         # Submission ID
          "groups": "GROUP",          # Accessible groups
          "ttl": "30",                # Days to live
          "submitter": "user",        # ID of the submitter
          "max_score": "1422"},       # Max score of all files
        "times": {                  # Timing
          "submitted":                # Time submitted
            "2014-06-17T19:20:19Z"}, 
        "state": "completed"        # State of the submission
    }, ... ]}
    """
    user = kwargs['user']
    offset = int(request.args.get('offset', 0))
    length = int(request.args.get('length', 100))
    query = request.args.get('filter', "*")
    
    account = STORAGE.get_user_account(username)
    if not account: 
        return make_api_response("", "User %s does not exists." % username, 404)
        
    try:
        return make_api_response(STORAGE.list_submissions(username, start=offset, rows=length, qfilter=query,
                                                          access_control=user['access_control']))
    except RiakError, e:
        if e.value == "Query unsuccessful check the logs.":
            return make_api_response("", "The specified search query is not valid.", 400)
        else:
            raise
Exemple #3
0
def get_user_account(username, **kwargs):
    """
    Load the user account information.
    
    Variables: 
    username       => Name of the user to get the account info
    
    Arguments: 
    load_avatar    => If exists, this will load the avatar as well
    
    Data Block:
    None
    
    Result example:
    {                        
     "name": "Test user",        # Name of the user
     "is_active": true,          # Is the user active?
     "classification": "",            # Max classification for user
     "uname": "usertest",        # Username
     "is_admin": false,          # Is the user admin?
     "avatar": null,             # Avatar of the user
     "groups": ["TEST"]          # Groups the user is member of
    } 
    """
    if username != kwargs['user']['uname'] and not kwargs['user']['is_admin']:
        return make_api_response(
            {}, "You are not allow to view other users then yourself.", 403)

    user = STORAGE.get_user_account(username)
    if not user:
        return make_api_response({}, "User %s does not exists" % username, 404)

    user['2fa_enabled'] = user.pop('otp_sk', None) is not None
    user['apikeys'] = [x[0] for x in user.get('apikeys', [])]
    user['has_password'] = user.pop('password', None) is not None
    user['u2f_enabled'] = len(user.pop('u2f_devices', [])) != 0

    if "api_quota" not in user:
        user['api_quota'] = ACCOUNT_DEFAULT.get('api_quota', 10)

    if "submission_quota" not in user:
        user['submission_quota'] = ACCOUNT_DEFAULT.get('submission_quota', 5)

    if "load_avatar" in request.args:
        user['avatar'] = STORAGE.get_user_avatar(username)

    return make_api_response(user)
Exemple #4
0
def save_user_account(username, data, user):
    data = validate_settings(data,
                             ACCOUNT_DEFAULT,
                             exceptions=[
                                 'avatar', 'agrees_with_tos', 'dn', 'password',
                                 'otp_sk', 'u2f_devices'
                             ])

    if username != data['uname']:
        raise AccessDeniedException(
            "You are not allowed to change the username.")

    if username != user['uname'] and not user['is_admin']:
        raise AccessDeniedException(
            "You are not allowed to change another user then yourself.")

    current = STORAGE.get_user_account(username)
    if current:
        current = validate_settings(current,
                                    ACCOUNT_DEFAULT,
                                    exceptions=[
                                        'avatar', 'agrees_with_tos', 'dn',
                                        'password', 'otp_sk', 'u2f_devices'
                                    ])

        if not user['is_admin']:
            for key in current.iterkeys():
                if data[key] != current[
                        key] and key not in ACCOUNT_USER_MODIFIABLE:
                    raise AccessDeniedException(
                        "Only Administrators can change the value of the field [%s]."
                        % key)
    else:
        raise InvalidDataException(
            "You cannot save a user that does not exists [%s]." % username)

    if not data['avatar']:
        STORAGE.delete_user(data['uname'] + "_avatar")
    else:
        STORAGE.set_user_avatar(username, data['avatar'])
    data['avatar'] = None

    return STORAGE.set_user_account(username, data)
Exemple #5
0
def get_user_submission_params(username, **kwargs):
    """
    Load the user's default submission params that should be passed to the submit API.
    This is mainly use so you can alter a couple fields and preserve the user
    default values.

    Variables:
    username    => Name of the user you want to get the settings for

    Arguments:
    None

    Data Block:
    None

    Result example:
    {
     "profile": true,               # Should submissions be profiled
     "classification": "",          # Default classification for this user sumbissions
     "description": "",             # Default description for this user's submissions
     "priority": 1000,              # Default submission priority
     "service_spec": [],            # Default Service specific parameters
     "ignore_cache": true,          # Should file be reprocessed even if there are cached results
     "groups": [ ... ],             # Default groups selection for the user scans
     "ttl": 30,                     # Default time to live in days of the users submissions
     "services": [ ... ],           # Default list of selected services
     "ignore_tag": false,           # Send file to all service even if file not supported
     "ignore_filtering": false      # Should filtering services by ignored?
    }
    """
    user = kwargs['user']

    if username != "__CURRENT__" and username != user['uname']:
        user = STORAGE.get_user_account(username)

    params = load_user_settings(user)
    dispatch_task = ui_to_dispatch_task(params, kwargs['user']['uname'])
    dispatch_task['groups'] = user['groups']

    return make_api_response(dispatch_task)
Exemple #6
0
def get_user_settings(username, **kwargs):
    """
    Load the user's settings.
    
    Variables: 
    username    => Name of the user you want to get the settings for
    
    Arguments: 
    None
    
    Data Block:
    None
    
    Result example:
    {
     "profile": true,               # Should submissions be profiled
     "classification": "",          # Default classification for this user sumbissions
     "description": "",             # Default description for this user's submissions
     "hide_raw_results": false,     # Should you hide raw JSON results?
     "download_encoding": "blah",   # Default encoding for downloaded files
     "expand_min_score": 100,       # Default minimum score to auto-expand sections
     "priority": 1000,              # Default submission priority 
     "service_spec": [],            # Default Service specific parameters
     "ignore_cache": true,          # Should file be reprocessed even if there are cached results
     "groups": [ ... ],             # Default groups selection for the user scans
     "ttl": 30,                     # Default time to live in days of the users submissions
     "services": [ ... ],           # Default list of selected services
     "ignore_tag": false,           # Send file to all service even if file not supported
     "ignore_filtering": false      # Should filtering services by ignored?
    }
    """
    user = kwargs['user']

    if username != user['uname']:
        user = STORAGE.get_user_account(username)
    return make_api_response(load_user_settings(user))
Exemple #7
0
def agree_with_tos(username, **kwargs):
    """
    Specified user send agreement to Terms of Service

    Variables:
    username    => Name of the user that agrees with tos

    Arguments:
    None

    Data Block:
    None

    Result example:
    {
     "success": true             # Saving the user info succeded
    }
    """
    logged_in_user = kwargs['user']
    if logged_in_user['uname'] != username:
        return make_api_response(
            {"success": False},
            "You can't agree to Terms Of Service on behalf of someone else!",
            400)

    user = STORAGE.get_user_account(username)

    if not user:
        return make_api_response({"success": False},
                                 "User %s does not exist." % username, 403)
    else:
        user['agrees_with_tos'] = now_as_iso()
        if config.ui.get('tos_lockout', False):
            user['is_active'] = False
        STORAGE.save_user(username, user)
        return make_api_response({"success": True})
Exemple #8
0
def login(uname, path=None):
    user = STORAGE.get_user_account(uname)
    if not user:
        raise AccessDeniedException("User %s does not exists" % uname)

    if not user['is_active']:
        raise AccessDeniedException("User %s is disabled" % uname)

    add_access_control(user)

    if path:
        user["submenu"] = [{
            "icon": "glyphicon-user",
            "active": path.startswith("/account.html"),
            "link": "/account.html",
            "title": "Account"
        }, {
            "icon": "glyphicon-tasks",
            "active": path.startswith("/dashboard.html"),
            "link": "/dashboard.html",
            "title": "Dashboard"
        }, {
            "icon": "glyphicon-cog",
            "active": path.startswith("/settings.html"),
            "link": "/settings.html",
            "title": "Settings"
        }, {
            "icon": "glyphicon-log-out",
            "active": path.startswith("/logout.html"),
            "link": "/logout.html",
            "title": "Sign out"
        }]

        if user['is_admin']:
            user['menu_active'] = (path.startswith("/settings.html")
                                   or path.startswith("/account.html")
                                   or path.startswith("/admin/")
                                   or path.startswith("/dashboard.html")
                                   or path.startswith("/kibana-dash.html"))
            if config.logging.logserver.node:
                user["kibana_dashboards"] = [{
                    "icon":
                    None,
                    "active":
                    path.startswith("/kibana-dash.html?dash=%s" % x),
                    "link":
                    "/kibana-dash.html?dash=%s" % x,
                    "title":
                    "%s" % x.replace("-", " ")
                } for x in config.logging.logserver.kibana.dashboards
                                             if x != ""]
            user["admin_menu"] = [{
                "icon": None,
                "active": path.startswith("/admin/seed.html"),
                "link": "/admin/seed.html",
                "title": "Configuration"
            }, {
                "icon":
                None,
                "active":
                path.startswith("/admin/documentation.html"),
                "link":
                "/admin/documentation.html",
                "title":
                "Documentation"
            }, {
                "icon":
                None,
                "active":
                path.startswith("/admin/errors.html"),
                "link":
                "/admin/errors.html",
                "title":
                "Errors viewer"
            }, {
                "icon":
                None,
                "active":
                path.startswith("/admin/hosts.html"),
                "link":
                "/admin/hosts.html",
                "title":
                "Hosts"
            }, {
                "icon":
                None,
                "active":
                path.startswith("/admin/profiles.html"),
                "link":
                "/admin/profiles.html",
                "title":
                "Profiles"
            }, {
                "icon":
                None,
                "active":
                path.startswith("/admin/provisioning.html"),
                "link":
                "/admin/provisioning.html",
                "title":
                "Provisioning"
            }, {
                "icon":
                None,
                "active":
                path.startswith("/admin/services.html"),
                "link":
                "/admin/services.html",
                "title":
                "Services"
            }, {
                "icon":
                None,
                "active":
                path.startswith("/admin/site_map.html"),
                "link":
                "/admin/site_map.html",
                "title":
                "Site Map"
            }, {
                "icon":
                None,
                "active":
                path.startswith("/admin/users.html"),
                "link":
                "/admin/users.html",
                "title":
                "Users"
            }, {
                "icon":
                None,
                "active":
                path.startswith("/admin/virtual_machines.html"),
                "link":
                "/admin/virtual_machines.html",
                "title":
                "Virtual Machines"
            }]
        else:
            user['menu_active'] = (path.startswith("/settings.html")
                                   or path.startswith("/account.html")
                                   or path.startswith("/dashboard.html"))
            user["kibana_dashboards"] = []
            user["admin_menu"] = []

    user['2fa_enabled'] = user.pop('otp_sk', None) is not None
    user['allow_2fa'] = config.auth.get('allow_2fa', True)
    user['allow_apikeys'] = config.auth.get('allow_apikeys', True)
    user['allow_u2f'] = config.auth.get('allow_u2f', True)
    user['apikeys'] = [x[0] for x in user.get('apikeys', [])]
    user['c12n_enforcing'] = config.system.classification.definition.enforce
    user['has_password'] = user.pop('password', None) is not None
    user['internal_auth_enabled'] = config.auth.internal.enabled
    user['u2f_enabled'] = len(user.pop('u2f_devices', [])) != 0

    return user