Example #1
0
def is_user_viewer_of_record(user_info, recid):
    """Check if the user is allow to view the record based in the marc tags.

    Checks inside CFG_ACC_GRANT_VIEWER_RIGHTS_TO_EMAILS_IN_TAGS
    i.e. his email is inside the 506__m tag or he is inside an e-group listed
    in the 506__m tag

    :param user_info: the user_info dictionary that describe the user.
    :type user_info: user_info dictionary
    :param recid: the record identifier.
    :type recid: positive integer
    @return: True if the user is 'allow to view' the record; False otherwise
    @rtype: bool
    """
    from invenio_access.local_config import \
        CFG_ACC_GRANT_VIEWER_RIGHTS_TO_EMAILS_IN_TAGS, \
        CFG_ACC_GRANT_VIEWER_RIGHTS_TO_USERIDS_IN_TAGS

    if not isinstance(recid, MutableMapping):
        record = get_record(int(recid))
    else:
        record = recid

    uid_tags = cfg.get('CFG_ACC_GRANT_VIEWER_RIGHTS_TO_USERIDS_IN_TAGS',
                       CFG_ACC_GRANT_VIEWER_RIGHTS_TO_USERIDS_IN_TAGS)

    email_tags = cfg.get('CFG_ACC_GRANT_VIEWER_RIGHTS_TO_EMAILS_IN_TAGS',
                         CFG_ACC_GRANT_VIEWER_RIGHTS_TO_EMAILS_IN_TAGS)

    return is_user_in_tags(record, user_info, uid_tags, email_tags)
Example #2
0
def submit_rt_ticket(obj, queue, subject, body, requestors, ticket_id_key):
    """Submit ticket to RT with the given parameters."""
    from inspirehep.utils.tickets import get_instance

    # Trick to prepare ticket body
    body = "\n ".join([line.strip() for line in body.split("\n")])
    rt_instance = get_instance() if cfg.get("PRODUCTION_MODE") else None
    rt_queue = cfg.get("CFG_BIBCATALOG_QUEUES") or queue
    recid = obj.extra_data.get("recid", "")
    if not recid:
        recid = obj.data.get("recid", "")
    if not rt_instance:
        obj.log.error("No RT instance available. Skipping!")
        obj.log.info("Ticket submission ignored.")
    else:
        ticket_id = rt_instance.create_ticket(
            Queue=rt_queue,
            Subject=subject,
            Text=body,
            Requestors=requestors,
            CF_RecordID=recid
        )
        obj.extra_data[ticket_id_key] = ticket_id
        obj.log.info("Ticket {0} created:\n{1}".format(
            ticket_id,
            body.encode("utf-8", "ignore")
        ))
    return True
Example #3
0
def send_account_activation_email(user):
    """Send an account activation email."""
    expires_in = cfg.get('CFG_WEBSESSION_ADDRESS_ACTIVATION_EXPIRE_IN_DAYS')

    address_activation_key = EmailConfirmationSerializer(
        expires_in=timedelta(days=expires_in).total_seconds()
    ).create_token(user.id, {'email': user.email})

    # Render context.
    ctx = {
        "ip_address": None,
        "user": user,
        "email": user.email,
        "activation_link": url_for(
            'webaccount.access',
            mailcookie=address_activation_key,
            _external=True,
            _scheme='https',
        ),
        "days": expires_in,
    }

    # Send email
    send_email(
        cfg.get('CFG_SITE_SUPPORT_EMAIL'),
        user.email,
        _("Account registration at %(sitename)s",
          sitename=cfg["CFG_SITE_NAME_INTL"].get(
              getattr(g, 'ln', cfg['CFG_SITE_LANG']),
              cfg['CFG_SITE_NAME'])),
        render_template("accounts/emails/activation.tpl", **ctx)
    )
Example #4
0
def index(p, so, page):
    """Index page with uploader and list of existing depositions."""
    ctx = mycommunities_ctx()

    if not so:
        so = cfg.get('COMMUNITIES_DEFAULT_SORTING_OPTION')

    communities = Community.filter_communities(p, so)
    featured_community = FeaturedCommunity.get_current()
    form = SearchForm(p=p)
    per_page = cfg.get('COMMUNITIES_DISPLAYED_PER_PAGE', 10)
    page = max(page, 1)
    p = Pagination(page, per_page, communities.count())

    ctx.update({
        'r_from': max(p.per_page * (p.page - 1), 0),
        'r_to': min(p.per_page * p.page, p.total_count),
        'r_total': p.total_count,
        'pagination': p,
        'form': form,
        'title': _('Community Collections'),
        'communities': communities.slice(
            per_page * (page - 1), per_page * page).all(),
        'featured_community': featured_community,
        'format_record': format_record,
    })

    return render_template(
        "communities/index.html",
        **ctx
    )
Example #5
0
def get_canonical_and_alternates_urls(url, drop_ln=True, washed_argd=None, quote_path=False):
    """
    Given an Invenio URL returns a tuple with two elements. The first is the
    canonical URL, that is the original URL with CFG_SITE_URL prefix, and
    where the ln= argument stripped. The second element element is mapping,
    language code -> alternate URL

    @param quote_path: if True, the path section of the given C{url}
                       is quoted according to RFC 2396
    """
    dummy_scheme, dummy_netloc, path, dummy_params, query, fragment = urlparse(url)
    canonical_scheme, canonical_netloc = urlparse(cfg.get("CFG_SITE_URL"))[0:2]
    parsed_query = washed_argd or parse_qsl(query)
    no_ln_parsed_query = [(key, value) for (key, value) in parsed_query if key != "ln"]
    if drop_ln:
        canonical_parsed_query = no_ln_parsed_query
    else:
        canonical_parsed_query = parsed_query
    if quote_path:
        path = urllib.quote(path)
    canonical_query = urlencode(canonical_parsed_query)
    canonical_url = urlunparse((canonical_scheme, canonical_netloc, path, dummy_params, canonical_query, fragment))
    alternate_urls = {}
    for ln in cfg.get("CFG_SITE_LANGS"):
        alternate_query = urlencode(no_ln_parsed_query + [("ln", ln)])
        alternate_url = urlunparse((canonical_scheme, canonical_netloc, path, dummy_params, alternate_query, fragment))
        alternate_urls[ln] = alternate_url
    return canonical_url, alternate_urls
Example #6
0
def send_account_activation_email(user):
    """Send an account activation email."""
    expires_in = cfg.get('CFG_WEBSESSION_ADDRESS_ACTIVATION_EXPIRE_IN_DAYS')

    address_activation_key = EmailConfirmationSerializer(expires_in=timedelta(
        days=expires_in).total_seconds()).create_token(user.id,
                                                       {'email': user.email})

    # Render context.
    ctx = {
        "ip_address":
        None,
        "user":
        user,
        "email":
        user.email,
        "activation_link":
        url_for(
            'webaccount.access',
            mailcookie=address_activation_key,
            _external=True,
            _scheme='https',
        ),
        "days":
        expires_in,
    }

    # Send email
    send_email(
        cfg.get('CFG_SITE_SUPPORT_EMAIL'), user.email,
        _("Account registration at %(sitename)s",
          sitename=cfg["CFG_SITE_NAME_INTL"].get(
              getattr(g, 'ln', cfg['CFG_SITE_LANG']), cfg['CFG_SITE_NAME'])),
        render_template("accounts/emails/activation.tpl", **ctx))
