forked from public/pyceo
Unsubscribe/resubscribe members when they're expired and renewed (#53)
Co-authored-by: Rio Liu <rio.liu@r26.me> Co-authored-by: Rio6 <rio.liu@r26.me> Co-authored-by: Max Erenberg <merenber@csclub.uwaterloo.ca> Reviewed-on: public/pyceo#53 Co-authored-by: Rio <r345liu@localhost> Co-committed-by: Rio <r345liu@localhost>
This commit is contained in:
parent
87470e1f3b
commit
55c4b2151d
|
@ -4,8 +4,8 @@ from zope import component
|
||||||
from .utils import authz_restrict_to_staff, authz_restrict_to_syscom, \
|
from .utils import authz_restrict_to_staff, authz_restrict_to_syscom, \
|
||||||
user_is_in_group, requires_authentication_no_realm, \
|
user_is_in_group, requires_authentication_no_realm, \
|
||||||
create_streaming_response, development_only, is_truthy
|
create_streaming_response, development_only, is_truthy
|
||||||
from ceo_common.errors import BadRequest
|
from ceo_common.errors import BadRequest, UserAlreadySubscribedError, UserNotSubscribedError
|
||||||
from ceo_common.interfaces import ILDAPService
|
from ceo_common.interfaces import ILDAPService, IConfig
|
||||||
from ceod.transactions.members import (
|
from ceod.transactions.members import (
|
||||||
AddMemberTransaction,
|
AddMemberTransaction,
|
||||||
ModifyMemberTransaction,
|
ModifyMemberTransaction,
|
||||||
|
@ -92,14 +92,25 @@ def renew_user(username: str):
|
||||||
g.need_admin_creds = True
|
g.need_admin_creds = True
|
||||||
|
|
||||||
ldap_srv = component.getUtility(ILDAPService)
|
ldap_srv = component.getUtility(ILDAPService)
|
||||||
|
cfg = component.getUtility(IConfig)
|
||||||
user = ldap_srv.get_user(username)
|
user = ldap_srv.get_user(username)
|
||||||
|
member_list = cfg.get('mailman3_new_member_list')
|
||||||
|
|
||||||
|
def unexpire(user):
|
||||||
|
if user.shadowExpire:
|
||||||
|
user.set_expired(False)
|
||||||
|
try:
|
||||||
|
user.subscribe_to_mailing_list(member_list)
|
||||||
|
except UserAlreadySubscribedError:
|
||||||
|
pass
|
||||||
|
|
||||||
if body.get('terms'):
|
if body.get('terms'):
|
||||||
user.add_terms(body['terms'])
|
user.add_terms(body['terms'])
|
||||||
user.set_expired(False)
|
unexpire(user)
|
||||||
return {'terms_added': body['terms']}
|
return {'terms_added': body['terms']}
|
||||||
elif body.get('non_member_terms'):
|
elif body.get('non_member_terms'):
|
||||||
user.add_non_member_terms(body['non_member_terms'])
|
user.add_non_member_terms(body['non_member_terms'])
|
||||||
user.set_expired(False)
|
unexpire(user)
|
||||||
return {'non_member_terms_added': body['non_member_terms']}
|
return {'non_member_terms_added': body['non_member_terms']}
|
||||||
else:
|
else:
|
||||||
raise BadRequest('Must specify either terms or non-member terms')
|
raise BadRequest('Must specify either terms or non-member terms')
|
||||||
|
@ -129,10 +140,16 @@ def expire_users():
|
||||||
dry_run = is_truthy(request.args.get('dry_run', 'false'))
|
dry_run = is_truthy(request.args.get('dry_run', 'false'))
|
||||||
|
|
||||||
ldap_srv = component.getUtility(ILDAPService)
|
ldap_srv = component.getUtility(ILDAPService)
|
||||||
|
cfg = component.getUtility(IConfig)
|
||||||
members = ldap_srv.get_expiring_users()
|
members = ldap_srv.get_expiring_users()
|
||||||
|
member_list = cfg.get('mailman3_new_member_list')
|
||||||
|
|
||||||
if not dry_run:
|
if not dry_run:
|
||||||
for member in members:
|
for member in members:
|
||||||
member.set_expired(True)
|
member.set_expired(True)
|
||||||
|
try:
|
||||||
|
member.unsubscribe_from_mailing_list(member_list)
|
||||||
|
except UserNotSubscribedError:
|
||||||
|
pass
|
||||||
|
|
||||||
return json.jsonify([member.uid for member in members])
|
return json.jsonify([member.uid for member in members])
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
This is a script which unsubscribes expired members from csc-general.
|
||||||
|
|
||||||
|
GSSAPI is used for SPNEGO authentication, so make sure to run `kinit` first.
|
||||||
|
Also, make sure to run this script from the top-level of the git directory
|
||||||
|
(see the sys.path hack below).
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import ldap3
|
||||||
|
from zope import component
|
||||||
|
|
||||||
|
sys.path.append(os.getcwd())
|
||||||
|
from ceo_common.errors import UserNotSubscribedError
|
||||||
|
from ceo_common.interfaces import IConfig, IHTTPClient
|
||||||
|
from ceo_common.model import Config, HTTPClient, RemoteMailmanService
|
||||||
|
|
||||||
|
# modify as necessary
|
||||||
|
CONFIG_FILE = '/etc/csc/ceod.ini'
|
||||||
|
NEW_MEMBER_LIST = 'csc-general'
|
||||||
|
|
||||||
|
cfg = Config(CONFIG_FILE)
|
||||||
|
component.provideUtility(cfg, IConfig)
|
||||||
|
http_client = HTTPClient()
|
||||||
|
component.provideUtility(http_client, IHTTPClient)
|
||||||
|
mailman_srv = RemoteMailmanService()
|
||||||
|
LDAP_URI = cfg.get('ldap_server_url')
|
||||||
|
LDAP_MEMBERS_BASE = cfg.get('ldap_users_base')
|
||||||
|
|
||||||
|
conn = ldap3.Connection(LDAP_URI, auto_bind=True, raise_exceptions=True)
|
||||||
|
conn.search(LDAP_MEMBERS_BASE, '(shadowExpire=1)', attributes=['uid'])
|
||||||
|
total_unsubscribed = 0
|
||||||
|
for entry in conn.entries:
|
||||||
|
uid = entry.uid.value
|
||||||
|
try:
|
||||||
|
mailman_srv.unsubscribe(uid, NEW_MEMBER_LIST)
|
||||||
|
print(f'Unsubscribed {uid}')
|
||||||
|
total_unsubscribed += 1
|
||||||
|
except UserNotSubscribedError:
|
||||||
|
print(f'{uid} is already unsubscribed')
|
||||||
|
print(f'Total unsubscribed: {total_unsubscribed}')
|
Loading…
Reference in New Issue