<commit_before># -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
#               2015 CERN.
#
# Invenio is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# Invenio is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Invenio; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

"""Invenio Access Control Admin."""

from __future__ import print_function

import urlparse

from flask import current_app

from intbitset import intbitset

from invenio.config import CFG_SITE_ADMIN_EMAIL, CFG_SITE_LANG, CFG_SITE_RECORD
from invenio.ext import principal
from invenio.ext.sqlalchemy import db
from invenio.legacy.dbquery import run_sql
from invenio.modules.access.firerole import (
    acc_firerole_check_user, compile_role_definition, deserialize,
    load_role_definition, serialize
)
from invenio.modules.access.local_config import (
    CFG_ACC_ACTIVITIES_URLS, CFG_ACC_EMPTY_ROLE_DEFINITION_SER,
    CFG_ACC_EMPTY_ROLE_DEFINITION_SRC, DEF_AUTHS, DEF_ROLES, DEF_USERS,
    DELEGATEADDUSERROLE, SUPERADMINROLE
)
from invenio.modules.access.models import AccACTION, AccAuthorization, \
    UserAccROLE

from six import iteritems

from sqlalchemy.exc import ProgrammingError


def acc_add_action(name_action='', description='', optional='no',
                   *allowedkeywords):
    """Create new entry in accACTION for an action.

    :param name_action: name of the new action, must be unique
    :param allowedkeywords: a list of allowedkeywords

    :return: id_action, name_action, description and allowedkeywords or
             0 in case of failure
    """
    keystr = ''
    # action with this name already exists, return 0
    if db.session.query(
            AccACTION.query.filter(
                AccACTION.name == name_action).exists()).scalar():
        return 0

    # create keyword string
    for value in allowedkeywords:
        if keystr:
            keystr += ','
        keystr += value

    if not allowedkeywords:
        optional = 'no'

    # insert the new entry
    try:
        a = AccACTION(name=name_action, description=description,
                      allowedkeywords=keystr, optional=optional)
        db.session.add(a)
        db.session.commit()
        return True, name_action, description, keystr, optional
    except ProgrammingError:
        return 0


def acc_delete_action(id_action=0, name_action=0):
    """Delete action in accACTION according to id, or secondly name.

    entries in accROLE_accACTION_accARGUMENT will also be removed.
    If the name or id is wrong, the function does nothing.

    :param id_action: id of action to be deleted, prefered variable
    :param name_action: this is used if id_action is not given
    """
    id_action = id_action or acc_get_action_id(name_action=name_action)
    if not id_action:
        return 0

    # delete the action
    if run_sql("""DELETE FROM "accACTION" WHERE id=%s""", (id_action, )):
        # delete all entries related
        return 1 + run_sql("""DELETE FROM "accROLE_accACTION_accARGUMENT" WHERE
            "id_accACTION" =%s""", (id_action, ))
    else:
        return 0


def acc_verify_action(name_action='', description='', allowedkeywords='',
                      dummy=''):
    """Check action.

    check if all the values of a given action are the same as
    those in accACTION in the database. self explanatory parameters.

    return id if identical, 0 if not.
    """
    id_action = acc_get_action_id(name_action=name_action)

    if not id_action:
        return 0

    res_desc = acc_get_action_description(id_action=id_action)
    res_keys = acc_get_action_keywords_string(id_action=id_action)

    bool_desc = res_desc == description and 1 or 0
    bool_keys = res_keys == allowedkeywords and 1 or 0
    bool_opti = acc_get_action_is_optional(id_action=id_action)

    return bool_desc and bool_keys and bool_opti and id_action or 0