Example #7
0
def is_user_owner_of_record(user_info, recid):
    """Check if the user is owner of the record.

    I.e. he is the submitter and/or belongs to a owner-like group authorized
    to 'see' the record.

    :param user_info: the user_info dictionary that describe the user.
    :type user_info: user_info dictionary
    :param recid: the record identifier.
    :type recid: positive integer
    :return: True if the user is 'owner' of the record; False otherwise
    """
    from invenio_access.local_config import \
        CFG_ACC_GRANT_AUTHOR_RIGHTS_TO_EMAILS_IN_TAGS, \
        CFG_ACC_GRANT_AUTHOR_RIGHTS_TO_USERIDS_IN_TAGS

    if not isinstance(recid, MutableMapping):
        record = get_record(int(recid))
    else:
        record = recid

    uid_tags = cfg.get('CFG_ACC_GRANT_AUTHOR_RIGHTS_TO_USERIDS_IN_TAGS',
                       CFG_ACC_GRANT_AUTHOR_RIGHTS_TO_EMAILS_IN_TAGS)

    email_tags = cfg.get('CFG_ACC_GRANT_AUTHOR_RIGHTS_TO_USERIDS_IN_TAGS',
                         CFG_ACC_GRANT_AUTHOR_RIGHTS_TO_USERIDS_IN_TAGS)

    return is_user_in_tags(record, user_info, uid_tags, email_tags)
Example #8
0
 def __init__(self):
     """Initialize provider."""
     self.api = DataCiteMDSClient(username=cfg.get('CFG_DATACITE_USERNAME'),
                                  password=cfg.get('CFG_DATACITE_PASSWORD'),
                                  prefix=cfg.get('CFG_DATACITE_DOI_PREFIX'),
                                  test_mode=cfg.get('CFG_DATACITE_TESTMODE',
                                                    False),
                                  url=cfg.get('CFG_DATACITE_URL'))
Example #9
0
def get_storage_path(suffix=""):
    """Return a path ready to store files."""
    from invenio_base.globals import cfg

    storage_path = os.path.join(cfg.get("CFG_PREFIX"), cfg.get("HARVESTER_STORAGE_PREFIX"), suffix)
    if not os.path.exists(storage_path):
        os.makedirs(storage_path)
    return storage_path
Example #10
0
def make_user_agent_string(component=None):
    """
    Return a nice and uniform user-agent string to be used when Invenio
    act as a client in HTTP requests.
    """
    ret = 'Invenio-%s (+%s; "%s")' % (cfg.get("CFG_VERSION"), cfg.get("CFG_SITE_URL"), cfg.get("CFG_SITE_NAME"))
    if component:
        ret += " %s" % component
    return ret
Example #11
0
 def __init__(self):
     """Initialize provider."""
     self.api = DataCiteMDSClient(
         username=cfg.get('CFG_DATACITE_USERNAME'),
         password=cfg.get('CFG_DATACITE_PASSWORD'),
         prefix=cfg.get('CFG_DATACITE_DOI_PREFIX'),
         test_mode=cfg.get('CFG_DATACITE_TESTMODE', False),
         url=cfg.get('CFG_DATACITE_URL')
     )
Example #12
0
def get_tarball_for_model(eng, arxiv_id):
    """We download it."""
    storage_path = os.path.join(
        cfg.get('OAIHARVESTER_STORAGEDIR', cfg.get('CFG_TMPSHAREDDIR')),
        str(eng.uuid)
    )
    if not os.path.exists(storage_path):
        os.makedirs(storage_path)
    return get_tarball(
        arxiv_id,
        storage_path
    )
Example #13
0
def get_instance():
    """Make a RT instance and return it."""
    url = cfg.get("CFG_BIBCATALOG_SYSTEM_RT_URL", "")
    login = cfg.get("CFG_BIBCATALOG_SYSTEM_RT_DEFAULT_USER", "")
    password = cfg.get("CFG_BIBCATALOG_SYSTEM_RT_DEFAULT_PWD", "")

    if url:
        tracker = rt.Rt(
            url=url,
            default_login=login,
            default_password=password,
        )
        tracker.login()
        return tracker
Example #14
0
    def _previously_rejected(obj, eng):
        if cfg.get("PRODUCTION_MODE"):
            model = eng.workflow_definition.model(obj)
            record = get_record_from_model(model)

            if days_ago is None:
                _days_ago = cfg.get("INSPIRE_ACCEPTANCE_TIMEOUT", 5)
            else:
                _days_ago = days_ago

            if is_too_old(record, days_ago=_days_ago):
                obj.log.info("Record is likely rejected previously.")
                return True
        return False
Example #15
0
def get_connection_for_dump_on_slave():
    """Return a slave connection for performing dbdump operation on a slave."""
    su_user = cfg.get("CFG_DATABASE_SLAVE_SU_USER", "")
    if "CFG_DATABASE_SLAVE_SU_PASS" not in cfg:
        cfg["CFG_DATABASE_SLAVE_SU_PASS"] = \
            _get_password_from_database_password_file(su_user)

    connection = connect(host=cfg.get("CFG_DATABASE_SLAVE", ""),
                         port=int(cfg.get("CFG_DATABASE_PORT"), 3306),
                         db=cfg.get("CFG_DATABASE_NAME", ""),
                         user=su_user,
                         passwd=cfg.get("CFG_DATABASE_SLAVE_SU_PASS", ""),
                         use_unicode=False, charset='utf8')
    connection.autocommit(True)
    return connection
Example #16
0
 def generator(self):
     """Load function from configuration ``CFG_BIBDOCFILE_FILEDIR``."""
     func = cfg.get(
         'RECORD_DOCUMENT_NAME_GENERATOR', default_name_generator)
     if isinstance(func, six.string_types):
         func = import_string(func)
     return func
Example #17
0
def default_name_generator(document):
    """Return default name of record document with storage path.

    The path is generated from the uuid using two folder level, being the first
    two characters the name of the first folder and the second two the name of
    the second folder.

    It avoids creating the directories twice but if any of them is not a
    directory it will raise an OSError exception.

    :param document: The document to be stored.
    :returns: Path based on the `_id` of the document.

    """
    uuid = document['_id']
    directory = os.path.join(cfg.get('CFG_BIBDOCFILE_FILEDIR'),
                             uuid[0:2], uuid[2:4])
    try:
        os.makedirs(directory)
    except OSError as e:
        if e.errno == errno.EEXIST and os.path.isdir(directory):
            pass
        else:
            raise
    return os.path.join(directory, uuid[4:])
