Beispiel #1
0
    def _update_user_membership(self, tas_project, username, action=None):
        if action not in ["add", "delete"]:
            raise ValueError("Invalid membership action {}".format(action))

        charge_code = self.get_attr(tas_project, "chargeCode")
        keycloak_client = KeycloakClient()
        keycloak_client.update_membership(charge_code, username, action)
Beispiel #2
0
    def save_project(self, proj, host=None):
        allocations = self.get_attr(proj, "allocations")
        reformated_proj = self.tas_to_portal_proj_obj(proj)
        reformated_proj.save()
        if reformated_proj.charge_code.startswith(
                TMP_PROJECT_CHARGE_CODE_PREFIX):
            # save project in portal
            new_proj = portal_proj.objects.filter(
                charge_code=reformated_proj.charge_code)
            if len(new_proj) == 0:
                logger.error(
                    f"Couldn't find project {reformated_proj.charge_code}")
            else:
                new_proj = new_proj[0]
                valid_charge_code = ("CHI-" + str(datetime.today().year)[2:] +
                                     str(new_proj.id).zfill(4))
                new_proj.charge_code = valid_charge_code
                new_proj.save()
                reformated_proj.charge_code = valid_charge_code

                # create allocation
                self.save_allocation(allocations[0], valid_charge_code, host)

                # save project in keycloak
                keycloak_client = KeycloakClient()
                keycloak_client.create_project(valid_charge_code,
                                               new_proj.pi.username)

        return self.portal_to_tas_proj_obj(reformated_proj,
                                           fetch_allocations=False)
Beispiel #3
0
def end_daypasses():
    beyond_duration_invitations = get_invitations_beyond_duration()
    for invitation in beyond_duration_invitations:
        try:
            LOG.info(f"Removing user from project with invite {invitation.id}\n")
            project = Project.objects.get(pk=invitation.project_id)
            user = User.objects.get(pk=invitation.user_accepted_id)
            keycloak_client = KeycloakClient()
            keycloak_client.update_membership(
                project.charge_code, user.username, "delete"
            )
            invitation.status = Invitation.STATUS_BEYOND_DURATION
            invitation.save()

            try:
                daypass_request = DaypassRequest.objects.get(invitation=invitation)
                approved_requests = (
                    DaypassRequest.objects.all()
                    .filter(
                        artifact=daypass_request.artifact,
                        status=DaypassRequest.STATUS_APPROVED,
                        invitation__status=Invitation.STATUS_BEYOND_DURATION,
                    )
                    .count()
                )
                if approved_requests == settings.DAYPASS_LIMIT:
                    # Send an email
                    handle_too_many_daypass_users(daypass_request.artifact)
            except DaypassRequest.DoesNotExist:
                pass
        except Exception as e:
            LOG.error(f"Error ending daypass invite {invitation.id}: {e}")
Beispiel #4
0
def get_all_alloc(request):
    """Get all allocations, grouped by project.

    Args:
        request: the request that is passed in.

    Raises:
        Exception: when loading projects fails.

    Returns:
        json: dumps all data as serialized json.
    """
    try:
        keycloak_client = KeycloakClient()
        user_attributes = keycloak_client.get_all_users_attributes()
        mapper = ProjectAllocationMapper(request)
        resp = mapper.get_all_projects()
        logger.debug("Total projects: %s", len(resp))
        for r in resp:
            pi_attributes = user_attributes.get(r["pi"]["username"], {})
            if pi_attributes:
                institution = pi_attributes.get("affiliationInstitution", [])
                country = pi_attributes.get("country", [])
                r["pi"]["institution"] = next(iter(institution), None)
                r["pi"]["country"] = next(iter(country), None)
    except Exception as e:
        logger.exception("Error loading chameleon projects")
        messages.error(request, e)
        raise
    return json.dumps(resp)
Beispiel #5
0
    def update_user_profile(self, user, new_profile,
                            is_request_pi_eligibililty):
        keycloak_client = KeycloakClient()

        if is_request_pi_eligibililty:
            pie_request = PIEligibility()
            pie_request.requestor_id = user.id
            pie_request.save()
            self._create_ticket_for_pi_request(user)

        email = new_profile.get("email")
        keycloak_client.update_user(
            user.username,
            email=email,
            affiliation_title=new_profile.get("title"),
            affiliation_department=new_profile.get("department"),
            affiliation_institution=new_profile.get("institution"),
            country=new_profile.get("country"),
            citizenship=new_profile.get("citizenship"),
            phone=new_profile.get("phone"),
        )
        # The email normally is saved during login; in this case we can
        # immediately persist the change for better UX.
        if email is not None:
            user.email = email
            user.save()
