Пример #1
0
def _get_cached_signatures(signature_cache, query_hash):
    try:
        s = signature_cache.get(query_hash)
        if s is None or s == b'':
            return s
        return make_file_response(s,
                                  f"al_signatures_{query_hash[:7]}.zip",
                                  len(s),
                                  content_type="application/zip")
    except Exception:  # pylint: disable=W0702
        LOGGER.exception('Failed to read cached signatures:')

    return None
Пример #2
0
def oauth_validate(**_):
    """
    Validate and oAuth session and return it's associated username, avatar and oAuth Token

    Variables:
    None

    Arguments:
    provider   =>   Which oAuth provider to validate the token against
    *          =>   All parameters returned by your oAuth provider callback...

    Data Block:
    None

    Result example:
    {
     "avatar": "data:image...",
     "oauth_token": "123123...123213",
     "username": "******"
    }
    """
    oauth_provider = request.values.get('provider', None)
    avatar = None
    username = None
    email_adr = None
    oauth_token = None

    if config.auth.oauth.enabled:
        oauth = current_app.extensions.get('authlib.integrations.flask_client')
        provider = oauth.create_client(oauth_provider)

        if provider:
            # noinspection PyBroadException
            try:
                oauth_provider_config = config.auth.oauth.providers[
                    oauth_provider]
                if oauth_provider_config.app_provider:
                    # Validate the token that we've received using the secret
                    token = provider.authorize_access_token(
                        client_secret=oauth_provider_config.client_secret)

                    # Initialize the app_provider
                    app_provider = OAuth2Session(
                        oauth_provider_config.app_provider.client_id
                        or oauth_provider_config.client_id,
                        oauth_provider_config.app_provider.client_secret
                        or oauth_provider_config.client_secret,
                        scope=oauth_provider_config.app_provider.scope)
                    app_provider.fetch_token(
                        oauth_provider_config.app_provider.access_token_url,
                        grant_type="client_credentials")

                else:
                    # Validate the token
                    token = provider.authorize_access_token()
                    app_provider = None

                user_data = None
                if oauth_provider_config.jwks_uri:
                    user_data = provider.parse_id_token(token)

                # Get user data from endpoint
                if app_provider and oauth_provider_config.app_provider.user_get:
                    url = oauth_provider_config.app_provider.user_get
                    uid = user_data.get('id', None)
                    if not uid and user_data and oauth_provider_config.uid_field:
                        uid = user_data.get(oauth_provider_config.uid_field,
                                            None)
                    if uid:
                        url = url.format(id=uid)
                    resp = app_provider.get(url)
                    if resp.ok:
                        user_data = resp.json()
                elif not user_data:
                    resp = provider.get(oauth_provider_config.user_get)
                    if resp.ok:
                        user_data = resp.json()

                # Add group data if API is configured for it
                groups = []
                if app_provider and oauth_provider_config.app_provider.group_get:
                    url = oauth_provider_config.app_provider.group_get
                    uid = user_data.get('id', None)
                    if not uid and user_data and oauth_provider_config.uid_field:
                        uid = user_data.get(oauth_provider_config.uid_field,
                                            None)
                    if uid:
                        url = url.format(id=uid)
                    resp_grp = app_provider.get(url)
                    if resp_grp.ok:
                        groups = resp_grp.json()
                elif oauth_provider_config.user_groups:
                    resp_grp = provider.get(oauth_provider_config.user_groups)
                    if resp_grp.ok:
                        groups = resp_grp.json()

                if groups:
                    if oauth_provider_config.user_groups_data_field:
                        groups = groups[
                            oauth_provider_config.user_groups_data_field]

                    if oauth_provider_config.user_groups_name_field:
                        groups = [
                            x[oauth_provider_config.user_groups_name_field]
                            for x in groups
                        ]

                    user_data['groups'] = groups

                if user_data:
                    data = parse_profile(user_data, oauth_provider_config)
                    has_access = data.pop('access', False)
                    if has_access and data['email'] is not None:
                        oauth_avatar = data.pop('avatar', None)

                        # Find if user already exists
                        users = STORAGE.user.search(f"email:{data['email']}",
                                                    fl="*",
                                                    as_obj=False)['items']
                        if users:
                            cur_user = users[0]
                            # Do not update username and password from the current user
                            data['uname'] = cur_user.get(
                                'uname', data['uname'])
                            data['password'] = cur_user.get(
                                'password', data['password'])
                        else:
                            if data['uname'] != data['email']:
                                # Username was computed using a regular expression, lets make sure we don't
                                # assign the same username to two users
                                res = STORAGE.user.search(
                                    f"uname:{data['uname']}",
                                    rows=0,
                                    as_obj=False)
                                if res['total'] > 0:
                                    cnt = res['total']
                                    new_uname = f"{data['uname']}{cnt}"
                                    while STORAGE.user.get(
                                            new_uname) is not None:
                                        cnt += 1
                                        new_uname = f"{data['uname']}{cnt}"
                                    data['uname'] = new_uname
                            cur_user = {}

                        username = data['uname']
                        email_adr = data['email']

                        # Add add dynamic classification group
                        data['classification'] = get_dynamic_classification(
                            data['classification'], data['email'])

                        # Make sure the user exists in AL and is in sync
                        if (not cur_user and oauth_provider_config.auto_create) or \
                                (cur_user and oauth_provider_config.auto_sync):

                            # Update the current user
                            cur_user.update(data)

                            # Save avatar
                            if oauth_avatar:
                                avatar = fetch_avatar(oauth_avatar, provider,
                                                      oauth_provider_config)
                                if avatar:
                                    STORAGE.user_avatar.save(username, avatar)

                            # Save updated user
                            STORAGE.user.save(username, cur_user)

                        if cur_user:
                            if avatar is None:
                                avatar = STORAGE.user_avatar.get(
                                    username
                                ) or "/static/images/user_default.png"
                            oauth_token = hashlib.sha256(
                                str(token).encode(
                                    "utf-8", errors='replace')).hexdigest()
                            get_token_store(username).add(oauth_token)
                        else:
                            return make_api_response(
                                {"err_code": 3},
                                err="User auto-creation is disabled",
                                status_code=403)
                    else:
                        return make_api_response(
                            {"err_code": 2},
                            err="This user is not allowed access to the system",
                            status_code=403)

            except OAuthError as err:
                return make_api_response({"err_code": 1},
                                         err=str(err),
                                         status_code=401)

            except Exception as err:
                LOGGER.exception(str(err))
                return make_api_response(
                    {
                        "err_code": 1,
                        "exception": str(err)
                    },
                    err=
                    "Unhandled exception occured while processing oAuth token",
                    status_code=401)

    if username is None:
        return make_api_response({"err_code": 0},
                                 err="oAuth disabled on the server",
                                 status_code=401)

    return make_api_response({
        "avatar": avatar,
        "username": username,
        "oauth_token": oauth_token,
        "email_adr": email_adr
    })
Пример #3
0
                # TODO: this needs testing that can only be done when a service datasource is available.
                path = cfg
                cfg = config
                for point in path.split('.'):
                    if 'enabled' in cfg:
                        if not cfg['enabled']:
                            raise SkipDatasource()
                    cfg = cfg.get(point)
            cls = load_module_by_path(classpath)
            obj = cls(LOGGER, **cfg)
            sources[name] = create_query_datasource(obj)
        except SkipDatasource:
            continue
        except Exception:
            LOGGER.exception(
                "Problem creating %s datasource (%s)", name, classpath
            )
except Exception:
    LOGGER.exception("No datasources")


# noinspection PyUnusedLocal
@hash_search_api.route("/<file_hash>/", methods=["GET"])
@api_login(required_priv=['R'])
def search_hash(file_hash, *args, **kwargs):
    """
    Search for a hash in multiple data sources as configured in the seed.

    Variables:
    file_hash   => Hash to search in the multiple data sources
                   [MD5, SHA1 or SHA256]