Example #18
0
def arxiv_fft_get(obj, eng):
    """Get FFT from arXiv, if arXiv ID is provided."""
    deposition = Deposition(obj)
    sip = deposition.get_latest_sip(sealed=False)
    metadata = sip.metadata

    if 'arxiv_id' in metadata and metadata['arxiv_id']:
        arxiv_pdf_url = cfg.get("ARXIV_PDF_URL", "http://arxiv.org/pdf/") + \
            "{0}.{1}"

        from invenio.config import CFG_TMPSHAREDDIR
        arxiv_file, arxiv_file_path = mkstemp(
            prefix="%s_" % (metadata['arxiv_id'].replace("/", "_")),
            suffix='.pdf',
            dir=CFG_TMPSHAREDDIR,
        )
        os.close(arxiv_file)

        download_url(url=arxiv_pdf_url.format(metadata['arxiv_id'], "pdf"),
                     content_type="pdf",
                     download_to_file=arxiv_file_path)

        # To get 1111.2222.pdf as filename.
        filename = "{0}.pdf".format(metadata['arxiv_id'].replace("/", "_"))

        try:
            try:
                save_deposition_file(deposition,
                                     filename,
                                     arxiv_file_path)
            except FilenameAlreadyExists:
                obj.log.error("PDF file not saved: filename already exists.")
        except Exception as e:
            obj.log.error("PDF file not saved: {}.".format(e.message))
Example #19
0
def default_name_generator(document):
    """Return default name of record document with storage path.

    The path is generated from the uuid using two folder level, being the first
    two characters the name of the first folder and the second two the name of
    the second folder.

    It avoids creating the directories twice but if any of them is not a
    directory it will raise an OSError exception.

    :param document: The document to be stored.
    :returns: Path based on the `_id` of the document.

    """
    uuid = document['_id']
    directory = os.path.join(cfg.get('CFG_BIBDOCFILE_FILEDIR'), uuid[0:2],
                             uuid[2:4])
    try:
        os.makedirs(directory)
    except OSError as e:
        if e.errno == errno.EEXIST and os.path.isdir(directory):
            pass
        else:
            raise
    return os.path.join(directory, uuid[4:])
Example #20
0
 def generator(self):
     """Load function from configuration ``CFG_BIBDOCFILE_FILEDIR``."""
     func = cfg.get('RECORD_DOCUMENT_NAME_GENERATOR',
                    default_name_generator)
     if isinstance(func, six.string_types):
         func = import_string(func)
     return func
Example #21
0
def send_reset_password_email(email):
    """Reset password by sending a email with the unique link."""
    expires_in = cfg.get('CFG_WEBSESSION_ADDRESS_ACTIVATION_EXPIRE_IN_DAYS')

    reset_key = EmailConfirmationSerializer(
        expires_in=timedelta(days=expires_in).total_seconds()
    ).create_token(email, {'email': email})

    if not reset_key:
        raise AccountSecurityError(
            _('Something goes wrong when the cookie has been generated')
        )

    email_text = render_template(
        'accounts/email_reset_password.html',
        reset_key=reset_key, email=email
    )

    return send_email(
        fromaddr=cfg['CFG_SITE_SUPPORT_EMAIL'],
        subject=_("Password reset request for %(website)s",
                  website=cfg['CFG_SITE_URL']),
        toaddr=email,
        content=email_text
    )
Example #22
0
def train(records, output, skip_categories=False, skip_astro=False):
    """Train a set of records from the command line.

    Usage: inveniomanage predicter train -r /path/to/json -o model.pickle
    """
    if not records:
        print("Missing records!", file=sys.stderr)
        return

    if not os.path.isfile(records):
        print("{0} is not a file!".format(records), file=sys.stderr)
        return

    if os.path.basename(output) == output:
        # Only a relative name, prefix with config
        output = os.path.join(
            cfg.get("CLASSIFIER_MODEL_PATH", ""), output
        )
    else:
        output = os.path.abspath(output)

    # Make sure directories are created
    if not os.path.exists(os.path.dirname(output)):
        os.makedirs(output)

    # Check that location is writable
    if not os.access(os.path.dirname(output), os.W_OK):
        print("{0} is not writable file!".format(output), file=sys.stderr)
        return

    job = celery_train.delay(records, output, skip_categories, skip_astro)
    print("Scheduled job {0}".format(job.id))
Example #23
0
def setup_app():
    """Setup OAuth2 provider."""
    # Initialize OAuth2 provider
    oauth2.init_app(current_app)

    # Configures the OAuth2 provider to use the SQLALchemy models for getters
    # and setters for user, client and tokens.
    bind_sqlalchemy(oauth2, db.session, client=Client)

    # Flask-OAuthlib does not support CACHE_REDIS_URL
    if cfg['OAUTH2_CACHE_TYPE'] == 'redis' and \
       cfg.get('CACHE_REDIS_URL'):
        from redis import from_url as redis_from_url
        cfg.setdefault(
            'OAUTH2_CACHE_REDIS_HOST',
            redis_from_url(cfg['CACHE_REDIS_URL'])
        )

    # Configures an OAuth2Provider instance to use configured caching system
    # to get and set the grant token.
    bind_cache_grant(current_app, oauth2, OAuthUserProxy.get_current_user)

    # Disables oauthlib's secure transport detection in in debug mode.
    if current_app.debug or current_app.testing:
        os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
Example #24
0
def login(nickname=None, password=None, login_method=None,
          remember=False, referer=None):
    """Login."""
    if cfg.get('CFG_ACCESS_CONTROL_LEVEL_SITE') > 0:
        return abort(401)  # page is not authorized

    if 'action' in request.values:
        warnings.warn('Action argument "{}" is not used anymore.'.format(
            request.values['action']), DeprecationWarning)
    form = LoginForm(CombinedMultiDict(
        [ImmutableMultiDict({'referer': referer, 'login_method': 'Local'}
                            if referer else {'login_method': 'Local'}),
         request.values]), csrf_enabled=False)

    if request.method == "POST":
        try:
            if login_method == 'Local' and form.validate_on_submit() and \
               authenticate(nickname, password, login_method=login_method,
                            remember=remember):
                flash(
                    _("You are logged in as %(nick)s.", nick=nickname),
                    "success"
                )
                return login_redirect(referer)

            else:
                flash(_("Invalid credentials."), "error")
        except Exception as e:
            current_app.logger.error(
                'Exception during login process: %s', str(e)
            )
            flash(_("Problem with login."), "error")

    return render_template('accounts/login.html', form=form), 401