Beispiel #6
0
def add_openstack_data(self, **kwargs):
    ticket_id = kwargs.get("ticket_id")
    username = kwargs.get("username")

    messages = []
    bound_task = self

    def write_message(progress_pct, message):
        LOG.info(message)
        messages.append(message)
        bound_task.update_state(
            state="PROGRESS",
            meta={
                "messages": messages,
                "progress_pct": progress_pct,
            },
        )

    try:
        if username:
            keycloak_client = KeycloakClient()
            projects = keycloak_client.get_full_user_projects_by_username(
                username)

            regions = list(settings.OPENSTACK_AUTH_REGIONS.keys())
            region_list = []
            for i, region in enumerate(regions):
                try:
                    factor = (1.0 / len(regions)) * 100
                    write_message(factor * i, f'Processing region "{region}"')
                    region_list.append(
                        get_openstack_data(username, region, projects))
                except Exception as err:
                    LOG.error(
                        f"Failed to get OpenStack data for region {region}: {err}"
                    )
            openstack_user_data = remove_empty_lines(
                render_to_string("djangoRT/project_details.txt",
                                 {"regions": region_list}))
        else:
            openstack_user_data = "No openstack data for anonymous user."
        rt = rtUtil.DjangoRt()
        rt.commentOnTicket(ticket_id, openstack_user_data)
    except Exception as exc:
        LOG.exception("Failed to gather data")
        exc_message = getattr(exc, "message", None)
        if exc_message:
            messages.append(exc_message)
        raise OpenstackDataError(messages=messages) from exc
    # Return current state as last action
    return {
        "messages": messages,
        "progress_pct": 100.0,
    }
Beispiel #7
0
def get_project_members(project):
    users = []
    # try get members from keycloak
    keycloak_client = KeycloakClient()
    for username in keycloak_client.get_project_members(
            get_charge_code(project)):
        try:
            user = get_user_model().objects.get(username=username)
            users.append(user)
        except get_user_model().DoesNotExist:
            logger.exception(f"Could not get user model for {username}")
    return users
Beispiel #8
0
    def _update_user_membership(self, tas_project, user_ref, action=None):
        if action not in ["add", "delete"]:
            raise ValueError("Invalid membership action {}".format(action))

        UserModel = get_user_model()
        try:
            user = UserModel.objects.get(username=user_ref)
        except UserModel.DoesNotExist:
            user = UserModel.objects.get(email=user_ref)

        charge_code = self.get_attr(tas_project, "chargeCode")
        keycloak_client = KeycloakClient()
        keycloak_client.update_membership(charge_code, user.username, action)
Beispiel #9
0
 def get_project_members(self, tas_project):
     users = []
     # try get members from keycloak
     keycloak_client = KeycloakClient()
     pi_username = tas_project.pi.username
     for username in keycloak_client.get_project_members(
             tas_project.chargeCode):
         if username == pi_username:
             role = "PI"
         else:
             role = "Standard"
         user = self.get_user(username, to_pytas_model=True, role=role)
         if user:
             users.append(user)
     return users
Beispiel #10
0
def active_approved_allocations(balance_service):
    now = datetime.now(pytz.utc)

    approved_allocations = Allocation.objects.filter(status='approved',
                                                     start_date__lte=now)
    activated_alloc_count = 0
    for alloc in approved_allocations:
        charge_code = alloc.project.charge_code
        # deactivate active allocation for the project and set status to active
        project_active_allocations = Allocation.objects.filter(
            status='active', project_id=alloc.project.id)
        prev_alloc = None
        if len(project_active_allocations) > 0:
            prev_alloc = project_active_allocations[0]
        try:
            with transaction.atomic():
                if prev_alloc:
                    _deactivate_allocation(balance_service, prev_alloc)
                alloc.status = 'active'
                alloc.save()
                KeycloakClient().update_project(charge_code,
                                                has_active_allocation='true')
                # recharge balance service
                balance_service.recharge(charge_code, alloc.su_allocated)
                activated_alloc_count = activated_alloc_count + 1
        except Exception:
            logger.exception(f'Error activating project {charge_code}')

    logger.debug(
        'need to activated {} allocations, and {} were actually activated'.
        format(len(approved_allocations), activated_alloc_count))
Beispiel #11
0
    def keycloak_metadata(self, obj):
        """User metadata from keycloak backend. Returns a list of strings."""
        keycloak_client = KeycloakClient()
        keycloak_user = keycloak_client.get_user_by_username(
            obj.requestor.username)

        if not keycloak_user:
            return "No Keycloak User Found"

        full_name = "{} {}".format(keycloak_user["lastName"],
                                   keycloak_user["firstName"])
        email = keycloak_user["email"]
        yield [f"Name: {full_name}", f"Email: {email}"]

        for key, val in keycloak_user["attributes"].items():
            if key not in ["joinDate"]:
                # convert camelcase to separate out words
                key = re.sub("([A-Z])", " \\1", key).strip().capitalize()
                yield [(f"{key}: {val}")]
