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' })
def send_email(*args, **kwargs): utils.send_email(*args, **kwargs)
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)
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()
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)
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)