def _check_geni_federation_status(request): """ Checks if a user who authenticated view GENI/OpenID is on the Chameleon Federation project on the GENI side. If so, then checks if the user is on the corresponding project on the Chameleon side. Returns a tuple of boolean values for (on_geni_project, on_chameleon_project) """ geni_project_key = '%s|%s' % (settings.GENI_FEDERATION_PROJECTS['geni']['id'], settings.GENI_FEDERATION_PROJECTS['geni']['name']) on_geni_project = geni_project_key in request.session['openid']['ax']['projects'] if on_geni_project: try: fed_proj = Project(settings.GENI_FEDERATION_PROJECTS['chameleon']['id']) on_chameleon_project = any(u.username == request.user.username \ for u in fed_proj.get_users()) except: logger.warn('Could not locate Chameleon federation project: %s' % \ settings.GENI_FEDERATION_PROJECTS['chameleon']) on_chameleon_project = False else: on_chameleon_project = False return on_geni_project, on_chameleon_project
def _check_geni_federation_status(request): """ Checks if a user who authenticated view GENI/OpenID is on the Chameleon Federation project on the GENI side. If so, then checks if the user is on the corresponding project on the Chameleon side. Returns a tuple of boolean values for (on_geni_project, on_chameleon_project) """ geni_project_key = '%s|%s' % ( settings.GENI_FEDERATION_PROJECTS['geni']['id'], settings.GENI_FEDERATION_PROJECTS['geni']['name']) on_geni_project = geni_project_key in request.session['openid']['ax'][ 'projects'] if on_geni_project: try: fed_proj = Project( settings.GENI_FEDERATION_PROJECTS['chameleon']['id']) on_chameleon_project = any(u.username == request.user.username \ for u in fed_proj.get_users()) except: logger.warn('Could not locate Chameleon federation project: %s' % \ settings.GENI_FEDERATION_PROJECTS['chameleon']) on_chameleon_project = False else: on_chameleon_project = False return on_geni_project, on_chameleon_project
def dashboard(request): context = {} # active projects... projects = Project.list(username=request.user) context['active_projects'] = [p for p in projects \ if p.source == 'Chameleon' and \ any(a.status in ['Active', 'Approved', 'Pending'] for a in p.allocations)] # open tickets... rt = rtUtil.DjangoRt() context['open_tickets'] = rt.getUserTickets(request.user.email) # ongoing outages... outages = [o for o in Outage.objects.order_by('-end_date', '-start_date') if not o.resolved] # silly ORM quirk context['outages'] = outages webinars = Webinar.objects.filter(end_date__gte=timezone.now()) context['webinars'] = webinars # federation status... if 'openid' in request.session: on_geni_project, on_chameleon_project = _check_geni_federation_status(request) context['geni_federation'] = { 'on_geni_project': on_geni_project, 'on_chameleon_project': on_chameleon_project, 'geni_project_name': settings.GENI_FEDERATION_PROJECTS['geni']['name'], 'chameleon_project_name': settings.GENI_FEDERATION_PROJECTS['chameleon']['name'], } return render(request, 'dashboard.html', context)
def activate_geni(request): fed_proj = Project(settings.GENI_FEDERATION_PROJECTS["chameleon"]["id"]) on_chameleon_project = any(u.username == request.user for u in fed_proj.get_users()) if on_chameleon_project: messages.info("Your access to the Chameleon-GENI Federation Project is active.") return HttpResponseRedirect(reverse("dashboard")) if request.method == "POST": if request.POST.get("accept_user_terms") == "on": fed_proj.add_user(request.user) messages.success(request, "Your access to the Chameleon-GENI Federation Project is active.") return HttpResponseRedirect(reverse("dashboard")) else: messages.error(request, "Please agree to Chameleon Acceptable Use Policy before proceeding.") context = { "geni": settings.GENI_FEDERATION_PROJECTS["geni"], "chameleon": settings.GENI_FEDERATION_PROJECTS["chameleon"], } return render(request, "chameleon_openid/activate_geni.html", context)
def user_projects(request): context = {} tas = TASClient() user = tas.get_user(username=request.user) context['is_pi_eligible'] = user['piEligibility'] == 'Eligible' projects = Project.list(username=request.user) projects = list(p for p in projects if p.source == 'Chameleon') context['projects'] = projects return render(request, 'projects/user_projects.html', context)
def user_projects(request): context = {} tas = TASClient() user = tas.get_user(username=request.user) context['is_pi_eligible'] = user['piEligibility'] == 'Eligible' projects = Project.list(username=request.user) projects = list(p for p in projects if p.source == 'Chameleon') for proj in projects: try: extras = ProjectExtras.objects.get(tas_project_id=proj.id) proj.__dict__['nickname'] = extras.nickname except ProjectExtras.DoesNotExist: project_nickname = None context['projects'] = projects return render(request, 'projects/user_projects.html', context)
def dashboard(request): context = {} # active projects... projects = Project.list(username=request.user) context['active_projects'] = [p for p in projects \ if p.source == 'Chameleon' and \ any(a.status in ['Active', 'Approved', 'Pending'] for a in p.allocations)] # open tickets... rt = rtUtil.DjangoRt() context['open_tickets'] = rt.getUserTickets(request.user.email) # ongoing outages... outages = [ o for o in Outage.objects.order_by('-end_date', '-start_date') if not o.resolved ] # silly ORM quirk context['outages'] = outages webinars = Webinar.objects.filter(end_date__gte=timezone.now()) context['webinars'] = webinars # federation status... if 'openid' in request.session: on_geni_project, on_chameleon_project = _check_geni_federation_status( request) context['geni_federation'] = { 'on_geni_project': on_geni_project, 'on_chameleon_project': on_chameleon_project, 'geni_project_name': settings.GENI_FEDERATION_PROJECTS['geni']['name'], 'chameleon_project_name': settings.GENI_FEDERATION_PROJECTS['chameleon']['name'], } return render(request, 'dashboard.html', context)
def test_bad_id(self, mock_project): mock_project.side_effect = Exception('API Error: Object reference not set to an instance of an object.') with pytest.raises(Exception) as e: p = Project(123) assert 'API Error' in str(e.value)
def test_get(self, mock_project): mock_project.return_value = { "allocations": [ { "computeAllocated": 50000, "computeRequested": 50000, "computeUsed": 52774.149, "dateRequested": "2014-01-20T19:00:12Z", "dateReviewed": "2014-01-20T19:00:12Z", "decisionSummary": "Project Approved.", "end": "2015-01-20T06:00:00Z", "id": 456, "justification": "Resource justification.", "memoryAllocated": 0, "memoryRequested": 0, "project": "TEST-123456", "projectId": 23567, "requestor": "PI User", "requestorId": 123000, "resource": "Stampede3", "resourceId": 31, "reviewer": None, "reviewerId": 0, "start": "2014-01-21T06:00:00Z", "status": "Active", "storageAllocated": 0, "storageRequested": 0 } ], "chargeCode": "TEST-123456", "description": "TEST-123456", "field": "Testing", "fieldId": 100, "gid": 123000, "id": 123, "pi": { "citizenship": "United States", "citizenshipId": 230, "country": "United States", "countryId": 230, "department": None, "departmentId": 0, "email": "*****@*****.**", "emailConfirmations": [], "firstName": "PI", "id": 17033, "institution": "University College", "institutionId": 999, "lastName": "User", "phone": None, "piEligibility": "Eligible", "source": "Standard", "title": None, "username": "******" }, "piId": 999999, "source": "Standard", "title": "Lorem ipsum", "type": "Research", "typeId": 0 } p = Project(123) assert p.id == 123
def view_project(request, project_id): try: project = Project(project_id) if project.source != 'Chameleon': raise Http404('The requested project does not exist!') except Exception as e: logger.error(e) raise Http404('The requested project does not exist!') if request.POST: if 'add_user' in request.POST: form = ProjectAddUserForm(request.POST) if form.is_valid(): # try to add user try: add_username = form.cleaned_data['username'] if project.add_user(add_username): messages.success(request, 'User "%s" added to project!' % add_username) form = ProjectAddUserForm() except: logger.exception('Failed adding user') form.add_error('username', '') form.add_error('__all__', 'Unable to add user. Confirm that the ' 'username is correct.') else: form.add_error('__all__', 'There were errors processing your request. ' 'Please see below for details.') else: form = ProjectAddUserForm() if 'del_user' in request.POST: # try to remove user try: del_username = request.POST['username'] if project.remove_user(del_username): messages.success(request, 'User "%s" removed from project' % del_username) except: logger.exception('Failed removing user') messages.error(request, 'An unexpected error occurred while attempting ' 'to remove this user. Please try again') else: form = ProjectAddUserForm() users = project.get_users() if not project_member_or_admin_or_superuser(request.user, project, users): raise PermissionDenied project.active_allocations = [] project.pending_allocations = [] project.rejected_allocations = [] project.inactive_allocations = [] for a in project.allocations: if a.status == 'Active' and a.resource == 'Chameleon': project.active_allocations.append(a) project.has_active_allocations = True if a.status == 'Pending' and a.resource == 'Chameleon': project.pending_allocations.append(a) project.has_pending_allocations = True if a.status == 'Inactive' and a.resource == 'Chameleon': project.inactive_allocations.append(a) project.has_inactive_allocations = True if a.status == 'Rejected' and a.resource == 'Chameleon': project.rejected_allocations.append(a) project.has_rejected_allocations = True if a.start and isinstance(a.start, basestring): a.start = datetime.strptime(a.start, '%Y-%m-%dT%H:%M:%SZ') if a.dateRequested: if isinstance(a.dateRequested, basestring): a.dateRequested = datetime.strptime(a.dateRequested, '%Y-%m-%dT%H:%M:%SZ') if a.dateReviewed: if isinstance(a.dateReviewed, basestring): a.dateReviewed = datetime.strptime(a.dateReviewed, '%Y-%m-%dT%H:%M:%SZ') if a.end: if isinstance(a.end, basestring): a.end = datetime.strptime(a.end, '%Y-%m-%dT%H:%M:%SZ') days_left = (a.end - datetime.today()).days if days_left >= 0 and days_left <= 90: a.up_for_renewal = True a.renewal_days = days_left return render(request, 'projects/view_project.html', { 'project': project, 'users': users, 'is_pi': request.user.username == project.pi.username, 'form': form, })
def create_allocation(request, project_id, allocation_id=-1): tas = TASClient() user = tas.get_user(username=request.user) if user['piEligibility'] != 'Eligible': messages.error(request, 'Only PI Eligible users can request allocations. If you would ' 'like to request PI Eligibility, please ' '<a href="/user/profile/edit/">submit a PI Eligibility ' 'request</a>.') return HttpResponseRedirect(reverse('projects:user_projects')) project = Project(project_id) allocation = None if allocation_id > 0: for a in project.allocations: if a.id == int(allocation_id): allocation = a # goofiness that we should clean up later; requires data cleansing abstract = project.description if '--- Supplemental details ---' in abstract: additional = abstract.split('\n\n--- Supplemental details ---\n\n') abstract = additional[0] additional = additional[1].split('\n\n--- Funding source(s) ---\n\n') justification = additional[0] if len(additional) > 1: funding_source = additional[1] else: funding_source = '' elif allocation: justification = allocation.justification if '--- Funding source(s) ---' in justification: parts = justification.split('\n\n--- Funding source(s) ---\n\n') justification = parts[0] funding_source = parts[1] else: funding_source = '' else: justification = '' funding_source = '' if request.POST: form = AllocationCreateForm(request.POST, initial={'description': abstract, 'supplemental_details': justification, 'funding_source': funding_source}) if form.is_valid(): allocation = form.cleaned_data.copy() allocation['computeRequested'] = 20000 # Also update the project project.description = allocation.pop('description', None) supplemental_details = allocation.pop('supplemental_details', None) logger.error(supplemental_details) funding_source = allocation.pop('funding_source', None) #if supplemental_details == None: # raise forms.ValidationError("Justifcation is required") # This is required if not supplemental_details: supplemental_details = '(none)' logger.error(supplemental_details) if funding_source: allocation['justification'] = '%s\n\n--- Funding source(s) ---\n\n%s' % ( supplemental_details, funding_source) else: allocation['justification'] = supplemental_details allocation['projectId'] = project_id allocation['requestorId'] = tas.get_user(username=request.user)['id'] allocation['resourceId'] = '39' if allocation_id > 0: allocation['id'] = allocation_id try: logger.info('Submitting allocation request for project %s: %s' % (project.id, allocation)) updated_project = tas.edit_project(project.as_dict()) tas.create_allocation(allocation) messages.success(request, 'Your allocation request has been submitted!') return HttpResponseRedirect( reverse('projects:view_project', args=[updated_project['id']])) except: logger.exception('Error creating allocation') form.add_error('__all__', 'An unexpected error occurred. Please try again') else: form.add_error('__all__', 'There were errors processing your request. ' 'Please see below for details.') else: form = AllocationCreateForm(initial={'description': abstract, 'supplemental_details': justification, 'funding_source': funding_source}) context = { 'form': form, 'project': project, 'alloc_id': allocation_id, 'alloc': allocation } return render(request, 'projects/create_allocation.html', context)
def view_project(request, project_id): try: project = Project(project_id) if project.source != 'Chameleon': raise Http404('The requested project does not exist!') except Exception as e: logger.error(e) raise Http404('The requested project does not exist!') if request.POST: if 'add_user' in request.POST: form = ProjectAddUserForm(request.POST) if form.is_valid(): # try to add user try: add_username = form.cleaned_data['username'] if project.add_user(add_username): messages.success( request, 'User "%s" added to project!' % add_username) form = ProjectAddUserForm() except: logger.exception('Failed adding user') form.add_error('username', '') form.add_error( '__all__', 'Unable to add user. Confirm that the ' 'username is correct.') else: form.add_error( '__all__', 'There were errors processing your request. ' 'Please see below for details.') else: form = ProjectAddUserForm() if 'del_user' in request.POST: # try to remove user try: del_username = request.POST['username'] if project.remove_user(del_username): messages.success( request, 'User "%s" removed from project' % del_username) except: logger.exception('Failed removing user') messages.error( request, 'An unexpected error occurred while attempting ' 'to remove this user. Please try again') else: form = ProjectAddUserForm() users = project.get_users() if not project_member_or_admin_or_superuser(request.user, project, users): raise PermissionDenied project.active_allocations = [] project.approved_allocations = [] project.pending_allocations = [] project.rejected_allocations = [] project.inactive_allocations = [] for a in project.allocations: if a.status == 'Active' and a.resource == 'Chameleon': project.active_allocations.append(a) project.has_active_allocations = True if a.status == 'Approved' and a.resource == 'Chameleon': project.approved_allocations.append(a) project.has_approved_allocations = True if a.status == 'Pending' and a.resource == 'Chameleon': project.pending_allocations.append(a) project.has_pending_allocations = True if a.status == 'Inactive' and a.resource == 'Chameleon': project.inactive_allocations.append(a) project.has_inactive_allocations = True if a.status == 'Rejected' and a.resource == 'Chameleon': project.rejected_allocations.append(a) project.has_rejected_allocations = True if a.start and isinstance(a.start, basestring): a.start = datetime.strptime(a.start, '%Y-%m-%dT%H:%M:%SZ') if a.dateRequested: if isinstance(a.dateRequested, basestring): a.dateRequested = datetime.strptime(a.dateRequested, '%Y-%m-%dT%H:%M:%SZ') if a.dateReviewed: if isinstance(a.dateReviewed, basestring): a.dateReviewed = datetime.strptime(a.dateReviewed, '%Y-%m-%dT%H:%M:%SZ') if a.end: if isinstance(a.end, basestring): a.end = datetime.strptime(a.end, '%Y-%m-%dT%H:%M:%SZ') days_left = (a.end - datetime.today()).days if days_left >= 0 and days_left <= 90: a.up_for_renewal = True a.renewal_days = days_left return render( request, 'projects/view_project.html', { 'project': project, 'users': users, 'is_pi': request.user.username == project.pi.username, 'form': form, })
def create_allocation(request, project_id, allocation_id=-1): tas = TASClient() user = tas.get_user(username=request.user) if user['piEligibility'] != 'Eligible': messages.error( request, 'Only PI Eligible users can request allocations. If you would ' 'like to request PI Eligibility, please ' '<a href="/user/profile/edit/">submit a PI Eligibility ' 'request</a>.') return HttpResponseRedirect(reverse('projects:user_projects')) project = Project(project_id) allocation = None if allocation_id > 0: for a in project.allocations: if a.id == int(allocation_id): allocation = a # goofiness that we should clean up later; requires data cleansing abstract = project.description if '--- Supplemental details ---' in abstract: additional = abstract.split('\n\n--- Supplemental details ---\n\n') abstract = additional[0] additional = additional[1].split('\n\n--- Funding source(s) ---\n\n') justification = additional[0] if len(additional) > 1: funding_source = additional[1] else: funding_source = '' elif allocation: justification = allocation.justification if '--- Funding source(s) ---' in justification: parts = justification.split('\n\n--- Funding source(s) ---\n\n') justification = parts[0] funding_source = parts[1] else: funding_source = '' else: justification = '' funding_source = '' if request.POST: form = AllocationCreateForm(request.POST, initial={ 'description': abstract, 'supplemental_details': justification, 'funding_source': funding_source }) if form.is_valid(): allocation = form.cleaned_data.copy() allocation['computeRequested'] = 20000 # Also update the project project.description = allocation.pop('description', None) supplemental_details = allocation.pop('supplemental_details', None) logger.error(supplemental_details) funding_source = allocation.pop('funding_source', None) #if supplemental_details == None: # raise forms.ValidationError("Justifcation is required") # This is required if not supplemental_details: supplemental_details = '(none)' logger.error(supplemental_details) if funding_source: allocation[ 'justification'] = '%s\n\n--- Funding source(s) ---\n\n%s' % ( supplemental_details, funding_source) else: allocation['justification'] = supplemental_details allocation['projectId'] = project_id allocation['requestorId'] = tas.get_user( username=request.user)['id'] allocation['resourceId'] = '39' if allocation_id > 0: allocation['id'] = allocation_id try: logger.info( 'Submitting allocation request for project %s: %s' % (project.id, allocation)) updated_project = tas.edit_project(project.as_dict()) tas.create_allocation(allocation) messages.success( request, 'Your allocation request has been submitted!') return HttpResponseRedirect( reverse('projects:view_project', args=[updated_project['id']])) except: logger.exception('Error creating allocation') form.add_error( '__all__', 'An unexpected error occurred. Please try again') else: form.add_error( '__all__', 'There were errors processing your request. ' 'Please see below for details.') else: form = AllocationCreateForm( initial={ 'description': abstract, 'supplemental_details': justification, 'funding_source': funding_source }) context = { 'form': form, 'project': project, 'alloc_id': allocation_id, 'alloc': allocation } return render(request, 'projects/create_allocation.html', context)
def view_project(request, project_id): try: project = Project(project_id) if project.source != 'Chameleon': raise Http404('The requested project does not exist!') except Exception as e: logger.error(e) raise Http404('The requested project does not exist!') form = ProjectAddUserForm() nickname_form = EditNicknameForm() if request.POST: if 'add_user' in request.POST: form = ProjectAddUserForm(request.POST) if form.is_valid(): # try to add user try: add_username = form.cleaned_data['username'] if project.add_user(add_username): messages.success(request, 'User "%s" added to project!' % add_username) form = ProjectAddUserForm() except: logger.exception('Failed adding user') form.add_error('username', '') form.add_error('__all__', 'Unable to add user. Confirm that the ' 'username is correct.') else: form.add_error('__all__', 'There were errors processing your request. ' 'Please see below for details.') elif 'nickname' in request.POST: nickname_form = edit_nickname(request, project_id) else: form = ProjectAddUserForm() if 'del_user' in request.POST: # try to remove user try: del_username = request.POST['username'] if project.remove_user(del_username): messages.success(request, 'User "%s" removed from project' % del_username) except: logger.exception('Failed removing user') messages.error(request, 'An unexpected error occurred while attempting ' 'to remove this user. Please try again') users = project.get_users() if not project_member_or_admin_or_superuser(request.user, project, users): raise PermissionDenied project.active_allocations = [] project.approved_allocations = [] project.pending_allocations = [] project.rejected_allocations = [] project.inactive_allocations = [] for a in project.allocations: if a.status == 'Active' and a.resource == 'Chameleon': project.active_allocations.append(a) project.has_active_allocations = True if a.status == 'Approved' and a.resource == 'Chameleon': project.approved_allocations.append(a) project.has_approved_allocations = True if a.status == 'Pending' and a.resource == 'Chameleon': project.pending_allocations.append(a) project.has_pending_allocations = True if a.status == 'Inactive' and a.resource == 'Chameleon': project.inactive_allocations.append(a) project.has_inactive_allocations = True if a.status == 'Rejected' and a.resource == 'Chameleon': project.rejected_allocations.append(a) project.has_rejected_allocations = True if a.start and isinstance(a.start, basestring): a.start = datetime.strptime(a.start, '%Y-%m-%dT%H:%M:%SZ') if a.dateRequested: if isinstance(a.dateRequested, basestring): a.dateRequested = datetime.strptime(a.dateRequested, '%Y-%m-%dT%H:%M:%SZ') if a.dateReviewed: if isinstance(a.dateReviewed, basestring): a.dateReviewed = datetime.strptime(a.dateReviewed, '%Y-%m-%dT%H:%M:%SZ') if a.end: if isinstance(a.end, basestring): a.end = datetime.strptime(a.end, '%Y-%m-%dT%H:%M:%SZ') days_left = (a.end - datetime.today()).days if days_left >= 0 and days_left <= 90: a.up_for_renewal = True a.renewal_days = days_left try: extras = ProjectExtras.objects.get(tas_project_id=project_id) project_nickname = extras.nickname except ProjectExtras.DoesNotExist: project_nickname = None user_mashup = [] for u in users: if u.role == 'PI': # Exclude PI from member list continue user = {} user['username'] = u.username user['role'] = u.role try: portal_user = User.objects.get(username=u.username) user['email'] = portal_user.email user['first_name'] = portal_user.first_name user['last_name'] = portal_user.last_name except User.DoesNotExist: logger.info('user: '******' not found') user_mashup.append(user) return render(request, 'projects/view_project.html', { 'project': project, 'project_nickname': project_nickname, 'users': user_mashup, 'is_pi': request.user.username == project.pi.username, 'form': form, 'nickname_form': nickname_form, })