Beispiel #12
0
def _deactivate_allocation(balance_service, alloc):
    charge_code = alloc.project.charge_code
    balance = balance_service.get_balance(charge_code) or {}
    if 'used' in balance and balance['used']:
        alloc.su_used = float(balance['used'])
    else:
        alloc.su_used = None
        logger.error(f'Couldn\'t find used balance for project {charge_code}')
    alloc.status = 'inactive'
    alloc.save()
    KeycloakClient().update_project(charge_code, has_active_allocation='false')
Beispiel #13
0
    def get_user_projects(self,
                          username,
                          alloc_status=[],
                          fetch_balance=True,
                          to_pytas_model=False):
        # get user projects from portal
        keycloak_client = KeycloakClient()
        charge_codes = keycloak_client.get_user_projects_by_username(username)
        projects_qs = portal_proj.objects.filter(charge_code__in=charge_codes)

        user_projects = [
            self.portal_to_tas_proj_obj(p, alloc_status=alloc_status)
            for p in self._with_relations(projects_qs,
                                          fetch_balance=fetch_balance)
        ]

        if to_pytas_model:
            return [tas_proj(initial=p) for p in user_projects]
        else:
            return user_projects
Beispiel #14
0
def _deactivate_allocation(alloc):
    balance = project_balances([alloc.project.id])
    if not balance:
        alloc.su_used = None
        LOG.error(f"Couldn't find used balance for project {alloc.project.charge_code}")
    else:
        balance = balance[0]
        alloc.su_used = balance["used"]
    alloc.status = "inactive"
    alloc.save()
    KeycloakClient().update_project(
        alloc.project.charge_code, has_active_allocation="false"
    )
Beispiel #15
0
    def update_user_metadata_from_keycloak(self, tas_formatted_user):
        keycloak_client = KeycloakClient()
        keycloak_user = keycloak_client.get_user_by_username(
            tas_formatted_user["username"])

        if keycloak_user:
            attrs = keycloak_user["attributes"]
            tas_formatted_user.update({
                "institution":
                attrs.get("affiliationInstitution", None),
                "department":
                attrs.get("affiliationDepartment", None),
                "title":
                attrs.get("affiliationTitle", None),
                "country":
                attrs.get("country", None),
                "phone":
                attrs.get("phone", None),
                "citizenship":
                attrs.get("citizenship", None),
            })
        return tas_formatted_user
Beispiel #16
0
def list_daypass_requests(request, **kwargs):
    keycloak_client = KeycloakClient()
    projects = [
        project["groupName"]
        for project in keycloak_client.get_user_roles(request.user.username)
        if manage_membership_in_scope(project["scopes"])
    ]
    pending_requests = (DaypassRequest.objects.all().filter(
        artifact__project__charge_code__in=projects,
        status=DaypassRequest.STATUS_PENDING,
    ).order_by("-created_at"))
    for daypass_request in pending_requests:
        daypass_request.url = reverse("sharing_portal:review_daypass",
                                      args=[daypass_request.id])
    reviewed_requests = (DaypassRequest.objects.all(
    ).exclude(status=DaypassRequest.STATUS_PENDING).filter(
        artifact__project__charge_code__in=projects).order_by("-created_at"))
    template = loader.get_template("sharing_portal/list_daypass_requests.html")
    context = {
        "pending_requests": pending_requests,
        "reviewed_requests": reviewed_requests,
    }
    return HttpResponse(template.render(context, request))
Beispiel #17
0
    def lazy_add_user_to_keycloak(self):
        keycloak_client = KeycloakClient()
        # check if user exist in keycloak
        keycloak_user = keycloak_client.get_user_by_username(self.current_user)
        if keycloak_user:
            return
        user = self.get_user(self.current_user)
        portal_user = self._get_user_from_portal_db(self.current_user)
        join_date = None
        if portal_user:
            join_date = datetime.timestamp(portal_user.date_joined)

        kwargs = {
            "first_name": user["firstName"],
            "last_name": user["lastName"],
            "email": user["email"],
            "affiliation_title": user["title"],
            "affiliation_department": user["department"],
            "affiliation_institution": user["institution"],
            "country": user["country"],
            "citizenship": user["citizenship"],
            "join_date": join_date,
        }
        keycloak_client.create_user(self.current_user, **kwargs)