Example #25
0
def load(module='', prefix=''):
    """ Load and returns a template class, given a module name (like
        'websearch', 'webbasket',...).  The module corresponding to
        the currently selected template model (see invenio.conf,
        variable CFG_WEBSTYLE_TEMPLATE_SKIN) is tried first. In case it does
        not exist, it returns the default template for that module.
    """
    local = {}
    # load the right template based on the CFG_WEBSTYLE_TEMPLATE_SKIN and the specified module
    if CFG_WEBSTYLE_TEMPLATE_SKIN == "default":
        try:
            mymodule = __import__("invenio.%s_%stemplates" % (module, prefix), local,
                                  local, ["invenio.legacy.%s.templates" % (module)])
        except ImportError:
            mymodule = __import__("invenio.legacy.%s.%stemplates" % (module, prefix),
                                  local, local,
                                  ["invenio.legacy.%s.templates" % (module)])
    else:
        try:
            mymodule = __import__("invenio.legacy.%s.templates_%s" % (module, CFG_WEBSTYLE_TEMPLATE_SKIN), local, local,
                                  ["invenio.legacy.%s.templates" % (module, CFG_WEBSTYLE_TEMPLATE_SKIN)])
        except ImportError:
            mymodule = __import__("invenio.legacy.%s.templates" % (module), local, local,
                                  ["invenio.legacy.%s.templates" % (module)])
    if 'inspect-templates' in cfg.get('CFG_DEVEL_TOOLS', []):
        for method_name in dir(mymodule.Template):
            if method_name.startswith('tmpl_'):
                enhance_method(module, mymodule.Template, method_name, method_wrapper)

    return mymodule.Template()
Example #26
0
def get_connection_for_dump_on_slave():
    """Return a slave connection for performing dbdump operation on a slave."""
    su_user = cfg.get("CFG_DATABASE_SLAVE_SU_USER", "")
    if "CFG_DATABASE_SLAVE_SU_PASS" not in cfg:
        cfg["CFG_DATABASE_SLAVE_SU_PASS"] = \
            _get_password_from_database_password_file(su_user)

    connection = connect(host=cfg.get("CFG_DATABASE_SLAVE", ""),
                         port=int(cfg.get("CFG_DATABASE_PORT"), 3306),
                         db=cfg.get("CFG_DATABASE_NAME", ""),
                         user=su_user,
                         passwd=cfg.get("CFG_DATABASE_SLAVE_SU_PASS", ""),
                         use_unicode=False,
                         charset='utf8')
    connection.autocommit(True)
    return connection
    def _report_via_email(obj, eng):
        recipients = obj.extra_data["config"].get("recipients")
        if not recipients:
            obj.log.warning("No recipients")
            return

        collections = obj.data.get('collections', dict())
        files_uploaded = []
        for update_type, filename in collections.items():
            count = len(obj.data.get(update_type, list()))
            files_uploaded.append((basename(filename), count))

        harvesting_date = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        context = {
            "object": obj,
            "files_uploaded": files_uploaded,
            "args": obj.extra_data.get("args", dict()),
            "harvesting_date": harvesting_date
        }

        body = render_template(
            template,
            **context
        )
        subject = "{0} harvest results: {1}".format(
            context.get("args").get("workflow"),
            harvesting_date
        )

        send_email(fromaddr=cfg.get("CFG_SITE_SUPPORT_EMAIL"),
                   toaddr=recipients,
                   subject=subject,
                   content=body)
Example #28
0
def get_harvesting_workflows():
    """Return the workflows enabled in the harvester module."""
    enabled_workflows = []
    for name in cfg.get("HARVESTER_WORKFLOWS", list()):
        if workflows.get(name):
            enabled_workflows.append(name)
    return enabled_workflows
Example #29
0
    def setUp(self):
        """ Initialises test by adding dummy log entries """
        from invenio_records.api import create_record
        from invenio_records.models import Record

        self.__transaction = db.session.begin_nested()
        for i in range(10):
            rec = Record(id=i + 1)
            db.session.add(rec)
            create_record({'recid': i + 1})

        from inspire.modules.citations.tasks import update_citations_log
        data = u'[[1, 2, 1, "added", "2013-04-25 04:20:30"],[2, 3, 1, "added", "2013-04-25 04:20:30"],[3, 5, 1, "added", "2013-04-25 04:20:30"],[4, 4, 2, "added", "2013-04-25 04:20:30"],[5, 5, 2, "added", "2013-04-25 04:20:30"],[6, 6, 2, "added", "2013-04-25 04:20:30"],[7, 10, 4, "added", "2013-04-25 04:20:30"],[8, 5, 1, "removed", "2013-04-25 04:20:30"],[9, 5, 4, "added", "2013-04-25 04:20:30"],[10, 6, 4, "added", "2013-04-25 04:20:30"],[11, 3, 4, "added", "2013-04-25 04:20:31"],[12, 8, 5, "added", "2013-04-25 04:20:31"],[13, 10, 4, "removed", "2013-04-25 04:20:31"],[14, 7, 6, "added", "2013-04-25 04:20:31"],[15, 9, 6, "added", "2013-04-25 04:20:31"],[16, 10, 6, "added", "2013-04-25 04:20:31"],[17, 1, 7, "added", "2013-04-25 04:20:31"],[18, 8, 7, "added", "2013-04-25 04:20:31"],[19, 10, 7, "added", "2013-04-25 04:20:31"],[20, 3, 8, "added", "2013-04-25 04:20:31"],[21, 10, 9, "added", "2013-04-25 04:20:31"],[22, 3, 9, "added", "2013-04-25 04:20:31"],[23, 3, 8, "removed", "2013-04-25 04:20:31"],[24, 1, 10, "added", "2013-04-25 04:20:31"],[25, 2, 10, "added", "2013-04-25 04:20:31"],[26, 3, 10, "added", "2013-04-25 04:20:31"]]'
        # Mocks two responses. The first one contains the dummy data and the second an empty list
        # to force update_citations_log() to terminate.
        httpretty.register_uri(
            httpretty.GET,
            cfg.get("CITATIONS_FETCH_LEGACY_URL"),
            responses=[
                httpretty.Response(body=data, status=200),
                httpretty.Response(body='[]', status=200),
            ]
        )
        Citation.query.delete()
        Citation_Log.query.delete()
        update_citations_log()
Example #30
0
def record_extraction_from_string(xml_string, oai_namespace="http://www.openarchives.org/OAI/2.0/"):
    """Given a OAI-PMH XML return a list of every record incl. headers.

    :param xml_string: OAI-PMH XML
    :type xml_string: str

    :param oai_namespace: optionally provide the OAI-PMH namespace
    :type oai_namespace: str

    :return: return a list of XML records as string
    :rtype: str
    """
    if oai_namespace:
        nsmap = {None: oai_namespace}
    else:
        nsmap = cfg.get("OAIHARVESTER_DEFAULT_NAMESPACE_MAP")
    namespace_prefix = "{{{0}}}".format(oai_namespace)
    root = etree.fromstring(xml_string)
    headers = []
    headers.extend(root.findall(".//{0}responseDate".format(namespace_prefix), nsmap))
    headers.extend(root.findall(".//{0}request".format(namespace_prefix), nsmap))

    records = root.findall(".//{0}record".format(namespace_prefix), nsmap)

    list_of_records = []
    for record in records:
        wrapper = etree.Element("OAI-PMH", nsmap=nsmap)
        for header in headers:
            wrapper.append(header)
        wrapper.append(record)
        list_of_records.append(etree.tostring(wrapper))
    return list_of_records
def duplicated_doi_validator(form, field):
    """Check if a record with the same doi already exists."""
    doi = field.data
    # TODO: local check for duplicates
    if not doi:
        return
    if cfg.get('PRODUCTION_MODE'):
        inspirehep_duplicated_validator('doi:' + doi, 'DOI')