def acc_update_action(id_action=0, name_action='', verbose=0, **update):
    """Try to change the values of given action details.

    if there is no change nothing is done.
    some changes require to update other parts of the database.

    :param id_action: id of the action to change
    :param name_action: if no id_action is given try to find it using this name
    :param **update: dictionary containg keywords: description, allowed
        keywords and/or optional other keywords are ignored
    """
    id_action = id_action or acc_get_action_id(name_action=name_action)

    if not id_action:
        return 0

    try:
        if 'description' in update:
            # change the description, no other effects
            if verbose:
                print('desc')
                run_sql(
                    """UPDATE "accACTION" SET description = %s """
                    """WHERE id = %s""",
                    (update['description'], id_action))

        if 'allowedkeywords' in update:
            # change allowedkeywords
            if verbose:
                print('keys')
            # check if changing allowedkeywords or not
            if run_sql("""SELECT id FROM "accACTION"
                       WHERE id = %s AND allowedkeywords != %s """,
                       (id_action, update['allowedkeywords'])):
                # change allowedkeywords
                if verbose:
                    print(' changing')
                run_sql("""UPDATE "accACTION" SET allowedkeywords = %s
                    WHERE id = %s""", (update['allowedkeywords'], id_action))
                # delete entries, but keep optional authorizations
                # if there still is keywords
                if verbose:
                    print(' deleting auths')
                run_sql("""DELETE FROM "accROLE_accACTION_accARGUMENT"
                        WHERE "id_accACTION"  = %s %s """,
                        (id_action, update['allowedkeywords'] and
                         'AND "id_accARGUMENT" != -1' or ''))

        if 'optional' in update:
            # check if there changing optional or not
            if verbose:
                print('optional')
            if run_sql("""SELECT id FROM "accACTION"
                       WHERE id = %s AND optional != %s """,
                       (id_action, update['optional'])):
                # change optional
                if verbose:
                    print(' changing')
                run_sql(
                    """UPDATE "accACTION" SET optional = %s WHERE id = %s""",
                    (update['optional'], id_action))
                # setting it to no, delete authorizations with
                # optional arguments<commit_msg>access: fix update of action allowedkeywords<commit_after># -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012,
#               2015 CERN.
#
# Invenio is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# Invenio is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Invenio; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

"""Invenio Access Control Admin."""

from __future__ import print_function

import urlparse

from flask import current_app

from intbitset import intbitset

from invenio.config import CFG_SITE_ADMIN_EMAIL, CFG_SITE_LANG, CFG_SITE_RECORD
from invenio.ext import principal
from invenio.ext.sqlalchemy import db
from invenio.legacy.dbquery import run_sql
from invenio.modules.access.firerole import (
    acc_firerole_check_user, compile_role_definition, deserialize,
    load_role_definition, serialize
)
from invenio.modules.access.local_config import (
    CFG_ACC_ACTIVITIES_URLS, CFG_ACC_EMPTY_ROLE_DEFINITION_SER,
    CFG_ACC_EMPTY_ROLE_DEFINITION_SRC, DEF_AUTHS, DEF_ROLES, DEF_USERS,
    DELEGATEADDUSERROLE, SUPERADMINROLE
)
from invenio.modules.access.models import AccACTION, AccAuthorization, \
    UserAccROLE

from six import iteritems

from sqlalchemy.exc import ProgrammingError


def acc_add_action(name_action='', description='', optional='no',
                   *allowedkeywords):
    """Create new entry in accACTION for an action.

    :param name_action: name of the new action, must be unique
    :param allowedkeywords: a list of allowedkeywords

    :return: id_action, name_action, description and allowedkeywords or
             0 in case of failure
    """
    keystr = ''
    # action with this name already exists, return 0
    if db.session.query(
            AccACTION.query.filter(
                AccACTION.name == name_action).exists()).scalar():
        return 0

    # create keyword string
    for value in allowedkeywords:
        if keystr:
            keystr += ','
        keystr += value

    if not allowedkeywords:
        optional = 'no'

    # insert the new entry
    try:
        a = AccACTION(name=name_action, description=description,
                      allowedkeywords=keystr, optional=optional)
        db.session.add(a)
        db.session.commit()
        return True, name_action, description, keystr, optional
    except ProgrammingError:
        return 0


