def view_project(request, project_id): mapper = ProjectAllocationMapper(request) try: project = mapper.get_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() pubs_form = AddBibtexPublicationForm() if request.POST and project_pi_or_admin_or_superuser( request.user, project): form = ProjectAddUserForm() if "add_user" in request.POST: form = ProjectAddUserForm(request.POST) if form.is_valid(): try: add_username = form.cleaned_data["username"] if mapper.add_user_to_project(project, add_username): sync_project_memberships(request, add_username) messages.success( request, f'User "{add_username}" added to project!') form = ProjectAddUserForm() except Exception as e: logger.exception("Failed adding user") messages.error( request, ("Unable to add user. Confirm that the username is " "correct and corresponds to a current Chameleon user." ), ) else: messages.error( request, ("There were errors processing your request. " "Please see below for details."), ) elif "del_user" in request.POST: try: del_username = request.POST["username"] # Ensure that it's not possible to remove the PI if del_username == project.pi.username: raise PermissionDenied( "Removing the PI from the project is not allowed.") if mapper.remove_user_from_project(project, del_username): sync_project_memberships(request, del_username) messages.success( request, 'User "%s" removed from project' % del_username) except PermissionDenied as exc: messages.error(request, exc) except: logger.exception("Failed removing user") messages.error( request, "An unexpected error occurred while attempting " "to remove this user. Please try again", ) elif "nickname" in request.POST: nickname_form = edit_nickname(request, project_id) users = mapper.get_project_members(project) if not project_member_or_admin_or_superuser(request.user, project, users): raise PermissionDenied for a in project.allocations: if a.start and isinstance(a.start, str): a.start = datetime.strptime(a.start, "%Y-%m-%dT%H:%M:%SZ") if a.dateRequested: if isinstance(a.dateRequested, str): a.dateRequested = datetime.strptime(a.dateRequested, "%Y-%m-%dT%H:%M:%SZ") if a.dateReviewed: if isinstance(a.dateReviewed, str): a.dateReviewed = datetime.strptime(a.dateReviewed, "%Y-%m-%dT%H:%M:%SZ") if a.end: if isinstance(a.end, str): a.end = datetime.strptime(a.end, "%Y-%m-%dT%H:%M:%SZ") user_mashup = [] for u in users: user = { "username": u.username, "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, "pubs_form": pubs_form, }, )
def view_project(request, project_id): mapper = ProjectAllocationMapper(request) keycloak_client = KeycloakClient() try: project = mapper.get_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() type_form_args = {"request": request} type_form = EditTypeForm(**type_form_args) pubs_form = AddBibtexPublicationForm() can_manage_project_membership, can_manage_project = get_user_permissions( keycloak_client, request.user.username, project) if (request.POST and can_manage_project_membership or is_admin_or_superuser(request.user)): form = ProjectAddUserForm() if "add_user" in request.POST: form = ProjectAddUserForm(request.POST) if form.is_valid(): try: add_username = form.cleaned_data["user_ref"] user = User.objects.get(username=add_username) if mapper.add_user_to_project(project, add_username): messages.success( request, f'User "{add_username}" added to project!') form = ProjectAddUserForm() except User.DoesNotExist: # Try sending an invite email_address = form.cleaned_data["user_ref"] try: validate_email(email_address) if email_exists_on_project(project, email_address): messages.error( request, "That email is tied to a user already on the " "project!", ) else: add_project_invitation( project_id, email_address, request.user, request, None, ) messages.success(request, "Invite sent!") except ValidationError: messages.error( request, ("Unable to add user. Confirm that the username " "is correct and corresponds to a current " "Chameleon user. You can also send an invite " "to an email address if the user does not yet " "have an account."), ) except Exception: messages.error( request, "Problem sending invite, please try again.") except Exception: logger.exception("Failed adding user") messages.error(request, "Unable to add user. Please try again.") else: messages.error( request, ("There were errors processing your request. " "Please see below for details."), ) elif "del_user" in request.POST: try: del_username = request.POST["user_ref"] # Ensure that it's not possible to remove the PI if del_username in [project.pi.username, project.pi.email]: raise PermissionDenied( "Removing the PI from the project is not allowed.") if mapper.remove_user_from_project(project, del_username): messages.success( request, 'User "%s" removed from project' % del_username) user = User.objects.get(username=del_username) daypass = get_daypass(user.id, project_id) if daypass: daypass.delete() except PermissionDenied as exc: messages.error(request, exc) except Exception: logger.exception("Failed removing user") messages.error( request, "An unexpected error occurred while attempting " "to remove this user. Please try again", ) elif "change_role" in request.POST: try: role_username = request.POST["user_ref"] role_name = request.POST["user_role"].lower() keycloak_client.set_user_project_role(role_username, get_charge_code(project), role_name) except Exception: logger.exception("Failed to change user role") messages.error( request, "An unexpected error occurred while attempting " "to change role for this user. Please try again", ) elif "del_invite" in request.POST: try: invite_id = request.POST["invite_id"] remove_invitation(invite_id) messages.success(request, "Invitation removed") except Exception: logger.exception("Failed to delete invitation") messages.error( request, "An unexpected error occurred while attempting " "to remove this invitation. Please try again", ) elif "resend_invite" in request.POST: try: invite_id = request.POST["invite_id"] resend_invitation(invite_id, request.user, request) messages.success(request, "Invitation resent") except Exception: logger.exception("Failed to resend invitation") messages.error( request, "An unexpected error occurred while attempting " "to resend this invitation. Please try again") elif "nickname" in request.POST: nickname_form = edit_nickname(request, project_id) elif "typeId" in request.POST: type_form = edit_type(request, project_id) for a in project.allocations: if a.start and isinstance(a.start, str): a.start = datetime.strptime(a.start, "%Y-%m-%dT%H:%M:%SZ") if a.dateRequested: if isinstance(a.dateRequested, str): a.dateRequested = datetime.strptime(a.dateRequested, "%Y-%m-%dT%H:%M:%SZ") if a.dateReviewed: if isinstance(a.dateReviewed, str): a.dateReviewed = datetime.strptime(a.dateReviewed, "%Y-%m-%dT%H:%M:%SZ") if a.end: if isinstance(a.end, str): a.end = datetime.strptime(a.end, "%Y-%m-%dT%H:%M:%SZ") users = get_project_members(project) if not project_member_or_admin_or_superuser(request.user, project, users): raise PermissionDenied user_roles = keycloak_client.get_roles_for_all_project_members( get_charge_code(project)) users_mashup = [] for u in users: if u.username == project.pi.username: continue u_role = user_roles.get(u.username, "member") user = { "id": u.id, "username": u.username, "role": u_role.title(), } 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 # Add if the user is on a daypass existing_daypass = get_daypass(portal_user.id, project_id) if existing_daypass: user["daypass"] = format_timedelta( existing_daypass.date_exceeds_duration() - timezone.now()) except User.DoesNotExist: logger.info("user: "******" not found") users_mashup.append(user) invitations = Invitation.objects.filter(project=project_id) invitations = [i for i in invitations if i.can_accept()] clean_invitations = [] for i in invitations: new_item = {} new_item["email_address"] = i.email_address new_item["id"] = i.id new_item["status"] = i.status.title() if i.duration: new_item["duration"] = i.duration clean_invitations.append(new_item) is_on_daypass = get_daypass(request.user.id, project_id) is not None return render( request, "projects/view_project.html", { "project": project, "project_nickname": project.nickname, "project_type": project.type, "users": users_mashup, "invitations": clean_invitations, "can_manage_project_membership": can_manage_project_membership, "can_manage_project": can_manage_project, "is_admin": request.user.is_superuser, "is_on_daypass": is_on_daypass, "form": form, "nickname_form": nickname_form, "type_form": type_form, "pubs_form": pubs_form, "roles": ROLES, "host": request.get_host(), }, )