Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
from __future__ import unicode_literals, print_function
from flask import render_template_string
from sqlalchemy.orm import subqueryload, undefer
from indico.core.db import db
from indico.core.db.sqlalchemy.principals import PrincipalType
from import ProtectionMode
from indico.core.notifications import make_email, send_email
from indico.modules.categories import Category
from indico.modules.groups import GroupProxy
from import make_app
email_tpl = '''
{%- autoescape off -%}
Dear user,
You are receiving this email since you are a manager of the following category:
{{ cat.chain_titles|join(' > ') }}
The category is public and there are no restrictions on who is allowed to
create events in it, i.e. anyone on the Internet could create events in your
category since a lightweight CERN account or a social media account can be used
to login to Indico.
For this reason we've enabled "Restricted event creation" in your category.
To keep the behavior as close as possible to what you had before, we've also added
the 'CERN Users' group to the list of people authorized to create events. That way
anyone who is affiliated with CERN can still create events, while random strangers
cannot anymore.
{% if creators %}
Additionally, the following list of users/groups is currently authorized to
create events in your category (in addition to all category managers):
{% for principal in creators -%}
- {{ }}
{% endfor %}
{%- endif %}
You can view/manage your category's protection setting on this page:
{{ url_for('categories.manage_protection', cat, _external=true) }}
Kind regards
CERN Indico Team
{%- endautoescape -%}
def main():
cern_users = GroupProxy('CERN Users', provider='cern-ldap')
# TODO remove the category children check with 3.0 when we allow mixed categories
cats = (Category.query
.filter(Category.effective_protection_mode == ProtectionMode.public,
.options(undefer('chain_titles'), subqueryload('acl_entries'))
for cat in cats:
managers = {p for p in cat.acl_entries if p.full_access}
recipients = { for p in managers if p.type == PrincipalType.user}
creators = {p.principal for p in cat.acl_entries if p.has_management_permission('create', explicit=True)}
if creators:
for p in creators:
print(' Existing creator: {}'.format(
if recipients:
body = render_template_string(email_tpl, cat=cat, creators=creators)
email = make_email(to_list=recipients,
subject='[Indico] Category security',
print(' Emailing managers: {}'.format(', '.join(sorted(recipients))))
raw_input('Email ok? Enter to continue')
print(' Restricting creation and adding CERN Users')
cat.update_principal(cern_users, add_permissions={'create'})
cat.event_creation_restricted = True
raw_input('Enter to commit')
if __name__ == '__main__':
with make_app(set_path=True).app_context():
Copy link

DirkHoffmann commented Dec 9, 2020

What is the raw_input() in l.81 supposed to do?
Is it a breakpoint before sending email? Then should be called before send_email() one line before.
For an a posteriori message that email was sent, the text is strange.

Copy link

ThiefMaster commented Dec 9, 2020

I'm BCCing myself so I'm basically pausing after sending an email... probably not that useful, I just had it in there when I wrote the very first version of that script a long time ago.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment