def test_post_send_rtt_usage_not_enough_ko(self): self.config.testing_securitypolicy(userid=u'janedoe', permissive=True) from pyvac.models import Request, User from pyvac.views.request import Send total_req = Request.find(self.session, count=True) def mock_get_rtt_usage(self, session): """ Get rrt usage for a user """ return {'allowed': 10, 'left': 0.5, 'state': 'error', 'taken': 9.5, 'year': 2014} orig_get_rtt_usage = User.get_rtt_usage User.get_rtt_usage = mock_get_rtt_usage user = User.by_login(self.session, u'janedoe') rtt_data = user.get_rtt_usage(self.session) self.assertTrue(rtt_data) request = self.create_request({'days': 1, 'date_from': '05/05/2015 - 05/05/2015', 'type': '2', 'breakdown': 'FULL', }) view = Send(request)() self.assertIsRedirect(view) # no new requests were made self.assertEqual(Request.find(self.session, count=True), total_req) expected = ['error;You only have 0.5 RTT to use.'] self.assertEqual(request.session.pop_flash(), expected) User.get_rtt_usage = orig_get_rtt_usage
def test_post_send_rtt_usage_not_enough_ko(self): self.config.testing_securitypolicy(userid=u'janedoe', permissive=True) from pyvac.models import Request, User from pyvac.views.request import Send total_req = Request.find(self.session, count=True) with patch('pyvac.models.User.pool', new_callable=PropertyMock) as mock_foo: mocked_pool = mock_pool(0.5, datetime(2014, 1, 1), datetime(2014, 12, 31)) mock_foo.return_value = {'RTT': mocked_pool} user = User.by_login(self.session, u'janedoe') rtt_pool = user.pool.get('RTT') self.assertTrue(rtt_pool) request = self.create_request({'days': 1, 'date_from': '05/05/2015 - 05/05/2015', # noqa 'type': '2', 'breakdown': 'FULL', }) view = Send(request)() self.assertIsRedirect(view) # no new requests were made self.assertEqual(Request.find(self.session, count=True), total_req) expected = ['error;You only have 0.5 RTT to use.'] self.assertEqual(request.session.pop_flash(), expected)
def test_post_send_rtt_year_ko(self): self.config.testing_securitypolicy(userid=u'janedoe', permissive=True) from pyvac.models import Request, User from pyvac.views.request import Send total_req = Request.find(self.session, count=True) with patch('pyvac.models.User.pool', new_callable=PropertyMock) as mock_foo: mocked_pool = mock_pool(10, datetime(2015, 1, 1), datetime(2015, 12, 31)) mock_foo.return_value = {'RTT': mocked_pool} user = User.by_login(self.session, u'janedoe') rtt_pool = user.pool.get('RTT') self.assertTrue(rtt_pool) request = self.create_request({ 'days': 1, 'date_from': '06/05/2016 - 06/05/2016', 'type': '2', 'breakdown': 'AM', }) view = Send(request)() self.assertIsRedirect(view) # no new requests were made self.assertEqual(Request.find(self.session, count=True), total_req) expected = ['error;RTT can only be used between 01/01/2015 and 31/12/2015'] # noqa self.assertEqual(request.session.pop_flash(), expected)
def test_post_send_exception_reason_length_ko(self): self.config.testing_securitypolicy(userid=u'janedoe', permissive=True) from pyvac.models import Request from pyvac.views.request import Send total_req = Request.find(self.session, count=True) with freeze_time('2015-10-01', ignore=['celery', 'psycopg2', 'sqlalchemy', 'icalendar']): request = self.create_request({ 'days': 1, 'date_from': '12/11/2015 - 12/11/2015', 'type': '6', 'breakdown': 'FULL', 'exception_text': "I need to see Star Wars, I'm a huge fan" "please, please, please, please, please, " "please, please, please, please, please, " "please, please, please, please, please, " "please, please, please, please, please, " "please, please, please, please, please, " "please, please, please, please, please, ", }) view = Send(request)() self.assertIsRedirect(view) self.assertEqual(Request.find(self.session, count=True), total_req) expected = [u'error;Exceptionnel reason must not exceed 140 ' 'characters'] self.assertEqual(request.session.pop_flash(), expected)
def test_post_send_recovery_ok(self): self.config.testing_securitypolicy(userid=u'janedoe', permissive=True) from pyvac.models import Request from pyvac.views.request import Send total_req = Request.find(self.session, count=True) msg = u"I need to see Star Wars, because I'm a really huge fan !!!" with freeze_time('2015-10-01', ignore=['celery', 'psycopg2', 'sqlalchemy', 'icalendar']): request = self.create_request({ 'days': 1, 'date_from': '12/11/2015 - 12/11/2015', 'type': '4', 'breakdown': 'FULL', 'exception_text': msg, }) view = Send(request)() self.assertIsRedirect(view) self.assertEqual(Request.find(self.session, count=True), total_req + 1) last_req = Request.find(self.session)[-1] self.assertEqual(last_req.type, u'Récupération') self.assertEqual(last_req.message, msg) self.session.delete(last_req)
def test_in_conflict_manager(self): from pyvac.models import Request req = Request.by_id(self.session, 1) self.assertIsInstance(req, Request) nb_conflicts = Request.in_conflict_manager(self.session, req, count=True) self.assertEqual(nb_conflicts, 1)
def test_post_send_rtt_holiday_ok(self): self.config.testing_securitypolicy(userid=u'janedoe', permissive=True) from pyvac.models import Request, User from pyvac.views.request import Send total_req = Request.find(self.session, count=True) janedoe = User.by_login(self.session, u'janedoe') old_created_at = janedoe.created_at janedoe.created_at = janedoe.created_at.replace(month=1) janedoe.get_rtt_usage(self.session) with freeze_time('2016-12-01', ignore=['celery', 'psycopg2', 'sqlalchemy', 'icalendar']): request = self.create_request({ 'days': 5, 'date_from': '11/07/2016 - 15/07/2016', 'type': '2', 'breakdown': 'FULL', }) view = Send(request)() self.assertIsRedirect(view) self.assertEqual(Request.find(self.session, count=True), total_req + 1) last_req = Request.find(self.session)[-1] self.assertEqual(last_req.status, u'PENDING') self.assertEqual(last_req.days, 4.0) janedoe.created_at = old_created_at self.delete_last_req(last_req)
def render(self): req_list = {'requests': [], 'conflicts': {}} requests = [] if self.user.is_admin: requests = Request.all_for_admin(self.session) elif self.user.is_super: requests = Request.by_manager(self.session, self.user) if requests: conflicts = {} for req in requests: req.conflict = [req2.summary for req2 in Request.in_conflict(self.session, req)] if req.conflict: conflicts[req.id] = '\n'.join(req.conflict) req_list['requests'] = requests req_list['conflicts'] = conflicts # always add our requests for req in Request.by_user(self.session, self.user): if req not in req_list['requests']: req_list['requests'].append(req) return req_list
def replay(settings): with open(settings['pyvac.celery.yaml']) as fdesc: Conf = yaml.load(fdesc, YAMLLoader) caldav_url = Conf.get('caldav').get('url') # XXX Register the database create_engine(settings, scoped=True) session = DBSession() calendar = get_calendar(caldav_url) requests = Request.find(session, where=(Request.status == 'APPROVED_ADMIN',), order_by=Request.user_id) print 'total requests', len(requests) print '' req_to_add = [] # for each requests for req in requests: print '-' * 10 print req.id, req.summarycal, req.date_from, req.date_to # check if entry in caldav exists results = calendar.date_search(req.date_from, req.date_to) if not results: # need to add missing entry in caldav print 'need to insert request' req_to_add.append(req.id) else: summaries = [] for event in results: try: parse_event(event) except Exception: continue event.load() # XXX: if needed to delete entries # uid = event.instance.vevent.uid.value # ics = '%s/%s.ics' % (caldav_url, uid) # print delFromCal(caldav_url, ics) summary = event.instance.vevent.summary.value summaries.append(summary) if req.summarycal not in summaries: print 'need to insert request' req_to_add.append(req.id) for req_id in set(req_to_add): req = Request.by_id(session, req_id) print 'processing', req.id, req.summarycal, req.date_from, req.date_to ics_url = addToCal(caldav_url, req.date_from, req.date_to, req.summarycal) # save ics url in request req.ics_url = ics_url session.add(req) session.flush() transaction.commit()
def test_post_send_rtt_usage_empty_ok(self): self.config.testing_securitypolicy(userid=u'janedoe', permissive=True) from pyvac.models import Request, User from pyvac.views.request import Send total_req = Request.find(self.session, count=True) def mock_get_rtt_usage(self, session): """ Get rrt usage for a user """ return orig_get_rtt_usage = User.get_rtt_usage User.get_rtt_usage = mock_get_rtt_usage user = User.by_login(self.session, u'janedoe') rtt_data = user.get_rtt_usage(self.session) self.assertIsNone(rtt_data) view = Send(self.create_request({ 'days': 1, 'date_from': '05/05/2015 - 05/05/2015', 'type': '2', 'breakdown': 'AM', }))() self.assertIsRedirect(view) self.assertEqual(Request.find(self.session, count=True), total_req + 1) User.get_rtt_usage = orig_get_rtt_usage
def test_post_send_recovery_ok(self): self.config.testing_securitypolicy(userid=u'janedoe', permissive=True) from pyvac.models import Request from pyvac.views.request import Send total_req = Request.find(self.session, count=True) msg = u"I need to see Star Wars, because I'm a really huge fan !!!" with freeze_time('2015-10-01', ignore=['celery', 'psycopg2', 'sqlalchemy', 'icalendar']): request = self.create_request({ 'days': 1, 'date_from': '12/11/2015 - 12/11/2015', 'type': '4', 'breakdown': 'FULL', 'exception_text': msg, }) view = Send(request)() self.assertIsRedirect(view) self.assertEqual(Request.find(self.session, count=True), total_req + 1) last_req = Request.find(self.session)[-1] self.assertEqual(last_req.type, u'Récupération') self.assertEqual(last_req.message, msg) self.delete_last_req(last_req)
def get_users_stats(self, users_per_id): entity_length = len(users_per_id) if not entity_length: return # retrieve today's squad off members today = datetime.now() today_off = [] today_requests = [] requests = Request.get_active(self.session) for req in requests: if req.user.id not in users_per_id: continue today_requests.append(req) if req.user not in today_off: today_off.append(req.user) # retrieve active requests since 15 days ago date_from = today - relativedelta(days=15) all_reqs = [] for user_id, user in list(users_per_id.items()): user_req = Request.by_user_future_approved(self.session, user, date_from=date_from) all_reqs.extend(user_req) # compute current month squad presence percentages data_months = {} for req in all_reqs: for dt in req.dates: if dt.month not in data_months: data_months[dt.month] = {} if dt.day not in data_months[dt.month]: data_months[dt.month][dt.day] = [] if req.user.login not in data_months[dt.month][dt.day]: data_months[dt.month][dt.day].append(req.user.login) data_days_current = [] labels = [] start_date = today - timedelta(days=15) stop_date = today + timedelta(days=15) for x in daterange(start_date, stop_date): labels.append("'%s'" % x.strftime('%d/%m')) perc = ((entity_length - len(data_months.get(x.month, {}).get(x.day, []))) / float(entity_length) * 100) # noqa perc = round(perc, 2) if x.isoweekday() in [6, 7]: perc = 0.0 data_days_current.append(perc) labels = '[%s]' % ','.join(labels) return {'users_per_id': users_per_id, 'data_days_current': data_days_current, 'today_requests': today_requests, 'labels': labels, 'today': today, 'today_off': today_off, 'today_off_length': len(today_off), 'entity_length': entity_length, }
def test_post_send_wrong_date_ko(self): self.config.testing_securitypolicy(userid=u'janedoe', permissive=True) from pyvac.models import Request from pyvac.views.request import Send total_req = Request.find(self.session, count=True) view = Send(self.create_request({'date_from': 'foo'}))() self.assertIsRedirect(view) self.assertEqual(Request.find(self.session, count=True), total_req)
def replay(settings): with open(settings["pyvac.celery.yaml"]) as fdesc: Conf = yaml.load(fdesc, YAMLLoader) caldav_url = Conf.get("caldav").get("url") # XXX Register the database create_engine(settings, scoped=True) session = DBSession() calendar = get_calendar(caldav_url) requests = Request.find(session, where=(Request.status == "APPROVED_ADMIN",), order_by=Request.user_id) print "total requests", len(requests) print "" req_to_add = [] # for each requests for req in requests: print "-" * 10 print req.id, req.summarycal, req.date_from, req.date_to # check if entry in caldav exists results = calendar.date_search(req.date_from, req.date_to) if not results: # need to add missing entry in caldav print "need to insert request" req_to_add.append(req.id) else: summaries = [] for event in results: try: parse_event(event) except Exception: continue event.load() # XXX: if needed to delete entries # uid = event.instance.vevent.uid.value # ics = '%s/%s.ics' % (caldav_url, uid) # print delFromCal(caldav_url, ics) summary = event.instance.vevent.summary.value summaries.append(summary) if req.summarycal not in summaries: print "need to insert request" req_to_add.append(req.id) for req_id in set(req_to_add): req = Request.by_id(session, req_id) print "processing", req.id, req.summarycal, req.date_from, req.date_to ics_url = addToCal(caldav_url, req.date_from, req.date_to, req.summarycal) # save ics url in request req.ics_url = ics_url session.add(req) session.flush() transaction.commit()
def test_by_user_outdated(self): from pyvac.models import User, Request user1 = User.by_login(self.session, u"jdoe") requests = Request.by_user(self.session, user1) self.assertEqual(len(requests), 5) outdated = Request.by_id(self.session, 7) self.assertIsInstance(outdated, Request) self.assertEqual(outdated.user, user1) self.assertFalse(outdated in requests)
def render(self): if not self.user: return self.redirect() _ = self.request.translate self.user.rtt = self.user.get_rtt_usage(self.session) holidays = get_holiday(self.user) ret_dict = {'types': [], 'holidays': holidays, 'sudo_users': [], 'futures_pending': [], 'futures_approved': []} vacation_types = VacationType.by_country(self.session, self.user.country) for vac in vacation_types: if vac.visibility and self.user.role not in vac.visibility: continue ret_dict['types'].append({'name': _(vac.name), 'id': vac.id}) if self.user.is_admin: ret_dict['sudo_users'] = User.for_admin(self.session, self.user) futures_pending = [timestamp for req in Request.by_user_future_pending(self.session, self.user) for timestamp in req.timestamps] ret_dict['futures_pending'] = futures_pending futures_approved = [timestamp for req in Request.by_user_future_approved(self.session, self.user) for timestamp in req.timestamps] ret_dict['futures_approved'] = futures_approved exception_info_tooltip = """\ This type is for events which are not covered by other types: \ wedding, funeral, etc. Providing a reason for this request is mandatory. """ ret_dict['exception_info_tooltip'] = _(exception_info_tooltip) if self.request.matched_route: matched_route = self.request.matched_route.name ret_dict.update({ 'matched_route': matched_route, 'csrf_token': self.request.session.get_csrf_token()}) return ret_dict ret_dict.update({'csrf_token': self.request.session.get_csrf_token()}) return ret_dict
def test_post_send_ok(self): self.config.testing_securitypolicy(userid=u'janedoe', permissive=True) from pyvac.models import Request from pyvac.views.request import Send total_req = Request.find(self.session, count=True) view = Send(self.create_request({'days': 4, 'date_from': '05/05/2014 - 10/05/2014', 'type': 'CP', }))() self.assertIsRedirect(view) self.assertEqual(Request.find(self.session, count=True), total_req + 1)
def test_by_user_outdated(self): from pyvac.models import User, Request user1 = User.by_login(self.session, u'jdoe') with freeze_time('2015-08-01', ignore=['celery', 'psycopg2', 'sqlalchemy', 'icalendar']): requests = Request.by_user(self.session, user1) self.assertEqual(len(requests), 8) outdated = Request.by_id(self.session, 7) self.assertIsInstance(outdated, Request) self.assertEqual(outdated.user, user1) self.assertFalse(outdated in requests)
def test_post_send_half_day_ok(self): self.config.testing_securitypolicy(userid=u'janedoe', permissive=True) from pyvac.models import Request from pyvac.views.request import Send total_req = Request.find(self.session, count=True) view = Send(self.create_request({ 'days': 0.5, 'date_from': '05/05/2015 - 05/05/2015', 'type': '1', 'breakdown': 'AM', }))() self.assertIsRedirect(view) self.assertEqual(Request.find(self.session, count=True), total_req + 1)
def run(self, *args, **kwargs): self.log = log # init database connection session = DBSession() statuses = ['PENDING', 'ACCEPTED_MANAGER', 'DENIED', 'APPROVED_ADMIN', 'CANCELED', 'ERROR'] for status in statuses: requests = Request.by_status(session, status) self.log.info('number of requests for %s: %d' % (status, len(requests))) req_accepted_notified = Request.by_status(session, 'ACCEPTED_MANAGER', notified=True) self.log.info('number of ACCEPTED_NOTIFIED requests: %d' % len(req_accepted_notified)) # req_pending_notified = Request.by_status(session, 'PENDING', # notified=True) # self.log.info('number of PENDING_NOTIFIED requests: %d' % # len(req_pending_notified)) req_list = [] req_list.extend(req_accepted_notified) # req_list.extend(req_pending_notified) for req in req_list: self.log.info('selecting task for req type %r' % req.status) check_status = req.status if req.status == 'ACCEPTED_MANAGER' and req.notified: check_status = 'ACCEPTED_NOTIFIED' # if req.status == 'PENDING' and req.notified: # check_status = 'PENDING_NOTIFIED' req_task = self.worker_tasks[check_status] self.log.info('task selected %r' % req_task.name) data = { 'req_id': req.id, } async_result = subtask(req_task).delay(data=data) self.log.info('task scheduled %r' % async_result) return True
def run(self, *args, **kwargs): self.log = log # init database connection session = DBSession() statuses = [ 'PENDING', 'ACCEPTED_MANAGER', 'DENIED', 'APPROVED_ADMIN', 'CANCELED', 'ERROR' ] for status in statuses: requests = Request.by_status(session, status) self.log.info('number of requests for %s: %d' % (status, len(requests))) req_accepted_notified = Request.by_status(session, 'ACCEPTED_MANAGER', notified=True) self.log.info('number of ACCEPTED_NOTIFIED requests: %d' % len(req_accepted_notified)) # req_pending_notified = Request.by_status(session, 'PENDING', # notified=True) # self.log.info('number of PENDING_NOTIFIED requests: %d' % # len(req_pending_notified)) req_list = [] req_list.extend(req_accepted_notified) # req_list.extend(req_pending_notified) for req in req_list: self.log.info('selecting task for req type %r' % req.status) check_status = req.status if req.status == 'ACCEPTED_MANAGER' and req.notified: check_status = 'ACCEPTED_NOTIFIED' # if req.status == 'PENDING' and req.notified: # check_status = 'PENDING_NOTIFIED' req_task = self.worker_tasks[check_status] self.log.info('task selected %r' % req_task.name) data = { 'req_id': req.id, } async_result = subtask(req_task).delay(data=data) self.log.info('task scheduled %r' % async_result) return True
def test_summarycsv_message(self): from pyvac.models import Request req = Request.by_id(self.session, 14) self.assertIsInstance(req, Request) msg = (u",Doe,Jane,13/06/2016,13/06/2016,1.0,Exceptionnel,," "I need to see Star Wars, I'm a huge fan") self.assertEqual(req.summarycsv, msg)
def process(self, data): """ accepted by manager auto flag as accepted by HR """ req = Request.by_id(self.session, data['req_id']) # after new field was added, it may not be set yet if not req.date_updated: return delta = datetime.now() - req.date_updated # after Request.date_updated + 3 days, auto accept it by HR if delta.days >= 3: # auto accept it as HR self.log.info('3 days passed, auto accept it by HR') # create history entry msg = 'Automatically accepted by HR after 3 days passed' # use error_message field, as it should not be used here # if it fails in ERROR it should be overwritten anyway # as the status will be changed from APPROVED_ADMIN to ERROR RequestHistory.new(self.session, req, req.status, 'APPROVED_ADMIN', user=None, error_message=msg) # update request status after sending email req.update_status('APPROVED_ADMIN') self.session.flush() transaction.commit() data['autoaccept'] = True async_result = subtask(WorkerApproved).delay(data=data) self.log.info('task scheduled %r' % async_result)
def render(self): req_id = self.request.params.get('request_id') req = Request.by_id(self.session, req_id) if not req: return '' # check if request have already been consumed if not self.user.is_admin: today = datetime.now() if req.date_from <= today: log.error('User %s tried to CANCEL consumed request %d.' % (self.user.login, req.id)) return req.status # delete from calendar if req.status == 'APPROVED_ADMIN' and req.ics_url: settings = self.request.registry.settings with open(settings['pyvac.celery.yaml']) as fdesc: Conf = yaml.load(fdesc, YAMLLoader) caldav_url = Conf.get('caldav').get('url') delFromCal(caldav_url, req.ics_url) RequestHistory.new(self.session, req, req.status, 'CANCELED', self.user) req.update_status('CANCELED') # save who performed this action req.last_action_user_id = self.user.id self.session.flush() return req.status
def render(self): from datetime import datetime today = datetime.now() end_date = datetime(today.year, 10, 31) previsions = Request.get_previsions(self.session, end_date) users_per_id = dict([(user.id, user) for user in User.find(self.session)]) settings = self.request.registry.settings use_ldap = False if 'pyvac.use_ldap' in settings: use_ldap = asbool(settings.get('pyvac.use_ldap')) user_attr = {} users_teams = {} if use_ldap: # synchronise user groups/roles User.sync_ldap_info(self.session) ldap = LdapCache() user_attr = ldap.get_users_units() users_teams = {} for team, members in ldap.list_teams().iteritems(): for member in members: users_teams.setdefault(member, []).append(team) return {'users_per_id': users_per_id, 'use_ldap': use_ldap, 'ldap_info': user_attr, 'users_teams': users_teams, 'previsions': previsions, 'today': today, 'end_date': end_date, }
def render(self): req_id = self.request.params.get('request_id') req = Request.by_id(self.session, req_id) if not req: return '' # check if request have already been consumed if not self.user.is_admin: today = datetime.now() if req.date_from <= today: log.error('User %s tried to CANCEL consumed request %d.' % (self.user.login, req.id)) return req.status # delete from calendar if req.status == 'APPROVED_ADMIN' and req.ics_url: settings = self.request.registry.settings with open(settings['pyvac.celery.yaml']) as fdesc: Conf = yaml.load(fdesc, YAMLLoader) caldav_url = Conf.get('caldav').get('url') delFromCal(caldav_url, req.ics_url) req.update_status('CANCELED') # save who performed this action req.last_action_user_id = self.user.id self.session.flush() return req.status
def process(self, data): """ submitted by user send mail to manager """ req = Request.by_id(self.session, data['req_id']) # send mail to manager src = req.user.email dst = req.user.manager_mail if 'reminder' in data: content = """A request from %s is still waiting your approval Request details: %s""" % (req.user.name, req.summarymail) else: content = """New request from %s Request details: %s""" % (req.user.name, req.summarymail) try: self.send_mail(sender=src, target=dst, request=req, content=content) # update request status after sending email req.notified = True except Exception as err: self.log.exception('Error while sending mail') req.flag_error(str(err), self.session) self.session.flush() transaction.commit()
def test_all_for_admin(self): from pyvac.models import Request with freeze_time('2014-12-25', ignore=['celery', 'psycopg2', 'sqlalchemy', 'icalendar']): nb_requests = Request.all_for_admin(self.session, count=True) self.assertEqual(nb_requests, 17)
def get_conflict_by_teams(self, requests, users_teams): """ Returns requests conflicts by teams """ conflicts = {} for req in requests: user_teams = users_teams.get(req.user.dn, []) matched = {} # for all requests in conflict with current req for req2 in Request.in_conflict(self.session, req): # if we have some match between request teams # and conflicting request teams conflict_teams = users_teams.get(req2.user.dn, []) common_set = set(conflict_teams) & set(user_teams) if common_set: for team in common_set: if team not in matched: matched[team] = [] matched[team].append(req2.summary) req.conflict = matched if req.conflict: for team in req.conflict: if req.id not in conflicts: conflicts[req.id] = {} conflicts[req.id][team] = ('\n'.join([team] + req.conflict[team])) return conflicts
def process(self, data): """ denied by last_action_user_id send mail to user """ req = Request.by_id(self.session, data['req_id']) # retrieve user who performed last action action_user = User.by_id(self.session, req.last_action_user_id) # send mail to user src = action_user.email dst = req.user.email content = """You request has been refused for the following reason: %s Request details: %s""" % (req.reason, req.summarymail) try: self.send_mail(sender=src, target=dst, request=req, content=content) # update request status after sending email req.notified = True except Exception as err: self.log.exception('Error while sending mail') req.flag_error(str(err)) self.session.flush() transaction.commit()
def test_by_status(self): from pyvac.models import Request requests = Request.by_status(self.session, u'PENDING') self.assertEqual(len(requests), 4) # take the first request = requests[0] self.assertIsInstance(request, Request)
def test_summarycsv(self): from pyvac.models import Request req = Request.by_id(self.session, 1) self.assertIsInstance(req, Request) msg = u"Doe,John,10/04/2015,14/04/2015,5.0,CP," self.assertEqual(req.summarycsv, msg)
def render(self): from datetime import datetime today = datetime.now() end_date = datetime(today.year, 10, 31) previsions = Request.get_previsions(self.session, end_date) users_per_id = dict([(user.id, user) for user in User.find(self.session)]) settings = self.request.registry.settings use_ldap = False if 'pyvac.use_ldap' in settings: use_ldap = asbool(settings.get('pyvac.use_ldap')) user_attr = {} users_teams = {} if use_ldap: # synchronise user groups/roles User.sync_ldap_info(self.session) ldap = LdapCache() user_attr = ldap.get_users_units() users_teams = {} for team, members in list(ldap.list_teams().items()): for member in members: users_teams.setdefault(member, []).append(team) return {'users_per_id': users_per_id, 'use_ldap': use_ldap, 'ldap_info': user_attr, 'users_teams': users_teams, 'previsions': previsions, 'today': today, 'end_date': end_date, }
def test_get_by_month(self): from pyvac.models import Request month = 8 year = 2011 country = u'fr' requests = Request.get_by_month(self.session, country, month, year) self.assertEqual(len(requests), 1)
def process(self, data): """ accepted by manager send mail to user send mail to HR """ req = Request.by_id(self.session, data['req_id']) # send mail to user src = req.user.manager_mail dst = req.user.email content = """Your request has been accepted by %s. Waiting for HR validation. Request details: %s""" % (req.user.manager_name, req.summarymail) try: self.send_mail(sender=src, target=dst, request=req, content=content) # send mail to HR admin = req.user.get_admin(self.session) dst = self.get_admin_mail(admin) content = """Manager %s has accepted a new request. Waiting for your validation. Request details: %s""" % (req.user.manager_name, req.summarymail) self.send_mail(sender=src, target=dst, request=req, content=content) # update request status after sending email req.notified = True except Exception as err: self.log.exception('Error while sending mail') req.flag_error(str(err)) self.session.flush() transaction.commit()
def test_all_for_admin(self): from pyvac.models import Request with freeze_time('2014-12-25', ignore=['celery', 'psycopg2', 'sqlalchemy', 'icalendar']): nb_requests = Request.all_for_admin(self.session, count=True) self.assertEqual(nb_requests, 19)
def test_summarycsv_label(self): from pyvac.models import Request req = Request.by_id(self.session, 6) self.assertIsInstance(req, Request) msg = u"Doe,John,24/08/2011,24/08/2011,0.5,RTT,AM" self.assertEqual(req.summarycsv, msg)
def process(self, data): """ submitted by user send mail to manager """ req = Request.by_id(self.session, data['req_id']) # send mail to manager src = req.user.email dst = req.user.manager_mail if 'reminder' in data: content = """A request from %s is still waiting your approval Request details: %s""" % (req.user.name, req.summarymail) else: content = """New request from %s Request details: %s""" % (req.user.name, req.summarymail) try: self.send_mail(sender=src, target=dst, request=req, content=content) # update request status after sending email req.notified = True except Exception as err: self.log.exception('Error while sending mail') req.flag_error(str(err)) self.session.flush() transaction.commit()
def render(self): req_id = self.request.params.get('request_id') req = Request.by_id(self.session, req_id) if not req: return '' reason = self.request.params.get('reason') req.reason = reason RequestHistory.new(self.session, req, req.status, 'DENIED', self.user, reason=reason) req.update_status('DENIED') # save who performed this action req.last_action_user_id = self.user.id self.session.flush() # call celery task directly, do not wait for polling from celery.registry import tasks from celery.task import subtask req_task = tasks['worker_denied'] data = {'req_id': req.id} subtask(req_task).apply_async(kwargs={'data': data}, countdown=5) log.info('scheduling task worker_denied for %s' % data) return req.status
def process(self, data): """ denied by last_action_user_id send mail to user """ req = Request.by_id(self.session, data['req_id']) # retrieve user who performed last action action_user = User.by_id(self.session, req.last_action_user_id) # send mail to user src = action_user.email dst = req.user.email content = """Your request has been refused for the following reason: %s Request details: %s""" % (req.reason, req.summarymail) try: self.send_mail(sender=src, target=dst, request=req, content=content) # update request status after sending email req.notified = True except Exception as err: self.log.exception('Error while sending mail') req.flag_error(str(err), self.session) self.session.flush() transaction.commit()
def process(self, data): """ accepted by manager send mail to user send mail to HR """ req = Request.by_id(self.session, data['req_id']) # send mail to user src = req.user.manager_mail dst = req.user.email content = """Your request has been accepted by %s. Waiting for HR validation. Request details: %s""" % (req.user.manager_name, req.summarymail) try: self.send_mail(sender=src, target=dst, request=req, content=content) # send mail to HR admin = req.user.get_admin(self.session) dst = self.get_admin_mail(admin) content = """Manager %s has accepted a new request. Waiting for your validation. Request details: %s""" % (req.user.manager_name, req.summarymail) self.send_mail(sender=src, target=dst, request=req, content=content) # update request status after sending email req.notified = True except Exception as err: self.log.exception('Error while sending mail') req.flag_error(str(err), self.session) self.session.flush() transaction.commit()
def run(self, *args, **kwargs): self.log = log # init database connection session = DBSession() req_accepted_notified = Request.by_status(session, 'ACCEPTED_MANAGER', notified=True) self.log.info('number of ACCEPTED_NOTIFIED requests: %d' % len(req_accepted_notified)) req_list = [] req_list.extend(req_accepted_notified) for req in req_list: self.log.info('selecting task for req type %r' % req.status) check_status = req.status if req.status == 'ACCEPTED_MANAGER' and req.notified: check_status = 'ACCEPTED_NOTIFIED' req_task = self.worker_tasks[check_status] self.log.info('task selected %r' % req_task.name) data = { 'req_id': req.id, } async_result = subtask(req_task).delay(data=data) self.log.info('task scheduled %r' % async_result) return True
def test_summarycsv_message(self): from pyvac.models import Request req = Request.by_id(self.session, 14) self.assertIsInstance(req, Request) msg = (u"Doe,Jane,13/06/2016,13/06/2016,1.0,Exceptionnel,," "I need to see Star Wars, I'm a huge fan") self.assertEqual(req.summarycsv, msg)
def render(self): req_id = self.request.params.get('request_id') req = Request.by_id(self.session, req_id) if not req: return '' data = {'req_id': req.id} if self.user.is_admin: req.update_status('APPROVED_ADMIN') # save who performed this action req.last_action_user_id = self.user.id task_name = 'worker_approved' settings = self.request.registry.settings with open(settings['pyvac.celery.yaml']) as fdesc: Conf = yaml.load(fdesc, YAMLLoader) data['caldav.url'] = Conf.get('caldav').get('url') else: req.update_status('ACCEPTED_MANAGER') # save who performed this action req.last_action_user_id = self.user.id task_name = 'worker_accepted' self.session.flush() # call celery task directly, do not wait for polling from celery.registry import tasks from celery.task import subtask req_task = tasks[task_name] subtask(req_task).delay(data=data) return req.status
def test_by_manager(self): from pyvac.models import User, Request manager1 = User.by_login(self.session, u'manager1') requests = Request.by_manager(self.session, manager1) self.assertEqual(len(requests), 2) # take the first request = requests.pop() self.assertIsInstance(request, Request)
def test_post_send_cp_lu_half_ok(self): self.config.testing_securitypolicy(userid=u'sarah.doe', permissive=True) from pyvac.models import Request from pyvac.views.request import Send total_req = Request.find(self.session, count=True) request = self.create_request({ 'days': 0.5, 'date_from': '17/10/2016 - 17/10/2016', 'type': '1', 'breakdown': 'AM', }) view = Send(request)() self.assertIsRedirect(view) self.assertEqual(Request.find(self.session, count=True), total_req + 1) last_req = Request.find(self.session)[-1] self.assertEqual(last_req.days, 4.0)
def test_post_send_vacation_type_visibility_ko(self): self.config.testing_securitypolicy(userid=u'janedoe', permissive=True) from pyvac.models import Request from pyvac.views.request import Send total_req = Request.find(self.session, count=True) request = self.create_request({'days': 1, 'date_from': '05/05/2015 - 05/05/2015', 'type': '5', 'breakdown': 'FULL', }) view = Send(request)() self.assertIsRedirect(view) # no new requests were made self.assertEqual(Request.find(self.session, count=True), total_req) expected = [u'error;You are not allowed to use type: Maladie'] self.assertEqual(request.session.pop_flash(), expected)
def process(self, data): """ approved by HR send mail to user send mail to manager """ req = Request.by_id(self.session, data['req_id']) admin = req.user.get_admin(self.session) # send mail to user src = self.get_admin_mail(admin) dst = req.user.email if 'autoaccept' in data: content = """Your request was automatically approved, it has been added to calendar. Request details: %s""" % req.summarymail else: content = """HR has accepted your request, it has been added to calendar. Request details: %s""" % req.summarymail try: self.send_mail(sender=src, target=dst, request=req, content=content) # send mail to manager src = self.get_admin_mail(admin) dst = req.user.manager_mail if 'autoaccept' in data: content = """A request you accepted was automatically approved, it has been added to calendar. Request details: %s""" % req.summarymail else: content = """HR has approved a request you accepted, it has been added to calendar. Request details: %s""" % req.summarymail self.send_mail(sender=src, target=dst, request=req, content=content) # update request status after sending email req.notified = True except Exception as err: log.exception('Error while sending mail') req.flag_error(str(err)) try: if 'caldav.url' in data: caldav_url = data['caldav.url'] else: conf_file = sys.argv[1] with open(conf_file) as fdesc: Conf = yaml.load(fdesc, YAMLLoader) caldav_url = Conf.get('caldav').get('url') # add new entry in caldav addToCal(caldav_url, req.date_from, req.date_to, req.summarycal) except Exception as err: log.exception('Error while adding to calendar') req.flag_error(str(err)) self.session.flush() transaction.commit()
def render(self): def fmt_req_type(req): label = ' %s' % req.label if req.label else '' return '%s%s' % (req.type, label) filter_nick = self.request.params.get('nick') filter_name = self.request.params.get('name') filter_date = self.request.params.get('date') # strict if provided will disable partial search for nicknames strict = self.request.params.get('strict') # remove unwanted chars from filter_date if filter_date: filter_date = re.sub('[^\d+]', '', filter_date) if filter_nick: # retrieve all availables nicknames all_nick = [nick.lower() for nick in User.get_all_nicknames(self.session)] if strict: match = filter_nick.lower() in all_nick else: match = set([nick for nick in all_nick if filter_nick.lower() in nick.lower()]) if not match: # filter_nick does not match any known uid, stop here return JsonHTTPNotFound({'message': ('%s not found' % filter_nick)}) requests = Request.get_active(self.session, filter_date) data_name = dict([(req.user.name.lower(), fmt_req_type(req)) for req in requests]) data_nick = dict([(req.user.nickname, fmt_req_type(req)) for req in requests]) ret = val = None if filter_nick: val = data_nick.get(filter_nick.lower()) if val: ret = {filter_nick: val} elif not strict: val = dict([(k, v) for k, v in data_nick.items() if filter_nick.lower() in k]) return val else: return {} if filter_name: val = data_name.get(filter_name.lower()) if val: ret = {filter_name: val} else: val = dict([(k, v) for k, v in data_name.items() if filter_name.lower() in k]) return val return ret if ret else data_name
def test_post_send_vacation_type_visibility_ok(self): self.config.testing_securitypolicy(userid=u'admin', permissive=True) from pyvac.models import Request from pyvac.views.request import Send total_req = Request.find(self.session, count=True) request = self.create_request({'days': 1, 'date_from': '05/05/2015 - 05/05/2015', 'type': '5', 'breakdown': 'FULL', 'sudo_user': -1, }) view = Send(request)() self.assertIsRedirect(view) self.assertEqual(Request.find(self.session, count=True), total_req + 1) last_req = Request.find(self.session)[-1] self.assertEqual(last_req.type, u'Maladie') self.delete_last_req(last_req)
def test_post_send_half_day_other_half_ok(self): self.config.testing_securitypolicy(userid=u'jdoe', permissive=True) from pyvac.models import Request from pyvac.views.request import Send total_req = Request.find(self.session, count=True) with freeze_time('2011-07-14', ignore=['celery', 'psycopg2', 'sqlalchemy', 'icalendar']): request = self.create_request({ 'days': 0.5, 'date_from': '24/08/2011 - 24/08/2011', 'type': '1', 'breakdown': 'PM', }) view = Send(request)() self.assertIsRedirect(view) self.assertEqual(Request.find(self.session, count=True), total_req + 1)