def emails(workspace_id): ''' For GET requests, return all emails for the given workspace. For POST requests, add a new email to the given workspace. ''' if not validate_workspace(workspace_id): return 'workspace does not exist', 404 # request is a GET if request.method == 'GET': all_emails = Email.query.filter_by(workspace_id=workspace_id).order_by(Email.updated_at.desc()).all() schema = EmailSchema(many=True) email_data = schema.dump(all_emails) return jsonify(email_data) # request is a POST elif request.method == 'POST': name = request.form.get('Name') html = request.form.get('HTML').encode() subject = request.form.get('Subject') track = request.form.get('Track') track_bool = convert_to_bool(track) if type(track_bool) != bool: return 'Track must be either true or false', 400 email = Email(name=name, html=html, subject=subject, workspace_id=workspace_id, track=track_bool) db.session.add(email) update_workspace_ts(Workspace.query.filter_by(id=workspace_id).first()) db.session.commit() schema = EmailSchema() email_data = schema.dump(email) app.logger.info(f'Added email {name} - Added by {current_user.username} - Client IP address {request.remote_addr}') return jsonify(email_data), 200
def targets(workspace_id, list_id): ''' For GET requets, return all targets of the given list. For POST requests, add a target to the given list. ''' if not validate_workspace(workspace_id): return 'workspace does not exist', 404 targetlist = List.query.filter_by(id=list_id, workspace_id=workspace_id).first() if targetlist is None: return 'list does not exist', 404 # request is a GET if request.method == 'GET': targets = Person.query.filter_by(list_id=list_id) schema = PersonSchema(many=True) all_targets = schema.dump(targets) return jsonify(all_targets) # request is a POST if request.method == 'POST': first_name = request.form.get('first_name') last_name = request.form.get('last_name') email = request.form.get('email') person = Person(first_name=first_name, last_name=last_name, email=email) targetlist.targets.append(person) update_workspace_ts(Workspace.query.filter_by(id=workspace_id).first()) db.session.commit() return 'added person', 201
def email(workspace_id, email_id): ''' For GET requests, return the given email. For DELETE requests, delete the given email. For PUT requests, update the given email. ''' if not validate_workspace(workspace_id): return 'workspace does not exist', 404 email = Email.query.filter_by(id=email_id, workspace_id=workspace_id).first() if email is None: return 'email does not exist', 404 #request is a GET if request.method == 'GET': schema = EmailSchema() email_data = schema.dump(email) return jsonify(email_data) # request is a DELETE elif request.method == 'DELETE': app.logger.info( f'Deleted email {email.name} - Deleted by {current_user.username} - Client IP address {request.remote_addr}' ) db.session.delete(email) update_workspace_ts(Workspace.query.filter_by(id=workspace_id).first()) db.session.commit() return 'deleted', 204 # request is a PUT elif request.method == 'PUT': name = request.form.get('Name') subject = request.form.get('Subject') html = request.form.get('HTML').encode() track = request.form.get('Track') same_email = Email.query.filter_by(name=name).first() if same_email is not None and str(same_email.id) != email_id: return json.dumps({'success': False}), 200, { 'ContentType': 'application/json' } track_bool = convert_to_bool(track) if type(track_bool) != bool: return 'Track must be either true or false', 400 email.name = name email.subject = subject email.html = html email.track = track_bool update_workspace_ts(Workspace.query.filter_by(id=workspace_id).first()) db.session.commit() app.logger.info( f'Updated email {name} - Updated by {current_user.username} - Client IP address {request.remote_addr}' ) return json.dumps({'success': True}), 200, { 'ContentType': 'application/json' }
def targetlist(workspace_id, list_id): ''' For GET requests, return the given list. For PUT requests, udpate the given list. For DELETE requests, delete the given list. ''' if not validate_workspace(workspace_id): return 'workspace does not exist', 404 targetlist = List.query.filter_by(id=list_id, workspace_id=workspace_id).first() if targetlist is None: return 'list does not exist', 404 # request is a GET if request.method == 'GET': schema = ListSchema() list_data = schema.dump(targetlist) return jsonify(list_data) # request is a DELETE elif request.method == 'DELETE': app.logger.info( f'Deleted list {targetlist.name} - Deleted by {current_user.username} - Client IP address {request.remote_addr}' ) db.session.delete(targetlist) update_workspace_ts(Workspace.query.filter_by(id=workspace_id).first()) db.session.commit() return '', 204 # request is a PUT (update attributes of the List) elif request.method == 'PUT': req_json = request.get_json() name = req_json['name'] targets = req_json['targets'] same_list = List.query.filter_by(name=name).first() if same_list is not None and str(same_list.id) != list_id: return json.dumps({'success': False}), 200, { 'ContentType': 'application/json' } targetlist.targets = [] for target in targets: person = Person(first_name=target['first_name'], last_name=target['last_name'], email=target['email']) targetlist.targets.append(person) targetlist.name = name update_workspace_ts(Workspace.query.filter_by(id=workspace_id).first()) db.session.commit() schema = ListSchema() list_data = schema.dump(targetlist) app.logger.info( f'Updated list {targetlist.name} - Updated by {current_user.username} - Client IP address {request.remote_addr}' ) return jsonify(list_data), 201
def page(workspace_id, page_id): ''' For GET requests, return the given page. For DELETE requests, delete the given page. For PUT requests, update the given page. ''' if not validate_workspace(workspace_id): return 'workspace does not exist', 404 page = Page.query.filter_by(id=page_id, workspace_id=workspace_id).first() if page is None: return 'page does not exist', 404 #request is a GET if request.method == 'GET': page.find_form_fields() schema = PageSchema() page_data = schema.dump(page) return jsonify(page_data) # request is a DELETE elif request.method == 'DELETE': app.logger.info( f'Deleted page {page.name} - Deleted by {current_user.username} - Client IP address {request.remote_addr}' ) db.session.delete(page) update_workspace_ts(Workspace.query.filter_by(id=workspace_id).first()) db.session.commit() return 'deleted', 204 # request is a PUT elif request.method == 'PUT': name = request.form.get('Name') html = request.form.get('HTML').encode() url = request.form.get('URL') same_page = Page.query.filter_by(name=name).first() if same_page is not None and str(same_page.id) != page_id: return json.dumps({'success': False}), 200, { 'ContentType': 'application/json' } page.name = name page.html = html page.url = url update_workspace_ts(Workspace.query.filter_by(id=workspace_id).first()) db.session.commit() app.logger.info( f'Updated page {page.name} - Updated by {current_user.username} - Client IP address {request.remote_addr}' ) return json.dumps({'success': True}), 200, { 'ContentType': 'application/json' }
def profiles(workspace_id): ''' For GET requests, return all profiles. For POST requests, add a new profile. ''' if not validate_workspace(workspace_id): return 'workspace does not exist', 404 if request.method == 'GET': all_profiles = Profile.query.filter_by( workspace_id=workspace_id).order_by( Profile.updated_at.desc()).all() schema = ProfileSchema(many=True) profiles = schema.dump(all_profiles) return jsonify(profiles) # request is a POST else: name = request.form.get('Name') from_address = request.form.get('From_Address') host = request.form.get('SMTP_Host') port = request.form.get('SMTP_Port') username = request.form.get('Username') password = request.form.get('Password') tls = request.form.get('TLS') ssl = request.form.get('SSL') profile = Profile.query.filter_by(name=name).first() ssl_bool = convert_to_bool(ssl) tls_bool = convert_to_bool(tls) if profile is not None: return json.dumps({'success': False}), 200, { 'ContentType': 'application/json' } elif type(ssl_bool) != bool or type(tls_bool) != bool: return 'ssl/tls must be either true or false', 400 profile = Profile(name=name, from_address=from_address, smtp_host=host, smtp_port=port, \ username=encrypt(username.encode()), password=encrypt(password.encode()), tls=tls_bool, ssl=ssl_bool, workspace_id=workspace_id) db.session.add(profile) update_workspace_ts(Workspace.query.filter_by(id=workspace_id).first()) db.session.commit() schema = ProfileSchema() profile_data = schema.dump(profile) app.logger.info( f'Added profile {name} - Added by {current_user.username} - Client IP address {request.remote_addr}' ) return jsonify(profile_data), 201
def targetlists(workspace_id): ''' For GET requests, return all target lists associated with the given workspace. For POST requests, add a new list to the given workspace. ''' if not validate_workspace(workspace_id): return 'workspace does not exist', 404 # request is a GET if request.method == 'GET': workspace_lists = List.query.filter_by( workspace_id=workspace_id).order_by(List.updated_at.desc()).all() schema = ListSchema(many=True) list_data = schema.dump(workspace_lists) return jsonify(list_data) # request is a POST elif request.method == 'POST': req_json = request.get_json() name = req_json['name'] targets = req_json['targets'] list_name = List.query.filter_by(workspace_id=workspace_id, name=name).first() if list_name is not None: return json.dumps({'success': False}), 200, { 'ContentType': 'application/json' } new_list = List(name=name, workspace_id=workspace_id) for target in targets: person = Person(first_name=target['first_name'], last_name=target['last_name'], email=target['email']) new_list.targets.append(person) db.session.add(new_list) update_workspace_ts(Workspace.query.filter_by(id=workspace_id).first()) db.session.commit() schema = ListSchema() list_data = schema.dump(new_list) app.logger.info( f'Added list {name} - Added by {current_user.username} - Client IP address {request.remote_addr}' ) return jsonify(list_data), 201
def target(workspace_id, list_id, target_id): ''' For DELETE requests, delete the given target from the given list. ''' if not validate_workspace(workspace_id): return 'workspace does not exist', 404 targetlist = List.query.filter_by(id=list_id, workspace_id=workspace_id).first() if targetlist is None: return 'list does not exist', 404 target = Person.query.filter_by(id=target_id, list_id=list_id).first() if target is None: return 'target does not exist' db.session.delete(target) update_workspace_ts(Workspace.query.filter_by(id=workspace_id).first()) db.session.commit() return 'deleted', 204
def pages(workspace_id): ''' For GET requests, return all pages for the given workspace. For POST requests, add a new pages to the given workspace. ''' if not validate_workspace(workspace_id): return 'workspace does not exist', 404 # request is a GET if request.method == 'GET': all_pages = Page.query.filter_by(workspace_id=workspace_id).order_by( Page.updated_at.desc()).all() schema = PageSchema(many=True) page_data = schema.dump(all_pages) return jsonify(page_data) # request is a POST elif request.method == 'POST': name = request.form.get('Name') html = request.form.get('HTML').encode() url = request.form.get('URL') page = Page.query.filter_by(name=name).first() if page is not None: return json.dumps({'success': False}), 200, { 'ContentType': 'application/json' } page = Page(name=name, html=html, workspace_id=workspace_id, url=url) db.session.add(page) update_workspace_ts(Workspace.query.filter_by(id=workspace_id).first()) db.session.commit() schema = PageSchema() page_data = schema.dump(page) app.logger.info( f'Added page {name} - Added by {current_user.username} - Client IP address {request.remote_addr}' ) return jsonify(page_data), 201
def campaigns(workspace_id): ''' For GET requests, return all campaigns for the given workspace. For POST requests, all a campaign to the given workspace. ''' if not validate_workspace(workspace_id): return 'workspace does not exist', 404 # request is a GET if request.method == 'GET': all_campaigns = Campaign.query.filter_by( workspace_id=workspace_id).order_by( Campaign.updated_at.desc()).all() # sort the pages associated with the campaign by index # for campaign in all_campaigns: # campaign.pages.sort(key=lambda camp: camp.index) schema = CampaignSchema(many=True) campaign_data = schema.dump(all_campaigns) return jsonify(campaign_data) # request is a POST elif request.method == 'POST': name = request.form.get('Name') email_id = request.form.get('Email') page_ids = request.form.getlist( 'Pages[]' ) # page names is a list of page names # page names is a list of page names profile_id = request.form.get('Profile') list_id = request.form.get('List') domain_id = request.form.get('Domain') server_id = request.form.get('Server') port = request.form.get('Port') ssl = request.form.get('SSL') redirect_url = request.form.get('Redirect_URL') safety_url = request.form.get('Safety_URL') start_time = request.form.get('Start_Time') interval = request.form.get('Interval') batch_size = request.form.get('Batch_Size') payload_url = request.form.get('Payload_URL') payload_file = request.form.get('Payload_File') if len(request.files) > 0: attach = request.files['Attachment'] attach_name = attach.filename attach_bytes = attach.read() else: attach_name = None attach_bytes = None if start_time: start_time = convert_to_datetime(start_time) else: start_time = datetime.now() ssl_bool = convert_to_bool(ssl) if type(ssl_bool) != bool: return 'ssl must be either true or false', 400 pages = [] for page_id in page_ids: page = Page.query.with_entities(Page).filter( (Page.id == page_id) & ((Page.workspace_id == workspace_id) | (Page.workspace_id == 1))).first() pages.append(page) email = Email.query.with_entities(Email).filter( (Email.id == email_id) & ((Email.workspace_id == workspace_id) | (Email.workspace_id == 1))).first() profile = Profile.query.with_entities( Profile).filter((Profile.id == profile_id) & ((Profile.workspace_id == workspace_id) | (Profile.workspace_id == 1))).first() targetlist = List.query.with_entities(List).filter( (List.id == list_id) & ((List.workspace_id == workspace_id) | (List.workspace_id == 1))).first() domain = Domain.query.filter_by(id=domain_id).first() server = Server.query.filter_by(id=server_id).first() # make sure all given modules exist before continuing makeup = validate_campaign_makeup(email, pages, profile, targetlist, domain, server) if makeup: return makeup campaign = Campaign(name=name, workspace_id=workspace_id, email_id=email.id, profile_id=profile.id, \ start_time=start_time, send_interval=interval, batch_size=batch_size, \ list_id=targetlist.id, domain_id=domain.id, server_id=server.id, port=port, ssl=ssl_bool, redirect_url=redirect_url, \ safety_url=safety_url, payload_url=payload_url, payload_file=payload_file, attachment=attach_bytes, attachment_name=attach_name) db.session.add(campaign) update_workspace_ts(Workspace.query.filter_by(id=workspace_id).first()) db.session.commit() for idx, page in enumerate(pages): #page_association = Campaignpages(index=idx) #campaign.pages.append(page_association) page_association = Campaignpages(campaign_id=campaign.id, page_id=page.id, index=idx) db.session.add(page_association) db.session.commit() #schema = WorkerCampaignSchema() #campaign_data = schema.dump(campaign) app.logger.info( f'Added campaign {name} (ID: {campaign.id}) (Start time: {start_time}) - Added by {current_user.username} - Client IP address {request.remote_addr}' ) prep_tracking(campaign.list.targets, campaign.id) #campaign.cast(campaign_data) campaign.cast() schema = CampaignSchema() data = schema.dump(campaign) return json.dumps({ 'success': True, 'campaign': data }), 200, { 'ContentType': 'application/json' }
def profile(workspace_id, profile_id): ''' For GET requests, return the profile with the given name. For POST requests, use the given profile to send a test email. For DELETE requests, delete the given profile. ''' if not validate_workspace(workspace_id): return 'workspace does not exist', 404 profile = Profile.query.filter_by(id=profile_id, workspace_id=workspace_id).first() if profile is None: return 'profile does not exist', 404 # request is a GET if request.method == 'GET': schema = ProfileSchema() profile_data = schema.dump(profile) return jsonify(profile_data) # request is a DELETE elif request.method == 'DELETE': app.logger.info( f'Deleted profile {profile.name} - Deleted by {current_user.username} - Client IP address {request.remote_addr}' ) db.session.delete(profile) update_workspace_ts(Workspace.query.filter_by(id=workspace_id).first()) db.session.commit() return 'profile deleted', 204 # request is a POST elif request.method == 'POST': address = request.form.get('Address') if not validate_email_format(address): return 'Enter a valid email address', 400 success = profile.send_test_mail(address) if success: app.logger.info( f'Test email successfully email to {address} using profile {profile.name} - Sent by {current_user.username} - Client IP address {request.remote_addr}' ) else: app.logger.warning( f'Test email failed to {address} using profile {profile.name} - Sent by {current_user.username} - Client IP address {request.remote_addr}' ) return json.dumps({'success': success}), 200, { 'ContentType': 'application/json' } # request is a PUT elif request.method == 'PUT': name = request.form.get('Name') from_address = request.form.get('From_Address') host = request.form.get('SMTP_Host') port = request.form.get('SMTP_Port') username = request.form.get('Username') password = request.form.get('Password') tls = request.form.get('TLS') ssl = request.form.get('SSL') same_profile = Profile.query.filter_by(name=name).first() if same_profile is not None and str(same_profile.id) != profile_id: return json.dumps({'success': False}), 200, { 'ContentType': 'application/json' } ssl_bool = convert_to_bool(ssl) tls_bool = convert_to_bool(tls) if type(ssl_bool) != bool or type(tls_bool) != bool: return 'ssl/tls must be either true or false', 400 profile.name = name profile.from_address = from_address profile.smtp_host = host profile.smtp_port = port profile.username = encrypt(username.encode()) profile.password = encrypt(password.encode()) profile.tls = tls_bool profile.ssl = ssl_bool profile.workspace_id = workspace_id update_workspace_ts(Workspace.query.filter_by(id=workspace_id).first()) db.session.commit() schema = ProfileSchema() profile_data = schema.dump(profile) app.logger.info( f'Updated profile {name} - Updated by {current_user.username} - Client IP address {request.remote_addr}' ) return jsonify(profile_data), 200
def campaign(workspace_id, campaign_id): ''' For GET requests, return the given campaign. For DELETE requests, delete the given campaign. For PUT requests, update the given campaign. ''' if not validate_workspace(workspace_id): return 'workspace does not exist', 404 campaign = Campaign.query.filter_by(id=campaign_id, workspace_id=workspace_id).first() if campaign is None: return 'campaign does not exist', 404 # request is a GET if request.method == 'GET': schema = CampaignSchema() campaign_data = schema.dump(campaign) return jsonify(campaign_data) # request is a DELETE elif request.method == 'DELETE': if campaign.status == 'Active': campaign.kill() if campaign.status == 'Scheduled': campaign.remove_job() app.logger.info( f'Deleted campaign {campaign.name} (ID: {campaign.id}) - Deleted by {current_user.username} - Client IP address {request.remote_addr}' ) db.session.delete(campaign) update_workspace_ts(Workspace.query.filter_by(id=workspace_id).first()) db.session.commit() return 'campaign deleted', 204 # request is a PUT elif request.method == 'PUT': name = request.form.get('Name') email_name = request.form.get('Email_Name') profile_name = request.form.get('Profile_Name') list_name = request.form.get('List_Name') domain_name = request.form.get('Domain_Name') server_alias = request.form.get('Server_Alias') port = request.form.get('Port') ssl = request.form.get('SSL') redirect_url = request.form.get('Redirect_URL') same_campaign = Campaign.query.filter_by(name=name).first() if same_campaign is not None and str(same_campaign.id) != campaign_id: return json.dumps({'success': False}), 200, { 'ContentType': 'application/json' } ssl_bool = convert_to_bool(ssl) if type(ssl_bool) != bool: return 'ssl must be either true or false', 400 email = Email.query.filter_by(name=email_name, workspace_id=workspace_id).first() profile = Profile.query.filter_by(name=profile_name, workspace_id=workspace_id).first() targetlist = List.query.filter_by(name=list_name, workspace_id=workspace_id).first() domain = Domain.query.filter_by(domain=domain_name).first() server = Server.query.filter_by(alias=server_alias).first() # make sure all given modules exist before continuing makeup = validate_campaign_makeup(email, page, profile, targetlist, domain, server) if makeup: return makeup campaign.name = name campaign.email_id = email.id campaign.profile_id = profile.id campaign.list_id = targetlist.id campaign.domain_id = domain.id campaign.server_id = server.id campaign.port = port campaign.ssl = ssl_bool campaign.redirect_url = redirect_url update_workspace_ts(Workspace.query.filter_by(id=workspace_id).first()) db.session.commit() return 'campaign updated'