Beispiel #18
0
def active_approved_allocations(balance_service):
    now = timezone.now()

    approved_allocations = Allocation.objects.filter(
        status="approved", start_date__lte=now
    )
    activated_alloc_count = 0
    for alloc in approved_allocations:
        charge_code = alloc.project.charge_code
        # deactivate active allocation for the project and set status to active
        project_active_allocations = Allocation.objects.filter(
            status="active", project_id=alloc.project.id
        )
        prev_alloc = None
        if len(project_active_allocations) > 0:
            prev_alloc = project_active_allocations[0]
        try:
            with transaction.atomic():
                if prev_alloc:
                    _deactivate_allocation(prev_alloc)
                    allocation_charges = Charge.objects.filter(
                        allocation__id=prev_alloc.id
                    )
                    # duplicate the ongoing charges
                    for c in allocation_charges:
                        if c.end_time > now:
                            _fork_charge(c, now, alloc)
                alloc.status = "active"
                alloc.save()
                # TODO: remove recharge external balance service
                # after retiring redis
                balance_service.recharge(charge_code, alloc.su_allocated)
                KeycloakClient().update_project(
                    charge_code, has_active_allocation="true"
                )

                activated_alloc_count = activated_alloc_count + 1
        except Exception:
            LOG.exception(f'Error activating project {charge_code}')
        LOG.info(f'Started allocation {alloc.id} for {charge_code}')

    LOG.debug('need to activated {} allocations, and {} were actually activated'.format(len(approved_allocations), activated_alloc_count))
Beispiel #19
0
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(),
        },
    )
Beispiel #20
0
def create_project(request):
    mapper = ProjectAllocationMapper(request)
    form_args = {"request": request}

    user = mapper.get_user(request.user.username)
    if user["piEligibility"].lower() != "eligible":
        messages.error(
            request,
            "Only PI Eligible users can create new projects. "
            "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"))
    if request.POST:
        form = ProjectCreateForm(request.POST, **form_args)
        allocation_form = AllocationCreateForm(
            request.POST, initial={"publication_up_to_date": True})
        allocation_form.fields[
            "publication_up_to_date"].widget = forms.HiddenInput()
        funding_formset = FundingFormset(request.POST, initial=[{}])
        consent_form = ConsentForm(request.POST)
        if (form.is_valid() and allocation_form.is_valid()
                and funding_formset.is_valid() and consent_form.is_valid()):
            # title, description, typeId, fieldId
            project = form.cleaned_data.copy()
            allocation_data = allocation_form.cleaned_data.copy()
            # let's check that any provided nickname is unique
            project["nickname"] = project["nickname"].strip()
            nickname_valid = (project["nickname"]
                              and ProjectExtras.objects.filter(
                                  nickname=project["nickname"]).count() < 1
                              and Project.objects.filter(
                                  nickname=project["nickname"]).count() < 1)

            if not nickname_valid:
                form.add_error("__all__", "Project nickname unavailable")
                return render(request, "projects/create_project.html",
                              {"form": form})

            # pi
            pi_user_id = mapper.get_portal_user_id(request.user.username)
            project["piId"] = pi_user_id

            # allocations
            allocation = {
                "resourceId": 39,
                "requestorId": pi_user_id,
                "computeRequested": 20000,
                "justification": allocation_data.pop("justification", None),
            }

            project["allocations"] = [allocation]
            project["description"] = allocation_data.pop("description", None)

            # source
            project["source"] = "Chameleon"
            created_project = None
            try:
                with transaction.atomic():
                    created_project = mapper.save_project(
                        project, request.get_host())
                    _save_fundings(funding_formset, created_project["id"])
                logger.info("newly created project: " +
                            json.dumps(created_project))
                messages.success(request, "Your project has been created!")
                return HttpResponseRedirect(
                    reverse("projects:view_project",
                            args=[created_project["id"]]))
            except:
                # delete project from keycloak
                if created_project:
                    keycloak_client = KeycloakClient()
                    keycloak_client.delete_project(
                        created_project["chargeCode"])
                logger.exception("Error creating project")
                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 = ProjectCreateForm(**form_args)
        allocation_form = AllocationCreateForm(
            initial={"publication_up_to_date": True})
        allocation_form.fields[
            "publication_up_to_date"].widget = forms.HiddenInput()
        funding_formset = FundingFormset(initial=[{}])
        consent_form = ConsentForm()

    return render(
        request,
        "projects/create_project.html",
        {
            "form": form,
            "allocation_form": allocation_form,
            "funding_formset": funding_formset,
            "consent_form": consent_form,
        },
    )
Beispiel #21
0
def is_membership_manager(project, username):
    keycloak_client = KeycloakClient()
    return get_user_permissions(keycloak_client, username, project)[0]