def get_buyer_dashboard_data_for_team_overview(): """Buyer dashboard (Team overview) (role=buyer) --- tags: - dashboard definitions: BuyerDashboardTeamOverviewItems: type: object properties: items: type: array items: $ref: '#/definitions/BuyerDashboardTeamOverviewItem' organisation: type: string BuyerDashboardTeamOverviewItem: type: object properties: email: type: string name: type: string responses: 200: description: Buyer dashboard data for the 'Team overview' tab schema: $ref: '#/definitions/BuyerDashboardTeamOverviewItems' """ organisation = users.get_user_organisation(get_email_domain(current_user.email_address)) team_members = users.get_team_members(current_user.get_id(), get_email_domain(current_user.email_address)) return jsonify(items=team_members, organisation=organisation), 200
def get_buyer_dashboard_data_for_team_overview(): """Buyer dashboard (Team overview) (role=buyer) --- tags: - dashboard definitions: BuyerDashboardTeamOverviewItems: type: object properties: items: type: array items: $ref: '#/definitions/BuyerDashboardTeamOverviewItem' organisation: type: string BuyerDashboardTeamOverviewItem: type: object properties: email: type: string name: type: string responses: 200: description: Buyer dashboard data for the 'Team overview' tab schema: $ref: '#/definitions/BuyerDashboardTeamOverviewItems' """ organisation = users.get_user_organisation( get_email_domain(current_user.email_address)) team_members = users.get_team_members( current_user.get_id(), get_email_domain(current_user.email_address)) return jsonify(items=team_members, organisation=organisation), 200
def validate_basics(self): errors = [] if not self.team.name or not self.team.name.replace(' ', ''): errors.append({ 'message': 'A team name is required.', 'severity': 'error', 'step': 'about', 'id': 'T001' }) if self.team.email_address: if '@' not in self.team.email_address or self.team.email_address.count( '@') > 1: errors.append({ 'message': 'Please add a valid email address.', 'severity': 'error', 'step': 'about', 'id': 'T002' }) if get_email_domain(self.team.email_address) != self.domain: errors.append({ 'message': 'You must use an email address ending in @{}.'.format( self.domain), 'severity': 'error', 'step': 'about', 'id': 'T003' }) return errors
def is_duplicate_user(email_address): domain = get_email_domain(email_address) if domain in current_app.config['GENERIC_EMAIL_DOMAINS']: return False supplier_code = db.session.execute( """ select distinct(supplier_code) from vuser where email_domain = :domain """, { 'domain': domain }).fetchone() if (supplier_code and supplier_code[0]): send_existing_seller_notification(email_address, supplier_code[0]) duplicate_audit_event(email_address, {'supplier_code': supplier_code[0]}) return True application_id = db.session.execute( """ select distinct(application_id) from vuser where email_domain = :domain """, { 'domain': domain }).fetchone() if (application_id and application_id[0]): duplicate_audit_event(email_address, {'application_id': application_id[0]}) send_existing_application_notification( email_address=email_address, application_id=application_id[0]) return True return False
def get_team_members(): """Supplier dashboard (Team) (role=supplier) --- tags: - dashboard definitions: SellerDashboardTeamItems: type: object properties: teams: type: array items: $ref: '#/definitions/SellerDashboardTeamItem' SellerDashboardTeamItem: type: object properties: email: type: string name: type: string responses: 200: description: Seller dashboard data for the 'Team' tab schema: $ref: '#/definitions/SellerDashboardTeamItems' """ team_members = users.get_team_members( current_user.get_id(), get_email_domain(current_user.email_address)) return jsonify(teams={'items': team_members}), 200
def get_team(team_id): team = team_service.get_team(team_id) if not team: raise NotFoundError('Team {} does not exist'.format(team_id)) team_member = team_member_service.find( is_team_lead=True, team_id=team_id, user_id=current_user.id ).one_or_none() if not team_member: raise UnauthorisedError('Only team leads can edit a team') domain = get_email_domain(current_user.email_address) if team['teamMembers'] is not None: for user_id, team_member in team['teamMembers'].iteritems(): missing_permissions = [permission for permission in permission_types if permission not in team_member['permissions']] for permission in missing_permissions: team_member['permissions'][permission] = False team.update(domain=domain) return team
def validate_basics(self): errors = [] if not self.team.name or not self.team.name.replace(' ', ''): errors.append({ 'message': 'A team name is required.', 'severity': 'error', 'step': 'about', 'id': 'T001' }) if self.team.email_address: if not is_valid_email(self.team.email_address): errors.append({ 'message': 'Please add a valid email address.', 'severity': 'error', 'step': 'about', 'id': 'T002' }) if get_email_domain(self.team.email_address) not in self.agency_domains: errors.append({ 'message': 'You must use an email address ending in @{}.'.format(', @'.join(self.agency_domains)), 'severity': 'error', 'step': 'about', 'id': 'T003' }) return errors
def can_view_referral(created_by, supplier_code, referral_domain, current_user): return (current_user.role == 'buyer' and created_by == int(current_user.get_id()) or current_user.role == 'supplier' and supplier_code == current_user.supplier_code or current_user.role == 'admin' and referral_domain == get_email_domain(current_user.email_address))
def get_buyer_dashboard_data_for_team_briefs(): """Buyer dashboard (Team briefs) (role=buyer) --- tags: - dashboard definitions: BuyerDashboardTeamItems: type: object properties: items: type: array items: $ref: '#/definitions/BuyerDashboardTeamItem' organisation: type: string BuyerDashboardTeamItem: type: object properties: author: type: string closed_at: type: string nullable: true framework: type: string id: type: integer lot: type: string name: type: string status: type: string responses: 200: description: Buyer dashboard data for the 'Team briefs' tab schema: $ref: '#/definitions/BuyerDashboardTeamItems' """ organisation = users.get_user_organisation( get_email_domain(current_user.email_address)) team_briefs = briefs.get_team_briefs( current_user.get_id(), get_email_domain(current_user.email_address)) return jsonify(items=team_briefs, organisation=organisation), 200
def get_buyer_dashboard_data_for_team_briefs(): """Buyer dashboard (Team briefs) (role=buyer) --- tags: - dashboard definitions: BuyerDashboardTeamItems: type: object properties: items: type: array items: $ref: '#/definitions/BuyerDashboardTeamItem' organisation: type: string BuyerDashboardTeamItem: type: object properties: author: type: string closed_at: type: string nullable: true framework: type: string id: type: integer lot: type: string name: type: string status: type: string responses: 200: description: Buyer dashboard data for the 'Team briefs' tab schema: $ref: '#/definitions/BuyerDashboardTeamItems' """ organisation = users.get_user_organisation(get_email_domain(current_user.email_address)) team_briefs = briefs.get_team_briefs(current_user.get_id(), get_email_domain(current_user.email_address)) return jsonify(items=team_briefs, organisation=organisation), 200
def login(): """Login user --- tags: - auth security: - basicAuth: [] consumes: - application/json parameters: - name: body in: body required: true schema: id: LoginUser required: - emailAddress - password properties: emailAddress: type: string password: type: string responses: 200: description: User schema: $ref: '#/definitions/UserInfo' """ json_payload = request.get_json() email_address = json_payload.get('emailAddress', None) user = User.get_by_email_address(email_address.lower()) if user is None or (user.supplier and user.supplier.status == 'deleted'): return jsonify(message='User does not exist'), 403 elif encryption.authenticate_user(json_payload.get('password', None), user) and user.active: user.logged_in_at = datetime.utcnow() user.failed_login_count = 0 db.session.add(user) db.session.commit() login_user(user) user.user_organisation = users.get_user_organisation( get_email_domain(email_address)) return jsonify(user_info(user)) else: user.failed_login_count += 1 db.session.add(user) db.session.commit() return jsonify(message="Could not authorize user"), 403
def buyer_dashboard(): status = request.args.get('status', None) result = buyer_dashboard_business.get_briefs(current_user.id, status) counts = buyer_dashboard_business.get_brief_counts(current_user.id) email_domain = get_email_domain(current_user.email_address) organisation = users.get_user_organisation(email_domain) return jsonify( briefs=result, brief_counts=counts, organisation=organisation ), 200
def find_team_members(): keywords = request.args.get('keywords') or '' exclude = request.args.get('exclude') or '' if keywords: results = team_business.search_team_members( current_user, get_email_domain(current_user.email_address), keywords=keywords, exclude=exclude.split(',')) return jsonify(users=results), 200 else: abort('You must provide a keywords param.')
def get_people_overview(): people_overview = {} user = users.get(current_user.id) completed_teams = team_service.get_teams_for_user(user.id) domain = get_email_domain(user.email_address) people = users.get_buyer_team_members(domain) people_overview.update(users=people) organisation = users.get_user_organisation(domain) people_overview.update(organisation=organisation) completed_teams_count = len(completed_teams) people_overview.update(completedTeamsCount=completed_teams_count) return people_overview
def get_teams_overview(): teams_overview = {} user = users.get(current_user.id) completed_teams = team_service.get_teams_for_user(user.id) email_domain = get_email_domain(user.email_address) overview = team_service.get_teams_overview(user.id, email_domain) teams_overview.update(overview=overview) organisation = users.get_user_organisation(email_domain) teams_overview.update(organisation=organisation) completed_teams_count = len(completed_teams) teams_overview.update(completedTeamsCount=completed_teams_count) return teams_overview
def signup(): """Signup user --- tags: - auth consumes: - application/json parameters: - name: body in: body required: true schema: id: SignupUser required: - name - email_address - user_type properties: name: type: string email_address: type: string user_type: type: string employment_status: type: string line_manager_name: type: string line_manager_email: type: string framework: type: string responses: 200: description: User schema: $ref: '#/definitions/UserInfo' """ json_payload = request.get_json() name = json_payload.get('name', None) email_address = json_payload.get('email_address', None) user_type = json_payload.get('user_type', None) employment_status = json_payload.get('employment_status', None) line_manager_name = json_payload.get('line_manager_name', None) line_manager_email = json_payload.get('line_manager_email', None) framework = json_payload.get('framework', 'digital-marketplace') user = User.query.filter( User.email_address == email_address.lower()).first() if user is not None: send_user_existing_password_reset_email(user.name, email_address) return jsonify( email_address=email_address, message="Email invite sent successfully" ), 200 if user_type == 'seller' or user_type == 'applicant': if is_duplicate_user(email_address): return jsonify( email_address=email_address, message='An account with this email domain already exists' ), 409 if user_type == 'buyer' and not has_whitelisted_email_domain(get_email_domain(email_address)): return jsonify( email_address=email_address, message="A buyer account must have a valid government entity email domain" ), 403 user_data = { 'name': name, 'user_type': user_type, 'framework': framework, 'employment_status': employment_status } claim = user_claims_service.make_claim(type='signup', email_address=email_address, data=user_data) if not claim: return jsonify(message="There was an issue completing the signup process."), 500 publish_tasks.user_claim.delay( publish_tasks.compress_user_claim(claim), 'created' ) if employment_status == 'contractor': try: send_account_activation_manager_email( token=claim.token, manager_name=line_manager_name, manager_email=line_manager_email, applicant_name=name, applicant_email=email_address, framework=framework ) return jsonify( email_address=email_address, message="Email invite sent successfully" ), 200 except EmailError: return jsonify(message='An error occured when trying to send an email'), 500 if employment_status == 'employee' or user_type == 'seller': try: send_account_activation_email( token=claim.token, email_address=email_address, framework=framework ) return jsonify( email_address=email_address, message="Email invite sent successfully" ), 200 except EmailError: return jsonify( email_address=email_address, message='An error occured when trying to send an email' ), 500 else: return jsonify( email_address=email_address, message='An error occured when trying to send an email' ), 400
def add_user(data): if data is None: raise DataError('create_user requires a data arg') name = data.get('name') password = data.get('password') role = data.get('user_type') email_address = data.get('email_address', None) framework_slug = data.get('framework', 'digital-marketplace') if email_address is None: email_address = data.get('emailAddress', None) if 'hashpw' in data and not data['hashpw']: password = password else: password = encryption.hashpw(password) if role == 'seller': role = 'applicant' now = datetime.utcnow() user = User(email_address=email_address.lower(), phone_number=data.get('phoneNumber', None), name=name, role=role, password=password, active=True, created_at=now, updated_at=now, password_changed_at=now) audit_data = {} if "supplier_code" in data and data['supplier_code']: user.supplier_code = data['supplier_code'] user.role = 'supplier' audit_data['supplier_code'] = user.supplier_code if user.role == 'supplier' and user.supplier_code is None: raise ValueError( "'supplier_code' is required for users with 'supplier' role") if user.role != 'supplier' and user.supplier_code is not None: raise ValueError( "'supplier_code' is only valid for users with 'supplier' role, not '{}'" .format(user.role)) if "application_id" in data: user.application_id = data['application_id'] elif user.supplier_code is not None: appl = Application.query.filter_by( supplier_code=user.supplier_code).first() user.application_id = appl and appl.id or None if user.role == 'applicant' and user.application_id is None: raise ValueError( "'application id' is required for users with 'applicant' role") elif user.role != 'applicant' and user.role != 'supplier' and user.application_id is not None: raise ValueError( "'application_id' is only valid for users with applicant' or 'supplier' role, not '{}'" .format(user.role)) if user.role == 'buyer': agency = agency_service.get_or_add_agency( get_email_domain(email_address)) user.agency_id = agency.id db.session.add(user) db.session.flush() framework = Framework.query.filter( Framework.slug == framework_slug).first() db.session.add(UserFramework(user_id=user.id, framework_id=framework.id)) audit = AuditEvent(audit_type=AuditTypes.create_user, user=email_address.lower(), data=audit_data, db_object=user) db.session.add(audit) db.session.commit() user = db.session.query(User).options( noload('*')).filter(User.id == user.id).one_or_none() publish_tasks.user.delay(publish_tasks.compress_user(user), 'created') return user
def create_referral(self, service_type_price_id, requested_by, details): return self.create(service_type_price_id=service_type_price_id, domain=get_email_domain(requested_by.email_address), created_by=requested_by.id, details=details)
def __init__(self, team, current_user): self.team = team self.current_user = current_user self.domain = get_email_domain(current_user.email_address)
def signup(): """Signup user --- tags: - auth consumes: - application/json parameters: - name: body in: body required: true schema: id: SignupUser required: - name - email_address - user_type properties: name: type: string email_address: type: string user_type: type: string employment_status: type: string line_manager_name: type: string line_manager_email: type: string framework: type: string responses: 200: description: User schema: $ref: '#/definitions/UserInfo' """ json_payload = request.get_json() name = json_payload.get('name', None) email_address = json_payload.get('email_address', None) user_type = json_payload.get('user_type', None) employment_status = json_payload.get('employment_status', None) line_manager_name = json_payload.get('line_manager_name', None) line_manager_email = json_payload.get('line_manager_email', None) framework = json_payload.get('framework', 'digital-marketplace') user = User.query.filter( User.email_address == email_address.lower()).first() if user is not None: return jsonify( email_address=email_address, message="A user with the email address '{}' already exists".format( email_address)), 409 if user_type == 'seller' or user_type == 'applicant': if is_duplicate_user(email_address): return jsonify( email_address=email_address, message='An account with this email domain already exists' ), 409 # New ORAMS users don't need their email domain checked as that's done manually if framework == 'orams': try: orams_send_account_activation_admin_email(name, email_address, framework) return jsonify(email_address=email_address, message="Email invite sent successfully"), 200 except EmailError: return jsonify( message='An error occured when trying to send an email'), 500 if user_type == 'buyer' and not has_whitelisted_email_domain( get_email_domain(email_address)): return jsonify( email_address=email_address, message= "A buyer account must have a valid government entity email domain" ), 403 if employment_status == 'contractor': try: send_account_activation_manager_email( manager_name=line_manager_name, manager_email=line_manager_email, applicant_name=name, applicant_email=email_address, framework=framework) return jsonify(email_address=email_address, message="Email invite sent successfully"), 200 except EmailError: return jsonify( message='An error occured when trying to send an email'), 500 if employment_status == 'employee' or user_type == 'seller': try: send_account_activation_email(name=name, email_address=email_address, user_type=user_type, framework=framework) return jsonify(email_address=email_address, message="Email invite sent successfully"), 200 except EmailError: return jsonify( email_address=email_address, message='An error occured when trying to send an email'), 500 else: return jsonify( email_address=email_address, message='An error occured when trying to send an email'), 400
def create_user(): json_payload = get_json_from_request() json_has_required_keys(json_payload, ["users"]) json_payload = json_payload["users"] validate_user_json_or_400(json_payload) email_address = json_payload.get('email_address', None) if email_address is None: email_address = json_payload.get('emailAddress', None) user = User.query.filter( User.email_address == email_address.lower()).first() if user: abort(409, "User already exists") if 'hashpw' in json_payload and not json_payload['hashpw']: password = json_payload['password'] else: password = encryption.hashpw(json_payload['password']) now = datetime.utcnow() user = User( email_address=email_address.lower(), phone_number=json_payload.get('phoneNumber') or None, name=json_payload['name'], role=json_payload['role'], password=password, active=True, created_at=now, updated_at=now, password_changed_at=now ) audit_data = {} if "supplierCode" in json_payload: user.supplier_code = json_payload['supplierCode'] audit_data['supplier_code'] = user.supplier_code check_supplier_role(user.role, user.supplier_code) if "application_id" in json_payload: user.application_id = json_payload['application_id'] elif user.supplier_code is not None: appl = Application.query.filter_by(supplier_code=user.supplier_code).first() user.application_id = appl and appl.id or None check_applicant_role(user.role, user.application_id) try: db.session.add(user) db.session.flush() audit = AuditEvent( audit_type=AuditTypes.create_user, user=email_address.lower(), data=audit_data, db_object=user ) db.session.add(audit) db.session.commit() user = db.session.query(User).options(noload('*')).filter(User.id == user.id).one_or_none() publish_tasks.user.delay( publish_tasks.compress_user(user), 'created' ) if user.role == 'buyer': notification_message = 'Domain: {}'.format( get_email_domain(email_address) ) notification_text = 'A new buyer has signed up' notify_team(notification_text, notification_message) except IntegrityError: db.session.rollback() abort(400, "Invalid supplier code or application id") except DataError: db.session.rollback() abort(400, "Invalid user role") return jsonify(users=user.serialize()), 201