Exemplo n.º 1
0
    def request_country_exception(self):
        # re-check login...
        # verify we get to country block again
        try:
            self.auth.authenticate(
                username=self.username,
                password=self.request.form.get('password'),
                country=self.get_country_header())
            return json.dumps({
                'success': False,
                'message': 'Error authenticating request',
                'messageType': 'error'
            })
        except authentication.AuthenticationCountryBlocked:
            pass

        req_country = self.get_country_header()
        user = api.user.get(username=self.username)
        data = self.auth.issue_country_exception(user, req_country)

        email_subject = "Country block exception request(Site: %s)" % (
            api.portal.get_registry_record('plone.site_title'))

        for admin_user in get_managers():
            if admin_user.getId() == user.getId():
                # it could be an admin, do not allow him to authorize himself
                continue

            admin_email = admin_user.getProperty('email')

            email_data = data.copy()
            email_data.update({
                'admin_name': (admin_user.getProperty('fullname') or
                               admin_user.getUserName()),
                'name': (user.getProperty('fullname') or user.getUserName()),
                'auth_link': '{}/authorize-country-login?code={}&userid={}'.format(
                    self.context.absolute_url(),
                    data['code'],
                    user.getId()
                )
            })
            email_html = '''
<p>
Hello {admin_name},
</p>
<p>
There has been a request to suspend country login restrictions for this site.

<p>
The user requesting this access logged this information:
</p>
<ul>
<li><b>Username</b>: {username}</li>
<li><b>Name</b>: {name}</li>
<li><b>Country</b>: {country}</li>
<li><b>IP</b>: {ip}</li>
<li><b>User agent</b>: {user_agent}</li>
</ul>

<p>The user has 12 hours between after authorization has been giving to login
   with the temporary access</p>

<p>If you'd like to authorize this user, please click this link:
   <a href="{auth_link}">authorize {username}</a>
</p>'''.format(**email_data)
            send_email(admin_email, email_subject, html=email_html)

        return json.dumps({
            'success': True,
            'message': 'Successfully requested country exception.',
            'messageType': 'info'
        })
Exemplo n.º 2
0
def send_email(*args, **kwargs):
    utils.send_email(*args, **kwargs)
Exemplo n.º 3
0
def archive(site):
    setup_site(site)

    if (not api.portal.get_registry_record('castle.archival_enabled')
            or not api.portal.get_registry_record('castle.aws_s3_bucket_name')
            or not api.portal.get_registry_record('castle.aws_s3_key')
            or not api.portal.get_registry_record('castle.aws_s3_secret')
            or not api.portal.get_registry_record('plone.public_url')):
        logger.error(
            'Can not archive content. Either not enabled, S3 API not set or no public '
            'url set')
        return

    storage = archival.Storage(site)
    for brain in archival.getContentToArchive():
        try:
            ob = brain.getObject()

            container = aq_parent(ob)
            if (IPloneSiteRoot.providedBy(container)
                    and getDefaultPage(container) == ob.getId()):
                continue

            allowed = set(rolesForPermissionOn('View', ob))
            if 'Anonymous' not in allowed:
                # we can *not* archive unpublished content
                continue
            new_url = storage.add_content(ob)

            # resets login creds..
            login_as_admin(app)  # noqa

            if new_url:
                logger.warn('imported %s -> %s' % (ob.absolute_url(), new_url))
                # XXX might need to re-architect... might get conflict errors with how slow
                # archiving takes...
                api.content.delete(ob)
                transaction.commit()
            else:
                logger.error('error importing %s' % ob.absolute_url())
        except:
            logger.error('Error archiving %s' % brain.getPath(), exc_info=True)

    content_to_archive = archival.getContentToArchive(7)
    if len(content_to_archive) == 0:
        return

    backend_url = get_backend_url()
    # send out email warning of content about to be archived
    email_text = """
<p>Warning, this content will be archived in 7 days.
Login to
<a href="{site_url}">{site_title}</a> to extend this content.
</p>
<ul>""".format(site_title=api.portal.get_registry_record('plone.site_title'),
               site_url=backend_url)

    site_url = api.portal.get().absolute_url()
    for brain in content_to_archive:
        url = brain.getURL()
        url = url.replace(site_url, backend_url)
        email_text += """<li>
<a href="{url}">{title}</a></li>""".format(url=url, title=brain.Title)

    email_text += '</ul>'

    for user in api.user.get_users():
        roles = api.user.get_roles(user=user)
        if ('Site Administrator' not in roles and 'Manager' not in roles):
            continue
        email = user.getProperty('email')
        if not email:
            continue

        name = user.getProperty('fullname') or user.getId()
        html = '<p>Hi {name},</p>'.format(name=name) + email_text
        send_email(recipients=email,
                   subject="Content will be archived(Site: %s)" %
                   (api.portal.get_registry_record('plone.site_title')),
                   html=html)