Example #32
0
    def decorated(recid, *args, **kwargs):
        from invenio_collections.models import Collection

        from .api import get_record
        from .access import check_user_can_view_record
        from .models import Record as Bibrec
        # ensure recid to be integer
        recid = int(recid)
        g.bibrec = Bibrec.query.get(recid)

        g.record = record = get_record(recid)
        if record is None:
            abort(404)

        g.collection = collection = Collection.query.filter(
            Collection.name.in_(record['_collections'])).first()

        (auth_code, auth_msg) = check_user_can_view_record(
            current_user, record)

        # only superadmins can use verbose parameter for obtaining debug
        # information
        if not current_user.is_super_admin and 'verbose' in kwargs:
            kwargs['verbose'] = 0

        if auth_code:
            flash(auth_msg, 'error')
            abort(apache.HTTP_UNAUTHORIZED)

        # TODO check record status (exists, merged, deleted)

        title = record.get(cfg.get('RECORDS_BREADCRUMB_TITLE_KEY'), '')
        tabs = []

        def _format_record(record, of='hd', user_info=current_user, *args,
                           **kwargs):
            from invenio_formatter import format_record
            return format_record(record, of, user_info=user_info, *args,
                                 **kwargs)

        @register_template_context_processor
        def record_context():
            # from invenio.modules.comments.api import get_mini_reviews
            return dict(recid=recid,
                        record=record,
                        tabs=tabs,
                        title=title,
                        get_mini_reviews=lambda *args, **kwargs: '',
                        # FIXME get_mini_reviews,
                        collection=collection,
                        format_record=_format_record
                        )

        pre_template_render.send(
            "%s.%s" % (blueprint.name, f.__name__),
            recid=recid,
        )
        return f(recid, *args, **kwargs)
Example #33
0
    def __init__(self, expires_in=None):
        """Initialize underlying TimedJSONWebSignatureSerializer."""
        dt = expires_in or cfg.get('ACCOUNTS_CONFIRMLINK_EXPIRES_IN')

        super(EmailConfirmationSerializer, self).__init__(
            cfg['SECRET_KEY'],
            expires_in=dt,
            salt='accounts-email',
        )
    def __init__(self, expires_in=None):
        """Initialize underlying TimedJSONWebSignatureSerializer."""
        dt = expires_in or cfg.get('ACCOUNTS_CONFIRMLINK_EXPIRES_IN')

        super(EmailConfirmationSerializer, self).__init__(
            cfg['SECRET_KEY'],
            expires_in=dt,
            salt='accounts-email',
        )
def duplicated_arxiv_id_validator(form, field):
    """Check if a record with the same arXiv ID already exists."""
    arxiv_id = field.data
    # TODO: local check for duplicates
    if not arxiv_id:
        return
    if cfg.get('PRODUCTION_MODE'):
        inspirehep_duplicated_validator(
            '035__a:oai:arXiv.org:' + arxiv_id, 'arXiv ID')
Example #36
0
def was_already_harvested(record):
    """Return True if the record was already harvested.

    We use the following heuristic: if the record belongs to one of the
    CORE categories then it was probably ingested in some other way.
    """
    categories = record.get('subject_terms.term', [])
    for category in categories:
        if category.lower() in cfg.get('INSPIRE_ACCEPTED_CATEGORIES', []):
            return True
Example #37
0
def already_harvested(obj, eng):
    """Check if record is already harvested."""
    if cfg.get("PRODUCTION_MODE"):
        model = eng.workflow_definition.model(obj)
        record = get_record_from_model(model)

        if was_already_harvested(record):
            obj.log.info("Record is already being harvested on INSPIRE.")
            return True
    return False
def wash_field(f):
    """Wash field passed by URL."""
    if f:
        # get rid of unnecessary whitespace and make it lowercase
        # (e.g. Author -> author) to better suit iPhone etc input
        # mode:
        f = f.strip().lower()
    # wash legacy 'f' field names, e.g. replace 'wau' or `au' by
    # 'author', if applicable:
    return cfg.get('CFG_WEBSEARCH_FIELDS_CONVERT', {}).get(f, f)
Example #39
0
def wash_field(f):
    """Wash field passed by URL."""
    if f:
        # get rid of unnecessary whitespace and make it lowercase
        # (e.g. Author -> author) to better suit iPhone etc input
        # mode:
        f = f.strip().lower()
    # wash legacy 'f' field names, e.g. replace 'wau' or `au' by
    # 'author', if applicable:
    return cfg.get('CFG_WEBSEARCH_FIELDS_CONVERT', {}).get(f, f)
Example #40
0
def setup_app(app):
    """
    Prepare application config from Invenio configuration.

    @see: https://flask-email.readthedocs.org/en/latest/#configuration
    """
    cfg = app.config

    app.config.setdefault(
        'EMAIL_BACKEND',
        cfg.get('CFG_EMAIL_BACKEND', 'flask_email.backends.smtp.Mail'))
    app.config.setdefault('DEFAULT_FROM_EMAIL', cfg['CFG_SITE_SUPPORT_EMAIL'])
    app.config.setdefault('SERVER_EMAIL', cfg['CFG_SITE_ADMIN_EMAIL'])
    app.config.setdefault('ADMINS', (('', cfg['CFG_SITE_ADMIN_EMAIL']), ))
    app.config.setdefault('MANAGERS', (cfg['CFG_SITE_SUPPORT_EMAIL'], ))

    CFG_MISCUTIL_SMTP_HOST = cfg.get('CFG_MISCUTIL_SMTP_HOST')
    CFG_MISCUTIL_SMTP_PORT = cfg.get('CFG_MISCUTIL_SMTP_PORT')
    CFG_MISCUTIL_SMTP_USER = cfg.get('CFG_MISCUTIL_SMTP_USER', '')
    CFG_MISCUTIL_SMTP_PASS = cfg.get('CFG_MISCUTIL_SMTP_PASS', '')
    CFG_MISCUTIL_SMTP_TLS = cfg.get('CFG_MISCUTIL_SMTP_TLS', False)

    app.config.setdefault('EMAIL_HOST', CFG_MISCUTIL_SMTP_HOST)
    app.config.setdefault('EMAIL_PORT', CFG_MISCUTIL_SMTP_PORT)
    app.config.setdefault('EMAIL_HOST_USER', CFG_MISCUTIL_SMTP_USER)
    app.config.setdefault('EMAIL_HOST_PASSWORD', CFG_MISCUTIL_SMTP_PASS)
    app.config.setdefault('EMAIL_USE_TLS', CFG_MISCUTIL_SMTP_TLS)
    # app.config['EMAIL_USE_SSL']: defaults to False

    app.config.setdefault('EMAIL_FILE_PATH', cfg['CFG_LOGDIR'])
    return app
