<commit_before>## This file is part of Invenio.
## Copyright (C) 2007, 2008, 2009, 2010, 2011 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 MailCookie."""

__revision__ = "$Id$"

__lastupdated__ = """$Date$"""

"""These functions are temporaly managing roles and other authorization via
unique urls sent by email.

FIXME: This module should be refactored into a class, as there is no point
it has to host client specific code, when each client can instead
derive from the base class and add specific bits.
"""

import sys
if sys.hexversion < 0x2060000:
    from md5 import md5
else:
    from hashlib import md5

from invenio.dbquery import run_sql
from invenio.access_control_admin import acc_get_role_id, acc_add_user_role
from datetime import datetime, timedelta
from random import random
from cPickle import dumps, loads


class InvenioWebAccessMailCookieError(Exception):
    pass

class InvenioWebAccessMailCookieDeletedError(InvenioWebAccessMailCookieError):
    pass


_authorizations_kind = ('pw_reset', 'mail_activation', 'role', 'authorize_action',
                        'comment_msg', 'generic')
_datetime_format = "%Y-%m-%d %H:%M:%S"

def mail_cookie_create_common(kind, params, cookie_timeout=timedelta(days=1), onetime=False):
    """Create a unique url to be sent via email to access this authorization
    @param kind: kind of authorization (e.g. 'pw_reset', 'mail_activation', 'role')
    @param params: whatever parameters are needed
    @param cookie_timeout: for how long the url will be valid
    @param onetime: whetever to remove the cookie after it has used.
    """
    assert(kind in _authorizations_kind)
    expiration = datetime.today()+cookie_timeout
    data = (kind, params, expiration, onetime)
    password = <PASSWORD>(<PASSWORD>(<PASSWORD>()
    cookie_id = run_sql('INSERT INTO accMAILCOOKIE (data,expiration,kind,onetime) VALUES '
        '(AES_ENCRYPT(%s, %s),%s,%s,%s)',
        (dumps(data), password, expiration.strftime(_datetime_format), kind, onetime))
    cookie = password[:16]+hex(cookie_id)[2:-1]+password[-16:]
    return cookie

def mail_cookie_create_role(role_name, role_timeout=timedelta(hours=3), cookie_timeout=timedelta(days=1), onetime=True):
    """Create a unique url to be sent via email to belong temporaly to a role."""
    assert(acc_get_role_id(role_name) != 0)
    kind = 'role'
    params = (role_name, role_timeout)
    return mail_cookie_create_common(kind, params, cookie_timeout, onetime)

def mail_cookie_create_pw_reset(email, cookie_timeout=timedelta(days=1)):
    """Create a unique url to be sent via email to reset the local password."""
    kind = 'pw_reset'
    if (run_sql('SELECT email FROM user WHERE email=%s', (email, ))):
        params = email
        return mail_cookie_create_common(kind, params, cookie_timeout, False)
    else:
        raise InvenioWebAccessMailCookieError, "Email '%s' doesn't exist" % email

def mail_cookie_create_mail_activation(email, cookie_timeout=timedelta(days=1)):
    """Create a unique url to be sent via email to activate an email address"""
    kind = 'mail_activation'
    params = email
    return mail_cookie_create_common(kind, params, cookie_timeout, True)

def mail_cookie_create_authorize_action(action_name, arguments,  cookie_timeout=timedelta(days=1)):
    """Create a cookie for a valid authorization contanin all the
    information to authorize an action. Well it's a meta-cookie :-)."""

    kind = 'authorize_action'
    params = (action_name, arguments)
    return mail_cookie_create_common(kind, params, cookie_timeout, False)

def mail_cookie_retrieve_kind(cookie):
    """Retrieve if it exists the kind of a cookie."""
    try:
        password = cookie[:16]+cookie[-16:]
        cookie_id = int(cookie[16:-16], 16)
        res = run_sql("SELECT kind FROM accMAILCOOKIE WHERE id=%s", (cookie_id, ))
        if res:
            kind = res[0][0]
            assert(kind in _authorizations_kind)
            return kind
    except StandardError:
        raise InvenioWebAccessMailCookieError, "Cookie doesn't exist"

def mail_cookie_check_common(cookie, delete=False):
    """Retrieve data pointed by a cookie, returning a tuple (kind, params) or None
    if the cookie is not valid or is expired"""
    try:
        password = cookie[:16]+cookie[-16:]
        cookie_id = int(cookie[16:-16], 16)
    except Exception, e:
        raise InvenioWebAccessMailCookieError, "Cookie not valid: %s" % e
    try:
        res = run_sql("SELECT kind, AES_DECRYPT(data,%s), onetime, status FROM accMAILCOOKIE WHERE "
            "id=%s AND expiration>=NOW()", (password, cookie_id))
        if not res:
            raise StandardError<commit_msg>WebAccess: use DB slave for selected queries<commit_after>## This file is part of Invenio.
## Copyright (C) 2007, 2008, 2009, 2010, 2011 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 MailCookie."""

__revision__ = "$Id$"

__lastupdated__ = """$Date$"""

"""These functions are temporaly managing roles and other authorization via
unique urls sent by email.

FIXME: This module should be refactored into a class, as there is no point
it has to host client specific code, when each client can instead
derive from the base class and add specific bits.
"""

import sys
if sys.hexversion < 0x2060000:
    from md5 import md5
else:
    from hashlib import md5

from invenio.dbquery import run_sql
from invenio.access_control_admin import acc_get_role_id, acc_add_user_role
from datetime import datetime, timedelta
from random import random
from cPickle import dumps, loads


class InvenioWebAccessMailCookieError(Exception):
    pass

class InvenioWebAccessMailCookieDeletedError(InvenioWebAccessMailCookieError):
    pass


_authorizations_kind = ('pw_reset', 'mail_activation', 'role', 'authorize_action',
                        'comment_msg', 'generic')
_datetime_format = "%Y-%m-%d %H:%M:%S"

def mail_cookie_create_common(kind, params, cookie_timeout=timedelta(days=1), onetime=False):
    """Create a unique url to be sent via email to access this authorization
    @param kind: kind of authorization (e.g. 'pw_reset', 'mail_activation', 'role')
    @param params: whatever parameters are needed
    @param cookie_timeout: for how long the url will be valid
    @param onetime: whetever to remove the cookie after it has used.
    """
    assert(kind in _authorizations_kind)
    expiration = datetime.today()+cookie_timeout
    data = (kind, params, expiration, onetime)
    password = <PASSWORD>(str(random())).<PASSWORD>()
    cookie_id = run_sql('INSERT INTO accMAILCOOKIE (data,expiration,kind,onetime) VALUES '
        '(AES_ENCRYPT(%s, %s),%s,%s,%s)',
        (dumps(data), password, expiration.strftime(_datetime_format), kind, onetime))
    cookie = password[:16]+hex(cookie_id)[2:-1]+password[-16:]
    return cookie

def mail_cookie_create_role(role_name, role_timeout=timedelta(hours=3), cookie_timeout=timedelta(days=1), onetime=True):
    """Create a unique url to be sent via email to belong temporaly to a role."""
    assert(acc_get_role_id(role_name) != 0)
    kind = 'role'
    params = (role_name, role_timeout)
    return mail_cookie_create_common(kind, params, cookie_timeout, onetime)

def mail_cookie_create_pw_reset(email, cookie_timeout=timedelta(days=1)):
    """Create a unique url to be sent via email to reset the local password."""
    kind = 'pw_reset'
    if (run_sql('SELECT email FROM user WHERE email=%s', (email, ))):
        params = email
        return mail_cookie_create_common(kind, params, cookie_timeout, False)
    else:
        raise InvenioWebAccessMailCookieError, "Email '%s' doesn't exist" % email

def mail_cookie_create_mail_activation(email, cookie_timeout=timedelta(days=1)):
    """Create a unique url to be sent via email to activate an email address"""
    kind = 'mail_activation'
    params = email
    return mail_cookie_create_common(kind, params, cookie_timeout, True)

def mail_cookie_create_authorize_action(action_name, arguments,  cookie_timeout=timedelta(days=1)):
    """Create a cookie for a valid authorization contanin all the
    information to authorize an action. Well it's a meta-cookie :-)."""

    kind = 'authorize_action'
    params = (action_name, arguments)
    return mail_cookie_create_common(kind, params, cookie_timeout, False)

def mail_cookie_retrieve_kind(cookie):
    """Retrieve if it exists the kind of a cookie."""
    try:
        password = cookie[:16]+cookie[-16:]
        cookie_id = int(cookie[16:-16], 16)
        res = run_sql("SELECT kind FROM accMAILCOOKIE WHERE id=%s", (cookie_id, ), run_on_slave=True)
        if res:
            kind = res[0][0]
            assert(kind in _authorizations_kind)
            return kind
    except StandardError:
        raise InvenioWebAccessMailCookieError, "Cookie doesn't exist"

def mail_cookie_check_common(cookie, delete=False):
    """Retrieve data pointed by a cookie, returning a tuple (kind, params) or None
    if the cookie is not valid or is expired"""
    try:
        password = cookie[:16]+cookie[-16:]
        cookie_id = int(cookie[16:-16], 16)
    except Exception, e:
        raise InvenioWebAccessMailCookieError, "Cookie not valid: %s" % e
    try:
        res = run_sql("SELECT kind, AES_DECRYPT(data,%s), onetime, status FROM accMAILCOOKIE WHERE "
            "id=%s AND expiration>=NOW()", (password, cookie_id), run_on_slave=True)
        if not res:
            raise StandardError
{'fraction_non_alphanumeric': 0.09743447253866815, 'fraction_numerical': 0.015004167824395665, 'mean_word_length': 4.1863592699327565, 'pattern_counts': {'":': 0, '<': 10, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '646593', 'n_tokens_mistral': 3306, 'n_tokens_neox': 3123, 'n_words': 1115}