Exemplo n.º 4
0
def check_site(site):
    # XXX will store when last check was so we always only look back
    # to previous check time
    setSite(site)
    catalog = api.portal.get_tool('portal_catalog')
    es = ElasticSearchCatalog(catalog)
    if not es.enabled:
        return

    index_name = audit.get_index_name()
    es = ESConnectionFactoryFactory()()

    sannotations = IAnnotations(site)
    last_checked = sannotations.get(LAST_CHECKED_KEY)
    if last_checked is None:
        last_checked = DateTime() - 30

    filters = [{
        'term': {
            'type': 'workflow'
        }
    }, {
        'range': {
            'date': {
                'gt': last_checked.ISO8601()
            }
        }
    }]

    if len(filters) > 1:
        qfilter = {'and': filters}
    else:
        qfilter = filters[0]
    query = {
        "query": {
            'filtered': {
                'filter': qfilter,
                'query': {
                    'match_all': {}
                }
            }
        }
    }
    results = es.search(index=index_name,
                        doc_type=audit.es_doc_type,
                        body=query,
                        sort='date:desc',
                        size=1000)
    hits = results['hits']['hits']

    workflow = api.portal.get_tool('portal_workflow')
    forced = []
    checked = []
    for hit in hits:
        hit = hit['_source']
        if hit['object'] in checked:
            continue
        try:
            ob = uuidToObject(hit['object'])
            checked.append(hit['object'])
        except:
            continue

        try:
            review_history = workflow.getInfoFor(ob, 'review_history')
            if not review_history:
                continue

            for r in reversed(review_history):
                if (not r['action'] or r['review_state'] != 'published'
                        or not r.get('comments', '').startswith('OVERRIDE:')):
                    continue
                if r['time'] < last_checked:
                    # just quit now, we're getting to older history that we don't care about
                    break
                forced.append({'ob': ob, 'history_entry': r})
        except WorkflowException:
            continue

    if len(forced) > 0:
        # sent out email to admins
        site_url = site.absolute_url()
        registry = getUtility(IRegistry)
        public_url = registry.get('plone.public_url')
        if not public_url:
            public_url = site_url
        email_html = EMAIL_BODY + '<ul>'
        for item in forced:
            ob = item['ob']
            wf_entry = item['history_entry']
            try:
                user = api.user.get(wf_entry['actor'])
                user_name = user.getProperty('fullname') or user.getId()
            except:
                user_name = wf_entry['actor']
            email_html += EMAIL_BODY_ITEM.format(
                content_url=ob.absolute_url().replace(site_url, public_url),
                content_title=ob.Title(),
                user_name=user_name,
                comments=wf_entry.get('comments', ''))
        email_html += '</ul>'
        email_subject = "Forced content publication update(Site: %s)" % (
            api.portal.get_registry_record('plone.site_title'))

        for user in api.user.get_users():
            user_roles = api.user.get_roles(user=user)
            email = user.getProperty('email')
            if (('Manager' not in user_roles
                 and 'Site Administrator' not in user_roles) or not email):
                continue

            utils.send_email(email, email_subject, html=email_html)

    site._p_jar.sync()
    sannotations[LAST_CHECKED_KEY] = DateTime()
    transaction.commit()