Example #41
0
def _get_password_from_database_password_file(user):
    """Parse CFG_DATABASE_PASSWORD_FILE and return password for user."""
    pwfile = cfg.get("CFG_DATABASE_PASSWORD_FILE", None)
    if pwfile and os.path.exists(pwfile):
        for row in open(pwfile):
            if row.strip():
                a_user, pwd = row.strip().split(" // ")
                if user == a_user:
                    return pwd
        raise ValueError("user '%s' not found in database password file '%s'" %
                         (user, pwfile))
    raise IOError("No password defined for user '%s' but database password "
                  "file is not available" % user)
Example #42
0
def send_reset_password_email(email):
    """Reset password by sending a email with the unique link."""
    expires_in = cfg.get('CFG_WEBSESSION_ADDRESS_ACTIVATION_EXPIRE_IN_DAYS')

    reset_key = EmailConfirmationSerializer(expires_in=timedelta(
        days=expires_in).total_seconds()).create_token(email, {'email': email})

    if not reset_key:
        raise AccountSecurityError(
            _('Something goes wrong when the cookie has been generated'))

    email_text = render_template('accounts/email_reset_password.html',
                                 reset_key=reset_key,
                                 email=email)

    return send_email(fromaddr=cfg['CFG_SITE_SUPPORT_EMAIL'],
                      subject=_("Password reset request for %(website)s",
                                website=cfg['CFG_SITE_URL']),
                      toaddr=email,
                      content=email_text)
Example #43
0
def datacite_register(recid):
    """Register a DOI for new publication.

    If it fails, it will retry every 10 minutes for 1 hour.
    """
    record = get_record(recid)

    if record is None:
        logger.debug("Record %s not found" % recid)
        return

    doi_val = record.get(cfg['PIDSTORE_DATACITE_RECORD_DOI_FIELD'], None)
    logger.debug("Found DOI %s in record %s" % (doi_val, recid))

    pid = PersistentIdentifier.get("doi", doi_val)
    if not pid:
        logger.debug("DOI not locally managed.")
        return
    else:
        logger.debug("DOI locally managed.")

    if not pid.has_object("rec", recid):
        raise Exception("DOI %s is not assigned to record %s." %
                        (doi_val, recid))

    if pid.is_new() or pid.is_reserved():
        logger.info("Registering DOI %s for record %s" % (doi_val, recid))

        url = "%s/record/%s" % (cfg.get('PIDSTORE_DATACITE_SITE_URL',
                                        cfg['CFG_SITE_URL']), recid)
        doc = format_record(record, cfg['PIDSTORE_DATACITE_OUTPUTFORMAT'])

        if not pid.register(url=url, doc=doc):
            m = "Failed to register DOI %s" % doi_val
            logger.error(m + "\n%s\n%s" % (url, doc))
            if not datacite_register.request.is_eager:
                raise datacite_register.retry(exc=Exception(m))
        else:
            logger.info("Successfully registered DOI %s." % doi_val)
Example #44
0
def login(nickname=None,
          password=None,
          login_method=None,
          remember=False,
          referer=None):
    """Login."""
    if cfg.get('CFG_ACCESS_CONTROL_LEVEL_SITE') > 0:
        return abort(401)  # page is not authorized

    if 'action' in request.values:
        warnings.warn(
            'Action argument "{}" is not used anymore.'.format(
                request.values['action']), DeprecationWarning)
    form = LoginForm(CombinedMultiDict([
        ImmutableMultiDict({
            'referer': referer,
            'login_method': 'Local'
        } if referer else {'login_method': 'Local'}), request.values
    ]),
                     csrf_enabled=False)

    if request.method == "POST":
        try:
            if login_method == 'Local' and form.validate_on_submit() and \
               authenticate(nickname, password, login_method=login_method,
                            remember=remember):
                flash(_("You are logged in as %(nick)s.", nick=nickname),
                      "success")
                return login_redirect(referer)

            else:
                flash(_("Invalid credentials."), "error")
        except Exception as e:
            current_app.logger.error('Exception during login process: %s',
                                     str(e))
            flash(_("Problem with login."), "error")

    return render_template('accounts/login.html', form=form), 401
def get_current_user_records_that_can_be_displayed(qid):
    """Return records that current user can display.

    :param qid: query identifier

    :return: records in intbitset
    """
    CFG_WEBSEARCH_SEARCH_CACHE_TIMEOUT = cfg.get(
        'CFG_WEBSEARCH_SEARCH_CACHE_TIMEOUT')

    @search_results_cache.memoize(timeout=CFG_WEBSEARCH_SEARCH_CACHE_TIMEOUT)
    def get_records_for_user(qid, uid):
        key = get_search_results_cache_key_from_qid(qid)
        data = search_results_cache.get(key)
        if data is None:
            return intbitset([])
        cc = search_results_cache.get(key + '::cc')
        return get_records_that_can_be_displayed(
            current_user.get('precached_permitted_restricted_collections', []),
            intbitset().fastload(data), cc)

    # Simplifies API
    return get_records_for_user(qid, current_user.get_id())
Example #46
0
def setup_app():
    """Setup OAuth2 provider."""
    # Initialize OAuth2 provider
    oauth2.init_app(current_app)

    # Configures the OAuth2 provider to use the SQLALchemy models for getters
    # and setters for user, client and tokens.
    bind_sqlalchemy(oauth2, db.session, client=Client)

    # Flask-OAuthlib does not support CACHE_REDIS_URL
    if cfg['OAUTH2_CACHE_TYPE'] == 'redis' and \
       cfg.get('CACHE_REDIS_URL'):
        from redis import from_url as redis_from_url
        cfg.setdefault('OAUTH2_CACHE_REDIS_HOST',
                       redis_from_url(cfg['CACHE_REDIS_URL']))

    # Configures an OAuth2Provider instance to use configured caching system
    # to get and set the grant token.
    bind_cache_grant(current_app, oauth2, OAuthUserProxy.get_current_user)

    # Disables oauthlib's secure transport detection in in debug mode.
    if current_app.debug or current_app.testing:
        os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'
Example #47
0
def dbexec(version=False, interactive=False):
    """Runs SQL commands."""
    MYSQL = cfg.get('MYSQL', 'mysql')
    ## is version called?
    if version:
        print(__revision__)
        return 0

    params = [
        '--default-character-set=utf8',
        '--max_allowed_packet=1G',
        '--host=%s' % (cfg['CFG_DATABASE_HOST'], ),
        '--port=%s' % (cfg['CFG_DATABASE_PORT'], ),
        '--user=%s' % (cfg['CFG_DATABASE_USER'], ),
        '--password=%s' % (cfg['CFG_DATABASE_PASS'], ),
        cfg['CFG_DATABASE_NAME']
        ]

    ## interactive mode asked for?
    if not interactive:
        params.insert(0, '-B')

    return subprocess.call([MYSQL] + params)