def acc_delete_action(id_action=0, name_action=0):
    """Delete action in accACTION according to id, or secondly name.

    entries in accROLE_accACTION_accARGUMENT will also be removed.
    If the name or id is wrong, the function does nothing.

    :param id_action: id of action to be deleted, prefered variable
    :param name_action: this is used if id_action is not given
    """
    id_action = id_action or acc_get_action_id(name_action=name_action)
    if not id_action:
        return 0

    # delete the action
    if run_sql("""DELETE FROM "accACTION" WHERE id=%s""", (id_action, )):
        # delete all entries related
        return 1 + run_sql("""DELETE FROM "accROLE_accACTION_accARGUMENT" WHERE
            "id_accACTION" =%s""", (id_action, ))
    else:
        return 0


def acc_verify_action(name_action='', description='', allowedkeywords='',
                      dummy=''):
    """Check action.

    check if all the values of a given action are the same as
    those in accACTION in the database. self explanatory parameters.

    return id if identical, 0 if not.
    """
    id_action = acc_get_action_id(name_action=name_action)

    if not id_action:
        return 0

    res_desc = acc_get_action_description(id_action=id_action)
    res_keys = acc_get_action_keywords_string(id_action=id_action)

    bool_desc = res_desc == description and 1 or 0
    bool_keys = res_keys == allowedkeywords and 1 or 0
    bool_opti = acc_get_action_is_optional(id_action=id_action)

    return bool_desc and bool_keys and bool_opti and id_action or 0


def acc_update_action(id_action=0, name_action='', verbose=0, **update):
    """Try to change the values of given action details.

    if there is no change nothing is done.
    some changes require to update other parts of the database.

    :param id_action: id of the action to change
    :param name_action: if no id_action is given try to find it using this name
    :param **update: dictionary containg keywords: description, allowed
        keywords and/or optional other keywords are ignored
    """
    id_action = id_action or acc_get_action_id(name_action=name_action)

    if not id_action:
        return 0

    try:
        if 'description' in update:
            # change the description, no other effects
            if verbose:
                print('desc')
                run_sql(
                    """UPDATE "accACTION" SET description = %s """
                    """WHERE id = %s""",
                    (update['description'], id_action))

        if 'allowedkeywords' in update:
            # change allowedkeywords
            if verbose:
                print('keys')
            # check if changing allowedkeywords or not
            if run_sql("""SELECT id FROM "accACTION"
                       WHERE id = %s AND allowedkeywords != %s """,
                       (id_action, update['allowedkeywords'])):
                # change allowedkeywords
                if verbose:
                    print(' changing')
                run_sql("""UPDATE "accACTION" SET allowedkeywords = %s
                    WHERE id = %s""", (update['allowedkeywords'], id_action))
                # delete entries, but keep optional authorizations
                # if there still is keywords
                if verbose:
                    print(' deleting auths')
                run_sql("""DELETE FROM "accROLE_accACTION_accARGUMENT"
                        WHERE "id_accACTION"  = %s %s """,
                        (id_action, update['allowedkeywords'] and
                         ('AND ("id_accARGUMENT" != -1 '
                         '      OR "id_accARGUMENT" IS NULL)') or ''))

        if 'optional' in update:
            # check if there changing optional or not
            if verbose:
                print('optional')
            if run_sql("""SELECT id FROM "accACTION"
                       WHERE id = %s AND optional != %s """,
                       (id_action, update['optional'])):
                # change optional
                if verbose:
                    print(' changing')
                run_sql(
                    """UPDATE "accACTION" SET optional = %s WHERE id = %s""",
                    (update['optional'], id_action))
                # setting it to no, delete authorizations with
                # optional arguments
{'fraction_non_alphanumeric': 0.07873415968423239, 'fraction_numerical': 0.011079565127068763, 'mean_word_length': 2.4369347929557352, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4345413', 'n_tokens_mistral': 4196, 'n_tokens_neox': 3847, 'n_words': 1380}