Exemplo n.º 5
0
def _delete_items(uids):
    user = api.user.get_current()
    email = user.getProperty('email')
    name = user.getProperty('fullname') or user.getId()
    errors = []
    deleted = []
    site_path = '/'.join(api.portal.get().getPhysicalPath())

    for brain in api.portal.get_tool('portal_catalog')(UID=uids):
        obj = brain.getObject()

        try:
            lock_info = obj.restrictedTraverse('@@plone_lock_info')
        except AttributeError:
            lock_info = None
        if lock_info is not None and lock_info.is_locked():
            try:
                plone_lock_operations = obj.restrictedTraverse(
                    '@@plone_lock_operations')
                plone_lock_operations.safe_unlock()
            except AttributeError:
                pass

        parent = aq_parent(obj)
        obj_path = '/'.join(obj.getPhysicalPath())[len(site_path):]
        title = pretty_title_or_id(obj, obj)
        try:
            parent.manage_delObjects(obj.getId())
            deleted.append({'path': obj_path, 'title': title})
        except Unauthorized:
            errors.append({
                'path': obj_path,
                'msg': 'Unauthorized to delete object',
                'title': title
            })
        except:
            errors.append({
                'path': obj_path,
                'msg': 'Unknown error attempting to delete',
                'title': title
            })

    # we commit here so we can trigger conflict errors before
    # trying to send email
    transaction.commit()

    if email:
        errors_html = ''
        if len(errors) > 0:
            error_items_html = ''
            for error in errors:
                error_items_html += '<li>{0}({1}): {2}</li>'.format(
                    error['title'], error['path'], error['msg'])
            errors_html = """
<h3>There were errors attempting to delete some of the items</h3>
<ul>%s</ul>""" % error_items_html

        items_html = ''
        for item in deleted:
            items_html += '<li>{0}({1})</li>'.format(item['title'],
                                                     item['path'])
        deleted_html = """
<h3>Deleted items</h3>
<ul>{0}</ul>""".format(items_html)
        try:
            utils.send_email(
                recipients=email,
                subject="Finished deleting items(Site: %s)" %
                (api.portal.get_registry_record('plone.site_title')),
                html="""
<p>Hi {0},</p>

<p>The site has finished deleting items you asked for.</p>

{1}

{2}
""".format(name, deleted_html, errors_html))
        except:
            logger.warn('Could not send status email ', exc_info=True)
Exemplo n.º 6
0
def _paste_items(where, op, mdatas):
    logger.info('Copying a bunch of items')
    portal = api.portal.get()
    catalog = api.portal.get_tool('portal_catalog')
    dest = portal.restrictedTraverse(str(where.lstrip('/')))

    count = 0
    commit_count = 0
    if not getCelery().conf.task_always_eager:
        portal._p_jar.sync()

    try:
        if mdatas[0][0].startswith('cache:'):
            cache_key = mdatas[0][0].replace('cache:', '')
            mdatas = cache.get(cache_key)
    except IndexError:
        pass

    for mdata in mdatas[:]:
        count += len(catalog(path={'query': '/'.join(mdata), 'depth': -1}))
        ob = portal.unrestrictedTraverse(str('/'.join(mdata)), None)
        if ob is None:
            continue
        if op == 0:
            # copy
            api.content.copy(ob, dest, safe_id=True)
        else:
            api.content.move(ob, dest, safe_id=True)

        if count / 50 != commit_count:
            # commit every 50 objects moved
            transaction.commit()
            commit_count = count / 50
            if not getCelery().conf.task_always_eager:
                portal._p_jar.sync()
            # so we do not redo it
            try:
                mdatas.remove(mdata)
            except Exception:
                pass

    # we commit here so we can trigger conflict errors before
    # trying to send email
    transaction.commit()

    user = api.user.get_current()
    email = user.getProperty('email')
    if email:
        name = user.getProperty('fullname') or user.getId()
        try:
            utils.send_email(
                recipients=email,
                subject="Paste Operation Finished(Site: %s)" %
                (api.portal.get_registry_record('plone.site_title')),
                html="""
    <p>Hi %s,</p>

    <p>The site has finished pasting items into /%s folder.</p>""" %
                (name, where.lstrip('/')))
        except Exception:
            logger.warn('Could not send status email ', exc_info=True)