Example #48
0
    def decorated(recid, *args, **kwargs):
        from invenio_collections.models import Collection

        from .api import get_record
        from .access import check_user_can_view_record
        from .models import Record as Bibrec
        # ensure recid to be integer
        recid = int(recid)
        g.bibrec = Bibrec.query.get(recid)

        g.record = record = get_record(recid)
        if record is None:
            abort(404)

        g.collection = collection = Collection.query.filter(
            Collection.name.in_(record['_collections'])).first()

        (auth_code,
         auth_msg) = check_user_can_view_record(current_user, record)

        # only superadmins can use verbose parameter for obtaining debug
        # information
        if not current_user.is_super_admin and 'verbose' in kwargs:
            kwargs['verbose'] = 0

        if auth_code:
            flash(auth_msg, 'error')
            abort(apache.HTTP_UNAUTHORIZED)

        # TODO check record status (exists, merged, deleted)

        title = record.get(cfg.get('RECORDS_BREADCRUMB_TITLE_KEY'), '')
        tabs = []

        def _format_record(record,
                           of='hd',
                           user_info=current_user,
                           *args,
                           **kwargs):
            from invenio_formatter import format_record
            return format_record(record,
                                 of,
                                 user_info=user_info,
                                 *args,
                                 **kwargs)

        @register_template_context_processor
        def record_context():
            # from invenio.modules.comments.api import get_mini_reviews
            return dict(
                recid=recid,
                record=record,
                tabs=tabs,
                title=title,
                get_mini_reviews=lambda *args, **kwargs: '',
                # FIXME get_mini_reviews,
                collection=collection,
                format_record=_format_record)

        pre_template_render.send(
            "%s.%s" % (blueprint.name, f.__name__),
            recid=recid,
        )
        return f(recid, *args, **kwargs)
Example #49
0
def default_ln(ln):
    """Default ln."""
    cfg.get('CFG_SITE_LANG') if ln is None else ln
Example #50
0
def run_sql(sql,
            param=None,
            n=0,
            with_desc=False,
            with_dict=False,
            run_on_slave=False,
            connection=None):
    """Run SQL on the server with PARAM and return result.

    @param param: tuple of string params to insert in the query (see
    notes below)
    @param n: number of tuples in result (0 for unbounded)
    @param with_desc: if True, will return a DB API 7-tuple describing
    columns in query.
    @param with_dict: if True, will return a list of dictionaries
    composed of column-value pairs
    @param connection: if provided, uses the given connection.
    @return: If SELECT, SHOW, DESCRIBE statements, return tuples of data,
    followed by description if parameter with_desc is
    provided.
    If SELECT and with_dict=True, return a list of dictionaries
    composed of column-value pairs, followed by description
    if parameter with_desc is provided.
    If INSERT, return last row id.
    Otherwise return SQL result as provided by database.

    @note: When the site is closed for maintenance (as governed by the
    config variable CFG_ACCESS_CONTROL_LEVEL_SITE), do not attempt
    to run any SQL queries but return empty list immediately.
    Useful to be able to have the website up while MySQL database
    is down for maintenance, hot copies, table repairs, etc.
    @note: In case of problems, exceptions are returned according to
    the Python DB API 2.0.  The client code can import them from
    this file and catch them.
    """
    if cfg['CFG_ACCESS_CONTROL_LEVEL_SITE'] == 3:
        # do not connect to the database as the site is closed for maintenance:
        return []
    elif cfg['CFG_ACCESS_CONTROL_LEVEL_SITE'] > 0:
        # Read only website
        if not sql.upper().startswith("SELECT") \
           and not sql.upper().startswith("SHOW"):
            return

    if param:
        param = tuple(param)

    dbhost = cfg['CFG_DATABASE_HOST']
    if run_on_slave and cfg['CFG_DATABASE_SLAVE']:
        dbhost = cfg['CFG_DATABASE_SLAVE']

    if 'sql-logger' in cfg.get('CFG_DEVEL_TOOLS', []):
        log_sql_query(dbhost, sql, param)

    try:
        db = connection or _db_login(dbhost)
        cur = db.cursor()
        cur.execute("SET SESSION sql_mode = %s", ['ANSI_QUOTES'])
        gc.disable()
        rc = cur.execute(sql, param)
        gc.enable()
    except (OperationalError, MySQLdbOperationalError, InterfaceError):
        # unexpected disconnect, bad malloc error, etc
        # FIXME: now reconnect is always forced, we may perhaps want to ping()
        # first?
        if connection is not None:
            raise
        try:
            db = _db_login(dbhost, relogin=1)
            cur = db.cursor()
            cur.execute("SET SESSION sql_mode = %s", ['ANSI_QUOTES'])
            gc.disable()
            rc = cur.execute(sql, param)
            gc.enable()
        except (OperationalError, MySQLdbOperationalError, InterfaceError):
            # unexpected disconnect, bad malloc error, etc
            raise

    if string.upper(string.split(sql)[0]) in \
       ("SELECT", "SHOW", "DESC", "DESCRIBE"):
        if n:
            recset = cur.fetchmany(n)
        else:
            recset = cur.fetchall()

        if with_dict:  # return list of dictionaries
            # let's extract column names
            keys = [row[0] for row in cur.description]
            # let's construct a list of dictionaries
            list_dict_results = [
                dict(zip(*[keys, values])) for values in recset
            ]

            if with_desc:
                return list_dict_results, cur.description
            else:
                return list_dict_results
        else:
            if with_desc:
                return recset, cur.description
            else:
                return recset
    else:
        if string.upper(string.split(sql)[0]) == "INSERT":
            rc = cur.lastrowid
        return rc
 def replacements(self):
     """TODO."""
     return cfg.get(self.config_name, [])
Example #52
0
def main():
    """Main function that analyzes command line input and calls whatever
    is appropriate. """

    from invenio_access.firerole import repair_role_definitions
    from invenio_access.control import (acc_add_default_settings,
                                                acc_reset_default_settings)
    from invenio_base.globals import cfg
    from invenio.legacy.bibsched.bibtask import authenticate

    DEF_DEMO_USER_ROLES = cfg.get('DEF_DEMO_USER_ROLES', tuple())
    DEF_DEMO_ROLES = cfg.get('DEF_DEMO_ROLES', tuple())
    DEF_DEMO_AUTHS = cfg.get('DEF_DEMO_AUTHS', tuple())

    ## parse command line:
    # set user-defined options:
    options = {'user' : '', 'reset' : 0, 'compile' : 0, 'add' : 0, 'demo' : 0}
    try:
        opts, args = getopt.getopt(sys.argv[1:], "hVu:racD",
                                    ["help", "version", "user="******"reset", "add", "compile", "demo"])
    except getopt.GetoptError as err:
        usage(1, err)
    try:
        for opt in opts:
            if opt[0] in ("-h", "--help"):
                usage(0)
            elif opt[0] in ("-V", "--version"):
                print(__revision__)
                sys.exit(0)
            elif opt[0] in ("-u", "--user"):
                options["user"] = opt[1]
            elif opt[0] in ("-r", "--reset"):
                options["reset"] = 1
            elif opt[0] in ("-a", "--add"):
                options["add"] = 1
            elif opt[0] in ("-c", "--compile"):
                options["compile"] = 1
            elif opt[0] in ("-D", "--demo"):
                options["demo"] = 1
            else:
                usage(1)
        if options['add'] or options['reset'] or options['compile']:
            #if acca.acc_get_action_id('cfgwebaccess'):
            #    # Action exists hence authentication works :-)
            #    options['user'] = authenticate(options['user'],
            #        authorization_msg="WebAccess Administration",
            #        authorization_action="cfgwebaccess")
            if options['reset'] and options['demo']:
                acc_reset_default_settings(
                    [cfg['CFG_SITE_ADMIN_EMAIL']], DEF_DEMO_USER_ROLES,
                    DEF_DEMO_ROLES, DEF_DEMO_AUTHS)
                print("Reset default demo site settings.")
            elif options['reset']:
                acc_reset_default_settings([cfg['CFG_SITE_ADMIN_EMAIL']])
                print("Reset default settings.")
            elif options['add'] and options['demo']:
                acc_add_default_settings(
                    [cfg['CFG_SITE_ADMIN_EMAIL']], DEF_DEMO_USER_ROLES,
                    DEF_DEMO_ROLES, DEF_DEMO_AUTHS)
                print("Added default demo site settings.")
            elif options['add']:
                acc_add_default_settings([cfg['CFG_SITE_ADMIN_EMAIL']])
                print("Added default settings.")
            if options['compile']:
                repair_role_definitions()
                print("Compiled firewall like role definitions.")
        else:
            usage(1, "You must specify at least one command")
    except StandardError as e:
        from invenio.ext.logging import register_exception
        register_exception()
        usage(e)
    return
