def next_monthly_interval(self, interval, occurrence=None): now = current_timestamp() if not occurrence: occurrence = now candidate = occurrence.replace(day=1, hour=0, minute=1) current_month_threshold = now.replace(day=1, hour=0, minute=0) while candidate < current_month_threshold: candidate = advance_by_month(candidate, interval) next = self.next(candidate) if next < now + timedelta(minutes=1): next = self.next(advance_by_month(candidate, interval)) return next
def next(self, occurrence=None): if not occurrence: occurrence = current_timestamp() occurrence = occurrence.replace(second=0, microsecond=0) if self._check_date(occurrence): candidate = self._next_time(occurrence) if candidate: return candidate occurrence = occurrence.replace(hour=0, minute=0) while True: occurrence += timedelta(days=1) if self._check_date(occurrence): candidate = self._next_time(occurrence) if candidate: return candidate
def next_weekly_interval(self, interval, occurrence=None): now = current_timestamp() if not occurrence: occurrence = now if occurrence > now and self._check_date(occurrence): if occurrence.hour in self.hour and occurrence.minute in self.minute: return occurrence week = Week.from_date(occurrence) candidate = self.next(occurrence + timedelta(minutes=1)) if candidate in week and candidate > now: return candidate candidate = datetime.combine(week.start, time(0, 0, 0)).replace( tzinfo=occurrence.tzinfo) while now > candidate: candidate = advance_by_week(candidate, interval) week = Week.from_date(candidate) if now in week: candidate = now break return self.next(candidate)
def timestamp(): return current_timestamp().strftime('%Y%m%d%H%M%S')
def now(format='%Y-%m-%d %H:%M:%S %Z'): return current_timestamp().strftime(format)
def timestamp(): return current_timestamp().strftime('%Y%m%d%H%M%S')
def now(format='%Y-%m-%d %H:%M:%S %Z'): return current_timestamp().strftime(format)
def send_audit_data(self, request, response, subject, data, add_params): ''' :param request: object containing http request data :type request: Http request :param response: response object which contains status information :type response: Http response :param subject: object for which a change should be audited :type subject: subtype of Model :param data: contains the request payload :type data: dictionary :param add_params: additional parameters for processing, set by the calling method, e.g. add_params['optype']=OPTYPE_USER_CREATE :type add_params: ''' # first check, whether auditing is configured for the given # controller at all! if not self.is_audit_enabled(): log('info','auditing is DISABLED') return if not self.needs_audit(request, subject): log('info','auditing for this request is NOT enabled') return event_details = {} event_payload = {} add_params = add_params or {} audit_data = { AUDIT_ATTR_EVENT_DATE: current_timestamp(), AUDIT_ATTR_DETAILS: event_details, AUDIT_ATTR_PAYLOAD: event_payload, } # create a default correlation id, which may or may not be overwritten # by each controller. audit_data[AUDIT_ATTR_CORRELATION_ID]= str(uuid.uuid4()) # extract audit relevant details actor_id = request.context.get('user-id', '') method = request.headers['REQUEST_METHOD'] status = response.status or OK audit_data[AUDIT_ATTR_ORIGIN] = self._get_origin(request.headers) if method == DELETE: if subject: if data: data.update(subject.extract_dict()) else : # data is None if this method is called by "delete user" method data = subject.extract_dict() if method == POST and request.subject: # a POST request passing the subject's id, should normally rather be a PUT request # so translate that, accordingly method = PUT if method == 'TASK': # if the request was submitted by an automated task, # we expect to find the actual op in data method = add_params.pop('task_op', POST) taskname = add_params.get('task','') actor_detail = { ACTOR_DETAIL_USERNAME: ACTOR_SYSTEM, ACTOR_DETAIL_FIRSTNAME: 'automated-task', ACTOR_DETAIL_LASTNAME: taskname, ACTOR_DETAIL_EMAIL: '' } audit_data[AUDIT_ATTR_ACTOR] = actor_detail if data: self.validate_payload(data) event_payload.update(data) if subject is None: if status == OK and response.content and 'id' in response.content: add_params['id'] = response.content.get('id') else: if request.subject : ## if this method is called for delete then there is no subject and the object id is ## available only via request.subject where request.subject is a string like ## str: b8dc6fa8-cd70-4927-bcb1-5a4571ececd7 ## try: uuid.UUID(request.subject) add_params['id'] = request.subject except Exception as e : log('exception', e) pass else: try: add_params['id'] = subject.id except AttributeError: pass if actor_id != '': audit_data[AUDIT_ATTR_ACTOR_ID] = actor_id ## in case of an exception in credentialreset there is no value for logon ## user and we must check the request header for information on origin ## BUT the polymorphic prepare routines gets no request object if actor_id == '' : add_params['x-forwarded-for']= request.context.get('x-forwarded-for','unknown') if status == OK: audit_data[AUDIT_ATTR_RESULT] = REQ_RESULT_SUCCESS else: audit_data[AUDIT_ATTR_RESULT] = REQ_RESULT_FAILED self._prepare_audit_data(method, status, subject, audit_data, add_params) self._create_audit_event(audit_data)
def send_authorization_audit(self, user_id, environ, success ): if not self.is_audit_enabled(): log('info','auditing is DISABLED') return if not self.is_audit_enabled_for(AuditConfigParms.AUDIT_AUTH): log('info', 'auditing for login/logout is NOT enabled.') return event_details = {} event_payload = {} actor_detail = {} audit_data = { AUDIT_ATTR_EVENT_DATE: current_timestamp(), AUDIT_ATTR_DETAILS: event_details, AUDIT_ATTR_PAYLOAD: event_payload, AUDIT_ATTR_EVENT_CATEGORY: CATEGORY_AUTHENTICATION } audit_data[AUDIT_ATTR_ORIGIN] = self._get_origin(environ) context = environ['request.context'] close_session = context.get('close-session','false') if close_session == 'true': audit_data[AUDIT_ATTR_OPTYPE] = OPTYPE_LOGOUT else: audit_data[AUDIT_ATTR_OPTYPE] = OPTYPE_LOGIN correlation_id = str(uuid.uuid4()) audit_data[AUDIT_ATTR_CORRELATION_ID]= correlation_id if success: audit_data[AUDIT_ATTR_RESULT] = REQ_RESULT_SUCCESS else: audit_data[AUDIT_ATTR_RESULT] = REQ_RESULT_FAILED if user_id is not None: audit_data[AUDIT_ATTR_ACTOR_ID] = user_id else: username = context.get(CONTEXT_CREDENTIAL_USERNAME, '') actor_detail = { ACTOR_DETAIL_USERNAME: username, ACTOR_DETAIL_FIRSTNAME: '', ACTOR_DETAIL_LASTNAME: '', ACTOR_DETAIL_EMAIL: '' } audit_data[AUDIT_ATTR_ACTOR] = actor_detail event_details['type'] = 'authentication' event_details['source_ip'] = context.get('x-forwarded-for','') event_details['target_host'] = environ.get('HTTP_HOST','') credtype = context.get(CONTEXT_CREDENTIAL_TYPE) if credtype is not None: if credtype == 'password': event_details['method'] = AUTHENTICATION_METHOD_LOCAL else: event_details['method'] = AUTHENTICATION_METHOD_LDAP #_debug('+send_audit_data - audit record', str(audit_data)) # insert rest call to SIQ Audit here! # assume that failure to create/write the audit event will throw an exception # which we'll deliberately NOT catch, here! self._create_audit_event(audit_data) return correlation_id