-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Sms to drift user on password change (#31)
* Functionality created to enable sms notification on password change Added function to Cerebrum/modules/no/uio/sysadm_utils to validate that user is sys_adm(-drift) Created file changed_password_notifier.py, which holds two classes. One mixin for password change that creates adds a task to task queue, and one QueueHandler for changed password that creates the task and holds values related to queue. Created the script contrib/no/uio/new_password_task_processor.py that handles the tasks in TaskQueue for password change and tries to send out sms to given user.
- Loading branch information
Sverre Stafsengen Broen
authored and
GitHub Enterprise
committed
Jun 7, 2023
1 parent
0ba74d9
commit b64998f
Showing
3 changed files
with
206 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Copyright 2023 University of Oslo, Norway | ||
# | ||
# This file is part of Cerebrum. | ||
# | ||
# Cerebrum is free software; you can redistribute it and/or modify it | ||
# under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation; either version 2 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# Cerebrum is distributed in the hope that it will be useful, but | ||
# WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
# General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with Cerebrum; if not, write to the Free Software Foundation, | ||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
""" | ||
A file containing two classes that is related to TaskQueue whenever a | ||
password is changed. NotifyChangePasswordMixin is a mixin class for setting a | ||
new password, the functionality within will check if user is a sysadm_account | ||
and add it to queue if that is the case. NotifyPasswordQueueHandler is used for | ||
handling tasks and inherits queue_handler | ||
""" | ||
from Cerebrum import Account | ||
from Cerebrum.Utils import Factory | ||
from Cerebrum.modules.tasks.task_models import Task | ||
from Cerebrum.modules.tasks.task_queue import TaskQueue | ||
from Cerebrum.modules.tasks import queue_handler | ||
from Cerebrum.modules.no.uio.sysadm_utils import is_sysadm_account | ||
|
||
|
||
class NotifyChangePasswordMixin(Account.Account): | ||
def set_password(self, password): | ||
super(NotifyChangePasswordMixin, self).set_password(password) | ||
if not is_sysadm_account(self): | ||
return | ||
task = ChangedPasswordQueueHandler.create_changed_password_task( | ||
self.account_name) | ||
self.__task = task | ||
|
||
def clear(self): | ||
try: | ||
del self.__task | ||
except AttributeError: | ||
pass | ||
super(NotifyChangePasswordMixin, self).clear() | ||
|
||
def write_db(self): | ||
try: | ||
task = self.__task | ||
del self.__task | ||
except AttributeError: | ||
task = None | ||
ret = super(NotifyChangePasswordMixin, self).write_db() | ||
if task is not None: | ||
TaskQueue(self._db).push_task(task) | ||
return ret | ||
|
||
class ChangedPasswordQueueHandler(queue_handler.QueueHandler): | ||
queue = 'notify-changed-password' | ||
max_attempts = 12 | ||
|
||
@classmethod | ||
def create_changed_password_task(cls, key, nbf=None): | ||
return Task( | ||
queue=cls.queue, | ||
key=key, | ||
nbf=nbf, | ||
attempts=0, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
#!/usr/bin/env python | ||
# -*- coding: utf-8 -*- | ||
# | ||
# Copyright 2023 University of Oslo, Norway | ||
# | ||
# This file is part of Cerebrum. | ||
# | ||
# Cerebrum is free software; you can redistribute it and/or modify it | ||
# under the terms of the GNU General Public License as published by | ||
# the Free Software Foundation; either version 2 of the License, or | ||
# (at your option) any later version. | ||
# | ||
# Cerebrum is distributed in the hope that it will be useful, but | ||
# WITHOUT ANY WARRANTY; without even the implied warranty of | ||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
# General Public License for more details. | ||
# | ||
# You should have received a copy of the GNU General Public License | ||
# along with Cerebrum; if not, write to the Free Software Foundation, | ||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. | ||
""" | ||
Script containing functionality for sending sms to persons in | ||
task queue related to password change. | ||
""" | ||
|
||
import io | ||
import logging | ||
import argparse | ||
import cereconf | ||
import functools | ||
from os import path | ||
|
||
import Cerebrum.logutils | ||
import Cerebrum.logutils.options | ||
from Cerebrum.Utils import Factory | ||
from Cerebrum.utils.sms import SMSSender | ||
from Cerebrum.utils.argutils import add_commit_args | ||
from Cerebrum.modules.tasks.task_queue import TaskQueue | ||
from Cerebrum.modules.tasks.queue_processor import QueueProcessor | ||
from Cerebrum.modules.no.uio.changed_password_notifier import ChangedPasswordQueueHandler | ||
|
||
logger = logging.getLogger(__name__) | ||
sms = SMSSender(logger=logger) | ||
|
||
def get_message(uname, time): | ||
with io.open(path.join(cereconf.TEMPLATE_DIR, | ||
'changed_password_notifier.template'), 'r', | ||
encoding='UTF-8') as f: | ||
template = f.read() | ||
return template.format(account_name=uname, time= time) | ||
|
||
def send_sms(uname, task_iat, phone_number): | ||
if not phone_number: | ||
return False | ||
try: | ||
time_format = "%d.%m.%Y %H:%M:%S" | ||
time = task_iat.strftime(time_format) | ||
message = get_message(uname, time) | ||
return sms(phone_number, message) | ||
except Exception as e: | ||
logger.warning("Failed during execution of sending message") | ||
return False | ||
|
||
def task_callback(db, task, dryrun): | ||
ac = Factory.get('Account')(db) | ||
pe = Factory.get('Person')(db) | ||
co = Factory.get('Constants')(db) | ||
|
||
ac.find_by_name(task.key) | ||
pe.find(ac.owner_id) | ||
|
||
spec = map(lambda (s): (co.human2constant(s), co.human2constant("MOBILE")), | ||
cereconf.SYSTEM_LOOKUP_ORDER) | ||
mobile = pe.sort_contact_info(spec, pe.get_contact_info()) | ||
|
||
person_in_systems = [int(af['source_system']) for af in | ||
pe.list_affiliations(person_id=pe.entity_id)] | ||
mobile = filter(lambda x: x['source_system'] in person_in_systems, | ||
mobile)[0]['contact_value'] | ||
|
||
if dryrun: | ||
logger.info('Dryrun for id - %s', task.key) | ||
else: | ||
if not send_sms(ac.account_name, task.iat, mobile): | ||
raise Exception("Sms to " + str(mobile) + " failed with task key - " + | ||
task.key) | ||
return [] | ||
|
||
def run_tasks(dryrun): | ||
callback = functools.partial(task_callback, dryrun=dryrun) | ||
max_attempts = ChangedPasswordQueueHandler.max_attempts | ||
proc = QueueProcessor(ChangedPasswordQueueHandler(callback), | ||
limit=max_attempts, dryrun=dryrun) | ||
tasks = proc.select_tasks() | ||
for task in tasks: | ||
proc.process_task(task) | ||
|
||
|
||
def main(inargs=None): | ||
parser = argparse.ArgumentParser( | ||
description="Handle password change tasks and send sms to people affected", | ||
) | ||
add_commit_args(parser) | ||
Cerebrum.logutils.options.install_subparser(parser) | ||
|
||
args = parser.parse_args(inargs) | ||
Cerebrum.logutils.autoconf('cronjob', args) | ||
dryrun = not args.commit | ||
run_tasks(dryrun) | ||
|
||
|
||
if __name__ == '__main__': | ||
main() |