Example #53
0
def run_sql(sql,
            param=None,
            n=0,
            with_desc=False,
            with_dict=False,
            run_on_slave=False,
            connection=None):
    """Run SQL on the server with PARAM and return result.

    :param param: tuple of string params to insert in the query (see
    notes below)
    :param n: number of tuples in result (0 for unbounded)
    :param with_desc: if True, will return a DB API 7-tuple describing
    columns in query.
    :param with_dict: if True, will return a list of dictionaries
    composed of column-value pairs
    :param connection: if provided, uses the given connection.
    :return: If SELECT, SHOW, DESCRIBE statements, return tuples of data,
    followed by description if parameter with_desc is
    provided.
    If SELECT and with_dict=True, return a list of dictionaries
    composed of column-value pairs, followed by description
    if parameter with_desc is provided.
    If INSERT, return last row id.
    Otherwise return SQL result as provided by database.

    @note: When the site is closed for maintenance (as governed by the
    config variable CFG_ACCESS_CONTROL_LEVEL_SITE), do not attempt
    to run any SQL queries but return empty list immediately.
    Useful to be able to have the website up while MySQL database
    is down for maintenance, hot copies, table repairs, etc.
    @note: In case of problems, exceptions are returned according to
    the Python DB API 2.0.  The client code can import them from
    this file and catch them.
    """
    if cfg['CFG_ACCESS_CONTROL_LEVEL_SITE'] == 3:
        # do not connect to the database as the site is closed for maintenance:
        return []
    elif cfg['CFG_ACCESS_CONTROL_LEVEL_SITE'] > 0:
        # Read only website
        if not sql.upper().startswith("SELECT") and \
                not sql.upper().startswith("SHOW"):
            return

    if param:
        param = tuple(param)

    # FIXME port database slave support
    dbhost = cfg['CFG_DATABASE_HOST']
    if run_on_slave and cfg['CFG_DATABASE_SLAVE']:
        dbhost = cfg['CFG_DATABASE_SLAVE']

    if 'sql-logger' in cfg.get('CFG_DEVEL_TOOLS', []):
        log_sql_query(dbhost, sql, param)

    gc.disable()
    engine = db.engine.execution_options(use_unicode=0)
    sql = sql.replace('`', '"')
    current_app.logger.info(sql)
    if param is None:
        cur = engine.execute(sql.replace('%', '%%'))
    else:
        cur = engine.execute(sql, (param, ))
    gc.enable()

    if string.upper(string.split(sql)[0]) in \
            ("SELECT", "SHOW", "DESC", "DESCRIBE"):
        if n:
            recset = cur.fetchmany(n)
        else:
            recset = cur.fetchall()

        from invenio_base.helpers import utf8ifier
        recset = map(dict if with_dict else tuple, recset)
        recset = utf8ifier(recset)

        if with_desc:
            return recset, cur.description
        else:
            return recset
    else:
        if string.upper(string.split(sql)[0]) == "INSERT":
            return cur.lastrowid
        return cur
Example #54
0
def register():
    """Register."""
    req = request.get_legacy_request()

    # FIXME
    if cfg.get('CFG_ACCESS_CONTROL_LEVEL_SITE') > 0:
        from invenio.legacy import webuser
        return webuser.page_not_authorized(req,
                                           "../youraccount/register?ln=%s" %
                                           g.ln,
                                           navmenuid='youraccount')

    form = RegisterForm(request.values, csrf_enabled=False)

    title = _("Register")
    messages = []
    state = ""

    if form.validate_on_submit():
        from invenio.legacy import webuser
        ruid = webuser.registerUser(req,
                                    form.email.data.encode('utf8'),
                                    form.password.data.encode('utf8'),
                                    form.nickname.data.encode('utf8'),
                                    ln=g.ln)
        if ruid == 0:
            title = _("Account created")
            messages.append(_("Your account has been successfully created."))
            state = "success"
            if cfg.get('CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT') \
                    == 1:
                messages.append(
                    _("In order to confirm its validity, "
                      "an email message containing an account "
                      "activation key has been sent to the given "
                      "email address."))
                messages.append(
                    _("Please follow instructions presented "
                      "there in order to complete the account "
                      "registration process."))
            if cfg.get('CFG_ACCESS_CONTROL_LEVEL_ACCOUNTS') >= 1:
                messages.append(
                    _("A second email will be sent when the "
                      "account has been activated and can be "
                      "used."))
            elif cfg['CFG_ACCESS_CONTROL_NOTIFY_USER_ABOUT_NEW_ACCOUNT'] != 1:
                user = User.query.filter(
                    User.email == form.email.data.lower()).one()
                login_user(user.get_id())
                messages.append(_("You can now access your account."))
        else:
            title = _("Registration failure")
            state = "danger"
            if ruid == 5:
                messages.append(
                    _("Users cannot register themselves, only "
                      "admin can register them."))
            elif ruid == 6 or ruid == 1:
                # Note, code 1 is used both for invalid email, and email
                # sending
                # problems, however the email address is validated by the form,
                # so we only have to report a problem sending the email here
                messages.append(
                    _("The site is having troubles in sending "
                      "you an email for confirming your email "
                      "address."))
                messages.append(
                    _("The error has been logged and will be "
                      "taken in consideration as soon as possible."))
            else:
                # Errors [-2, (1), 2, 3, 4] taken care of by form validation
                messages.append(_("Internal error %(ruid)s", ruid=ruid))
    elif request.method == 'POST':
        title = _("Registration failure")
        state = "warning"

    return render_template('accounts/register.html',
                           form=form,
                           title=title,
                           messages=messages,
                           state=state)