class DependencyProviderTest(unittest.TestCase): def setUp(self): self._provider = DependencyProvider() def get_instance_test(self): # test normal behavior - test dao = self._provider.get_instance('EventDao') self.assertEqual(dao.__module__ + '.' + dao.__class__.__name__, 'test.classes.event_dao.EventDao') _filter = self._provider.get_instance('UserFilter') self.assertEqual(_filter.__module__ + '.' + _filter.__class__.__name__, 'test.classes.user_filter.UserFilter')
class UserFilter(): def __init__(self): # retrieve dependencies based on environment self.__provider = DependencyProvider() self.__attendee_dao = self.__provider.get_instance('AttendeeDao') self.__attendeeValidator = AttendeeValidator() def __create_new_user(self, req_body): attendee_name = '' try: if 'creator' in req_body: attendee_name = req_body['creator'] elif 'name' in req_body: attendee_name = req_body['name'] except Exception as e: raise ValidationException('Payload was not found in this request') else: if not attendee_name: raise ValidationException( 'Name for this user could not be located') # create a new user with the provided name self.__attendeeValidator.validate_attendee_name(attendee_name) att = self.__attendee_dao.save_attendee({'name': attendee_name}) # return the attendee object return att def set_user_id(self, req): ''' Checks if user_id cookie is in the request. Creates a new user if not. ''' try: # check if cookies were sent with this request cookies = req.req_body['cookies'] # Check if user_id cookie was sent with the request if cookies['user_id']: # validate the ID self.__attendeeValidator.validate_attendee_id( cookies['user_id']) # if the id exists in the DB, return the request unchanged if self.__attendee_dao.attendee_exists(cookies['user_id']): return req else: # ID not in database. Create new user and overwrite cookie att = self.__create_new_user(req.json_body) req.cookies['user_id'] = att['id'] return req else: # if not, create new user and attach user_id cookie att = self.__create_new_user(req.json_body) req.cookies['user_id'] = att['id'] except Exception as e: # if not, create new user and attach user_id cookie att = self.__create_new_user(req.json_body) req.cookies['user_id'] = att['id'] return req
class BaseDao(): def __init__(self): self.__provider = DependencyProvider() self.__psycopg2 = self.__provider.get_instance('psycopg2') try: db_conn_str = 'dbname=' + os.environ['DB_NAME'] conn = self.__psycopg2.connect(db_conn_str) self._cur = conn.cursor() except ImportError: print(ImportError) except: print(sys.exc_info()) print('I am unable to connect to the database')
from pyramid.view import view_config from pyramid.response import Response from pyramid.httpexceptions import HTTPBadRequest from pyramid.httpexceptions import HTTPNotFound from pyramid.httpexceptions import HTTPInternalServerError from classes.exception.base_app_exception import BaseAppException from classes.provider.dependency_provider import DependencyProvider from classes.service.attendee_service import AttendeeService from classes.exception.dao_exception import DaoException from classes.util.event_validator import EventValidator from classes.service.event_service import EventService from classes.util.hash_utils import HashUtils # init DAOs based on environment __provider = DependencyProvider() __user_filter = __provider.get_instance('UserFilter') __event_service = EventService() __attendee_service = AttendeeService() def post_event(request): ''' Get data for a specific event by ID. This returns the event object, populated by all date range objects ''' try: filtered_request = __user_filter.set_user_id(request) response = __event_service.create_event(filtered_request) except BaseAppException as e: response = HTTPBadRequest()
class AttendeeService: def __init__ (self): # init DAOs based on environment self.__provider = DependencyProvider() self.__event_dao = self.__provider.get_instance('EventDao') self.__attendee_dao = self.__provider.get_instance('AttendeeDao') self.__availability_dao = self.__provider.get_instance('AvailabilityDao') self.__eventValidator = EventValidator() self.__attendeeValidator = AttendeeValidator() def load_attendee (self, req): ''' returns JSON data of this single attendee ''' try: # validate att_id = req.matchdict['attendee_id'] if att_id is None: raise ServiceException('Id was not found on this request') self.__attendeeValidator.validate_attendee_id( att_id ) data = self.__attendee_dao.load_attendee(att_id) response = Response(content_type='application/json', status=200) response.charset = 'UTF-8' response.json_body = json.dumps(data) except BaseAppException as e: raise ServiceException(str(e)) except Exception as e: print(e, sys.exc_info()) raise ServiceException( 'An error occurred while loading attendee with id', att_id ) return response def update_attendee (self, req): ''' Updates an attendee's details such as name or email address ''' try: if 'id' not in req.json_body: raise ServiceException('Id was not found on this request') self.__attendeeValidator.validate_attendee_request(req) data = self.__attendee_dao.update_attendee(req.json_body) response = Response(content_type='application/json', status=200) response.charset = 'UTF-8' response.json_body = json.dumps(data) except BaseAppException as e: # Handle DAO/Validation errors raise ServiceException(str(e)) except Exception as e: # Handle unexpected errors print(e, sys.exc_info()) raise ServiceException( 'An error occurred while updating your info.' ) return response def update_attendee_availability (self, req): ''' TODO ? Updates the availability of an attendee ''' try: # TODO validate availability self.__attendeeValidator.validate_attendee_request(req) data = self.__availability_dao.update_availability(req.json_body) response = Response(content_type='application/json', status=200) response.charset = 'UTF-8' response.json_body = json.dumps(data) except BaseAppException as e: # Handle DAO/Validation errors raise ServiceException(str(e)) except Exception as e: # Handle unexpected errors print(e, sys.exc_info()) raise ServiceException( 'An error occurred while updating availability.' ) return response def load_event_attendees (self, req): ''' Returns a JSON list of all attendees in this event ''' try: # validate the event id eventId = req.matchdict['eventId'] self.__eventValidator.validate_event_id(eventId) # load the attendee list data = self.__attendee_dao.load_event_attendees(eventId) # build response object response = Response(content_type='application/json', status=200) response.charset = 'UTF-8' response.json_body = json.dumps(data) except BaseAppException as e: # Handle DAO/Validation errors raise ServiceException(str(e)) except Exception as e: # Handle unexpected errors print(e, sys.exc_info()) raise ServiceException( 'An error occurred while retrieving attendee list.' ) return response def create_attendee (self, req): ''' Create and attendee and join the target event. ''' try: # validate event ID and attendee payload eventId = req.matchdict['eventId'] self.__eventValidator.validate_event_id(eventId) self.__attendeeValidator.validate_attendee_request(req) # create the attendee and join the event data = self.__attendee_dao.save_attendee(req.json_body) self.__attendee_dao.join_event(data['id'], eventId) # build the response body response = Response(content_type='application/json', status=200) response.charset = 'UTF-8' response.json_body = json.dumps(data) except BaseAppException as e: raise ServiceException(str(e)) except Exception as e: print(e, sys.exc_info()) raise ServiceException('An error occurred while creating this event.') return response def remove_attendee_from_event (self, req): try: att_id = req.json_body['id'] event_id = req.matchdict['eventId'] self.__attendeeValidator.validate_attendee_id(att_id) self.__eventValidator.validate_event_id(event_id) data = self.__attendee_dao.delete_attendee(att_id, event_id) except BaseAppException as e: raise ServiceException(str(e)) except Exception as e: print(e, sys.exc_info()) raise ServiceException('An error occurred while creating this event.') return Response(status=200) def add_attendee_to_event (self, req): try: self.__attendeeValidator.validate_attendee_request(req) data = self.__attendee_dao.join_event( req.json_body['id'], req.matchdict['eventId'] ) except BaseAppException as e: raise ServiceException(str(e)) except Exception as e: print(e, sys.exc_info()) raise ServiceException('An error occurred while creating this event.') return Response(status=200)
class EventService: def __init__(self): # init DAOs based on environment self.__provider = DependencyProvider() self.__event_dao = self.__provider.get_instance('EventDao') self.__attendee_dao = self.__provider.get_instance('AttendeeDao') self.__availability_dao = self.__provider.get_instance( 'AvailabilityDao') self.__eventValidator = EventValidator() self.__attendeeValidator = AttendeeValidator() def load_event(self, req): try: # validate eventId = req.matchdict['eventId'] self.__eventValidator.validate_event_id(eventId) data = self.__event_dao.load_event(eventId) response = Response(content_type='application/json', status=200) response.charset = 'UTF-8' response.json_body = json.dumps(data) except BaseAppException as e: raise ServiceException(str(e)) except Exception as e: print(e, sys.exc_info()) raise ServiceException( 'An error occurred while loading this event.') return response def update_event(self, req): try: payload = req.json_body self.__eventValidator.validate_event(payload) data = self.__event_dao.update_event(payload) response = Response(content_type='application/json', status=200) response.charset = 'UTF-8' response.json_body = json.dumps(data) except BaseAppException as e: raise ServiceException(str(e)) except Exception as e: print(e, sys.exc_info()) raise ServiceException( 'An error occurred while updating this event.') return response def create_event(self, req): ''' Creates a new event. Validates the request object, extracts all required information, and builds the event and associated objects. ''' # TODO year mechanism. try: inputErrors = self.__eventValidator.validate_event(req.json_body) response_body = {} if not inputErrors: # set the creator_id and save the event req.json_body['creator_id'] = req.cookies['user_id'] data = self.__event_dao.save_event(req.json_body) # build the response body response_body = json.dumps(data) else: response_body = json.dumps(inputErrors) response = Response(content_type='application/json', status=200) response.charset = 'UTF-8' response.json_body = response_body except BaseAppException as e: raise ServiceException(str(e)) except Exception as e: print(e, sys.exc_info()) raise ServiceException( 'An error occurred while creating this event.') return response def delete_event(self, req): try: # validate event ID eventId = req.matchdict['eventId'] inputErrors = self.__eventValidator.validate_event_id(eventId) # make sure this user is the creator user_id = req.cookies['user_id'] event = self.__event_dao.load_event(eventId) # delete event if so if event['creator_id'] == user_id: self.__event_dao.delete_event(eventId) else: raise ServiceException( 'Only the creator cannot delete this event') except BaseAppException as e: raise ServiceException(str(e)) return Response(status=200) def delete_event_attendee(self, req): try: eventId = req.matchdict['eventId'] attendee_id = req.matchdict['attendee_id'] self.__eventValidator.validate_event_id(eventId) self.__attendeeValidator.validate_attendee_id(attendee_id) if req.cookies['user_id'] == attendee_id: # user is leaving this event self.__attendee_dao.leave_event(attendee_id, eventId) else: # check if this is the event creator event = self.__event_dao.load_event(eventId) if req.cookies['user_id'] == event['creator_id']: self.__attendee_dao.leave_event(attendee_id, eventId) else: # neither creator or the target user raise ServiceException( 'Only the creator can remove other users from an event' ) except BaseAppException as e: # Handle DAO/Validation errors raise ServiceException(str(e)) except Exception as e: # Handle unexpected errors print(e, sys.exc_info()) raise ServiceException( 'An error occurred while leaving this info.') return Response(status=200)
class AvailabilityValidator: def __init__(self): # init DAOs based on environment self.__provider = DependencyProvider() self.__event_dao = self.__provider.get_instance('EventDao') self.__attendee_dao = self.__provider.get_instance('AttendeeDao') self.__availability_dao = self.__provider.get_instance( 'AvailabilityDao') # init other validators self.__event_validator = EventValidator() self.__attendee_validator = AttendeeValidator() # init field validation info self.__availability_id_pattern = r'^[\w\d\s-]+$' self.__id_field = { 'name': 'id', 'pattern': r'^[\w\d\s-]+$', 'error_message': 'ID field must contain only numbers or letters.' } self.__year_field = { 'name': 'year', 'pattern': r'2[0-9]{3}', 'error_message': 'Year must start with 2 and be 4 digits long.' } base_err_string = ( '{0} field must have length {1} and only contain 0-3.') self.__january_field = { 'name': 'january', 'pattern': r'[0-3]{31}', 'error_message': base_err_string.format('January', 31) } self.__february_field = { 'name': 'february', 'pattern': r'[0-3]{28}', 'error_message': base_err_string.format('February', 28) } self.__february_leap_field = { 'name': 'february', 'pattern': r'[0-3]{29}', 'error_message': 'On leap years, Feburary must be 2 characters and only contain values 0-3' } self.__march_field = { 'name': 'march', 'pattern': r'[0-3]{31}', 'error_message': base_err_string.format('March', 31) } self.__april_field = { 'name': 'april', 'pattern': r'[0-3]{30}', 'error_message': base_err_string.format('April', 30) } self.__may_field = { 'name': 'may', 'pattern': r'[0-3]{31}', 'error_message': base_err_string.format('May', 31) } self.__june_field = { 'name': 'june', 'pattern': r'[0-3]{30}', 'error_message': base_err_string.format('June', 30) } self.__july_field = { 'name': 'july', 'pattern': r'[0-3]{31}', 'error_message': base_err_string.format('July', 31) } self.__august_field = { 'name': 'august', 'pattern': r'[0-3]{31}', 'error_message': base_err_string.format('August', 31) } self.__september_field = { 'name': 'september', 'pattern': r'[0-3]{30}', 'error_message': base_err_string.format('September', 30) } self.__october_field = { 'name': 'october', 'pattern': r'[0-3]{31}', 'error_message': base_err_string.format('October', 31) } self.__november_field = { 'name': 'novomber', 'pattern': r'[0-3]{30}', 'error_message': base_err_string.format('November', 30) } self.__december_field = { 'name': 'december', 'pattern': r'[0-3]{31}', 'error_message': base_err_string.format('December', 31) } # define general error self.__empty_value_message = '{0} is blank. A value for {0} is required.' def validate_availability_request(self, req): error_messages = [] try: # if POST or PUT validate the ID if (req.method == 'POST' or req.method == 'PUT'): av_id = req.matchdict['availability_id'] if av_id: self.validate_availability_id(av_id) else: error_messages.append( self.__empty_value_message.format('availability_id')) # validate attendee id if 'attendee_id' in req.json_body: self.__attendee_validator.validate_attendee_id( req.json_body['attendee_id']) else: error_messages.append( self.__empty_value_message.format('attendee_id')) # validate event ID if 'event_id' in req.json_body: self.__event_validator.validate_event_id( req.json_body['event_id']) else: error_messages.append( self.__empty_value_message.format('event_id')) # validate year self.validate_field(self.__year_field, req.json_body['year']) # validate january self.validate_field(self.__january_field, req.json_body['january']) # validate february self.validate_field(self.__february_field, req.json_body['february']) # validate march self.validate_field(self.__march_field, req.json_body['march']) # validate april self.validate_field(self.__april_field, req.json_body['april']) # validate may self.validate_field(self.__may_field, req.json_body['may']) # validate june self.validate_field(self.__june_field, req.json_body['june']) # validate july self.validate_field(self.__july_field, req.json_body['july']) # validate august self.validate_field(self.__august_field, req.json_body['august']) # validate september self.validate_field(self.__september_field, req.json_body['september']) # validate october self.validate_field(self.__october_field, req.json_body['october']) # validate november self.validate_field(self.__november_field, req.json_body['november']) # validate december self.validate_field(self.__december_field, req.json_body['december']) except ValidationException as e: error_messages.append(e.messages) except Exception as e: print('Exception during request validation:', e) raise ValidationException( 'An error has occurred. Please try again later.') if error_messages: raise ValidationException(error_messages) return None def validate_field(self, field, value): ''' Generic method for regex field validation ''' error_messages = [] try: if isinstance(value, str): test = re.search(field['pattern'], value) if test == None or test.string != value: error_messages.append(field['error_message']) else: error_messages.append( 'Field {0} must all be a non-empty string'.format( field['name'])) except Exception as e: print('Error occurred while validating field:', e, field) if error_messages: raise ValidationException(error_messages) def validate_availability_id(self, availability_id): error_messages = [] # Validate ID field if isinstance(availability_id, str): test = re.search(self.__availability_id_pattern, availability_id) if test == None or test.string != availability_id: error_messages.append( 'ID must only contain letters or numbers') else: error_messages.append('Availability ID must be a String') if error_messages: raise ValidationException(error_messages)
class AvailabilityService: def __init__(self): # init DAOs based on environment self.__provider = DependencyProvider() self.__event_dao = self.__provider.get_instance('EventDao') self.__attendee_dao = self.__provider.get_instance('AttendeeDao') self.__availability_dao = self.__provider.get_instance( 'AvailabilityDao') self.__event_validator = EventValidator() self.__attendee_validator = AttendeeValidator() # get all availability obs for this event def get_event_availability(self, req): try: event_id = req.matchdict['eventId'] self.__event_validator.validate_event_id(event_id) data = self.__availability_dao.get_event_availability(event_id) response = Response(content_type='application/json', status=200) response.charset = 'UTF-8' response.json_body = json.dumps(data) except BaseAppException as e: raise ServiceException(str(e)) except Exception as e: print(e, sys.exc_info()) raise ServiceException( 'An error occurred while loading availability for event:', event_id) return response # delete all availability obs for this event def delete_event_availability(self, req): try: event_id = req.matchdict['eventId'] self.__event_validator.validate_event_id(event_id) self.__availability_dao.delete_event_availability(event_id) response = Response(content_type='application/json', status=200) response.charset = 'UTF-8' except BaseAppException as e: raise ServiceException(str(e)) except Exception as e: print(e, sys.exc_info()) raise ServiceException( 'An error occurred while deleting availability for event:', event_id) return response # get all availability obs for this attendee def get_attendee_availability(self, req): try: attendee_id = req.matchdict['attendeeId'] self.__attendee_validator.validate_attendee_id(attendee_id) data = self.__availability_dao.get_attendee_availability( attendee_id) response = Response(content_type='application/json', status=200) response.charset = 'UTF-8' response.json_body = json.dumps(data) except BaseAppException as e: raise ServiceException(str(e)) except Exception as e: print(e, sys.exc_info()) raise ServiceException( 'An error occurred while loading availability for attendee:', attendee_id) return response # get availability ob for this attendee def get_availability(self, req): try: availability_id = req.matchdict['availabilityId'] self.__availability_validator.validate_availability_id( availability_id) data = self.__availability_dao.get_availability(availability_id) response = Response(content_type='application/json', status=200) response.charset = 'UTF-8' response.json_body = json.dumps(data) except BaseAppException as e: raise ServiceException(str(e)) except Exception as e: print(e, sys.exc_info()) raise ServiceException( 'An error occurred while loading availability with id:', availability_id) return response # add availability ob for this attendee def create_availability(self, req): try: # validate the payload self.__availability_validator.vaildaite_availability_request(req) # set the creator_id and save the event data = self.__availability_dao.create_availability(req.json_body) # build the response body response_body = json.dumps(data) response = Response(content_type='application/json', status=200) response.charset = 'UTF-8' response.json_body = response_body return response except BaseAppException as e: raise ServiceException(str(e)) except Exception as e: print(e, sys.exc_info()) raise ServiceException( 'An error occurred while adding availability.') # update availability ob for this attendee def update_availability(self, req): try: # validate the payload self.__availability_validator.vaildaite_availability_request(req) # set the creator_id and save the event data = self.__availability_dao.update_availability(req.json_body) # build the response body response_body = json.dumps(data) response = Response(content_type='application/json', status=200) response.charset = 'UTF-8' response.json_body = response_body return response except BaseAppException as e: raise ServiceException(str(e)) except Exception as e: print(e, sys.exc_info()) raise ServiceException( 'An error occurred while updating this event.') # delte availability ob def delete_availability(self, req): try: availability_id = req.matchdict['availabilityId'] self.__availability_validator.validate_availability_id( availability_id) self.__availability_dao.delete_availability(attendee_id) response = Response(content_type='application/json', status=200) response.charset = 'UTF-8' except BaseAppException as e: raise ServiceException(str(e)) except Exception as e: print(e, sys.exc_info()) raise ServiceException( 'An error occurred while loading availability with id:', availability_id) return response # delete all availability obs for this attendee def delete_attendee_availability(self, req): try: attendee_id = req.matchdict['attendeeId'] self.__availability_validator.validate_availability_id( availability_id) self.__attendee_validator.validate_attendee_id(attendee_id) self.__availability_dao.delete_attendee_availability(attendee_id) response = Response(content_type='application/json', status=200) response.charset = 'UTF-8' except BaseAppException as e: raise ServiceException(str(e)) except Exception as e: print(e, sys.exc_info()) raise ServiceException( 'An error occurred while deleting attendee availability:', availability_id) return response