From f246ac5039af0df65cee37bf3f9ea5de536d9012 Mon Sep 17 00:00:00 2001 From: HejdaJakub Date: Tue, 29 Sep 2020 13:40:35 +0200 Subject: [PATCH] New method for getting sponsored members and their sponsors * We want to create a new method, which returns sponsored members and their sponsors for specific VO. * The method returns list of sponsored members (RichMembers) and for each of them list of users, who sponsor this sponsored member. * The returned object also have to be filtered - the method returns to the sponsor only members, who are sponsored by this sponsor. --- .../perun/core/api/MemberWithSponsors.java | 56 +++++++++++++++++++ perun-base/src/main/resources/perun-roles.yml | 18 ++++++ .../perun/core/api/MembersManager.java | 12 ++++ .../perun/core/bl/MembersManagerBl.java | 2 + .../core/blImpl/MembersManagerBlImpl.java | 10 +--- .../perun/core/entry/MembersManagerEntry.java | 44 ++++++++++++++- .../MembersManagerEntryIntegrationTest.java | 27 +++++++++ perun-openapi/openapi.yml | 31 ++++++++++ .../rpc/methods/MembersManagerMethod.java | 17 ++++++ 9 files changed, 206 insertions(+), 11 deletions(-) create mode 100644 perun-base/src/main/java/cz/metacentrum/perun/core/api/MemberWithSponsors.java diff --git a/perun-base/src/main/java/cz/metacentrum/perun/core/api/MemberWithSponsors.java b/perun-base/src/main/java/cz/metacentrum/perun/core/api/MemberWithSponsors.java new file mode 100644 index 0000000000..b4fa249ccf --- /dev/null +++ b/perun-base/src/main/java/cz/metacentrum/perun/core/api/MemberWithSponsors.java @@ -0,0 +1,56 @@ +package cz.metacentrum.perun.core.api; + +import java.util.List; +import java.util.Objects; + +/** + * Sponsored member with list of his sponsors (for GUI) + * + * @author Jakub Hejda + */ +public class MemberWithSponsors { + private RichMember member; + private List sponsors; + + /** + * Constructor + */ + public MemberWithSponsors() { + } + + /** + * Constructor + */ + public MemberWithSponsors(RichMember member) { + this.member = member; + } + + public Member getMember() { + return member; + } + + public void setMember(RichMember member) { + this.member = member; + } + + public List getSponsors() { + return sponsors; + } + + public void setSponsors(List sponsors) { + this.sponsors = sponsors; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + MemberWithSponsors that = (MemberWithSponsors) o; + return Objects.equals(member, that.member); + } + + @Override + public int hashCode() { + return Objects.hash(member); + } +} diff --git a/perun-base/src/main/resources/perun-roles.yml b/perun-base/src/main/resources/perun-roles.yml index 8427fa90d6..372afcc7e8 100644 --- a/perun-base/src/main/resources/perun-roles.yml +++ b/perun-base/src/main/resources/perun-roles.yml @@ -2323,6 +2323,24 @@ perun_policies: include_policies: - default_policy + getSponsoredMembersAndTheirSponsors_Vo_policy: + policy_roles: + - VOADMIN: Vo + - VOOBSERVER: Vo + - PERUNOBSERVER: + - SPONSOR: Vo + include_policies: + - default_policy + + filter-getSponsoredMembersAndTheirSponsors_Vo_policy: + policy_roles: + - VOADMIN: Vo + - VOOBSERVER: Vo + - PERUNOBSERVER: + - SPONSOR: Member + include_policies: + - default_policy + extendExpirationForSponsoredMember_Member_User_policy: policy_roles: - REGISTRAR: diff --git a/perun-core/src/main/java/cz/metacentrum/perun/core/api/MembersManager.java b/perun-core/src/main/java/cz/metacentrum/perun/core/api/MembersManager.java index b083513d8b..da6aef031a 100644 --- a/perun-core/src/main/java/cz/metacentrum/perun/core/api/MembersManager.java +++ b/perun-core/src/main/java/cz/metacentrum/perun/core/api/MembersManager.java @@ -1271,6 +1271,18 @@ public interface MembersManager { */ List getSponsoredMembers(PerunSession sess, Vo vo) throws PrivilegeException, VoNotExistsException; + /** + * Gets list of sponsored members with sponsors. + * + * @param sess session + * @param vo virtual organization from which are the sponsored members chosen + * @param attrNames list of attrNames for selected attributes + * @throws VoNotExistsException if given VO does not exist + * @throws PrivilegeException if not VOADMIN, VOOBSERVER, PERUNOBSERVER or SPONSOR + * @return list of members with sponsors + */ + List getSponsoredMembersAndTheirSponsors(PerunSession sess, Vo vo, List attrNames) throws VoNotExistsException, PrivilegeException, AttributeNotExistsException; + /** * Extends expiration date. Sponsored members cannot apply for membership extension, this method allows a sponsor to extend it. * @param session actor diff --git a/perun-core/src/main/java/cz/metacentrum/perun/core/bl/MembersManagerBl.java b/perun-core/src/main/java/cz/metacentrum/perun/core/bl/MembersManagerBl.java index 29df050c56..9420e76f88 100644 --- a/perun-core/src/main/java/cz/metacentrum/perun/core/bl/MembersManagerBl.java +++ b/perun-core/src/main/java/cz/metacentrum/perun/core/bl/MembersManagerBl.java @@ -7,9 +7,11 @@ import cz.metacentrum.perun.core.api.Group; import cz.metacentrum.perun.core.api.Member; import cz.metacentrum.perun.core.api.MemberGroupStatus; +import cz.metacentrum.perun.core.api.MemberWithSponsors; import cz.metacentrum.perun.core.api.PerunSession; import cz.metacentrum.perun.core.api.Resource; import cz.metacentrum.perun.core.api.RichMember; +import cz.metacentrum.perun.core.api.RichUser; import cz.metacentrum.perun.core.api.SpecificUserType; import cz.metacentrum.perun.core.api.Status; import cz.metacentrum.perun.core.api.User; diff --git a/perun-core/src/main/java/cz/metacentrum/perun/core/blImpl/MembersManagerBlImpl.java b/perun-core/src/main/java/cz/metacentrum/perun/core/blImpl/MembersManagerBlImpl.java index cbd43087f5..2e7148d305 100644 --- a/perun-core/src/main/java/cz/metacentrum/perun/core/blImpl/MembersManagerBlImpl.java +++ b/perun-core/src/main/java/cz/metacentrum/perun/core/blImpl/MembersManagerBlImpl.java @@ -5,8 +5,6 @@ import cz.metacentrum.perun.audit.events.MembersManagerEvents.MemberDisabled; import cz.metacentrum.perun.audit.events.MembersManagerEvents.MemberExpired; import cz.metacentrum.perun.audit.events.MembersManagerEvents.MemberInvalidated; -import cz.metacentrum.perun.audit.events.MembersManagerEvents.MemberSuspended; -import cz.metacentrum.perun.audit.events.MembersManagerEvents.MemberUnsuspended; import cz.metacentrum.perun.audit.events.MembersManagerEvents.MemberValidated; import cz.metacentrum.perun.audit.events.MembersManagerEvents.MemberValidatedFailed; import cz.metacentrum.perun.audit.events.MembersManagerEvents.SponsoredMemberSet; @@ -67,9 +65,7 @@ import cz.metacentrum.perun.core.api.exceptions.NotGroupMemberException; import cz.metacentrum.perun.core.api.exceptions.ParentGroupNotExistsException; import cz.metacentrum.perun.core.api.exceptions.PasswordCreationFailedException; -import cz.metacentrum.perun.core.api.exceptions.PasswordOperationTimeoutException; import cz.metacentrum.perun.core.api.exceptions.PasswordStrengthException; -import cz.metacentrum.perun.core.api.exceptions.PasswordStrengthFailedException; import cz.metacentrum.perun.core.api.exceptions.RelationExistsException; import cz.metacentrum.perun.core.api.exceptions.SubjectNotExistsException; import cz.metacentrum.perun.core.api.exceptions.UserExtSourceExistsException; @@ -82,7 +78,6 @@ import cz.metacentrum.perun.core.api.exceptions.WrongReferenceAttributeValueException; import cz.metacentrum.perun.core.bl.MembersManagerBl; import cz.metacentrum.perun.core.bl.PerunBl; -import cz.metacentrum.perun.core.impl.Auditer; import cz.metacentrum.perun.core.impl.PerunSessionImpl; import cz.metacentrum.perun.core.impl.Utils; import cz.metacentrum.perun.core.implApi.ExtSourceApi; @@ -90,11 +85,10 @@ import cz.metacentrum.perun.core.implApi.MembersManagerImplApi; import cz.metacentrum.perun.core.implApi.modules.attributes.AbstractMembershipExpirationRulesModule; import cz.metacentrum.perun.core.implApi.modules.pwdmgr.PasswordManagerModule; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import java.sql.Timestamp; -import java.text.SimpleDateFormat; import java.time.Instant; import java.time.LocalDate; import java.time.ZoneId; @@ -102,10 +96,8 @@ import java.time.temporal.ChronoUnit; import java.time.temporal.TemporalUnit; import java.util.ArrayList; -import java.util.Calendar; import java.util.Collections; import java.util.Date; -import java.util.GregorianCalendar; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedHashMap; diff --git a/perun-core/src/main/java/cz/metacentrum/perun/core/entry/MembersManagerEntry.java b/perun-core/src/main/java/cz/metacentrum/perun/core/entry/MembersManagerEntry.java index 18c33d2c97..0a3f4e30d9 100644 --- a/perun-core/src/main/java/cz/metacentrum/perun/core/entry/MembersManagerEntry.java +++ b/perun-core/src/main/java/cz/metacentrum/perun/core/entry/MembersManagerEntry.java @@ -7,6 +7,7 @@ import cz.metacentrum.perun.core.api.ExtSource; import cz.metacentrum.perun.core.api.Group; import cz.metacentrum.perun.core.api.Member; +import cz.metacentrum.perun.core.api.MemberWithSponsors; import cz.metacentrum.perun.core.api.MembersManager; import cz.metacentrum.perun.core.api.PerunSession; import cz.metacentrum.perun.core.api.Resource; @@ -35,9 +36,7 @@ import cz.metacentrum.perun.core.api.exceptions.MemberNotValidYetException; import cz.metacentrum.perun.core.api.exceptions.ParentGroupNotExistsException; import cz.metacentrum.perun.core.api.exceptions.PasswordCreationFailedException; -import cz.metacentrum.perun.core.api.exceptions.PasswordOperationTimeoutException; import cz.metacentrum.perun.core.api.exceptions.PasswordStrengthException; -import cz.metacentrum.perun.core.api.exceptions.PasswordStrengthFailedException; import cz.metacentrum.perun.core.api.exceptions.PrivilegeException; import cz.metacentrum.perun.core.api.exceptions.ResourceNotExistsException; import cz.metacentrum.perun.core.api.exceptions.UserExtSourceNotExistsException; @@ -53,6 +52,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.util.stream.Collectors; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -1341,6 +1341,32 @@ public List getSponsoredMembers(PerunSession sess, Vo vo) throws Pri return membersManagerBl.convertMembersToRichMembers(sess, membersManagerBl.getSponsoredMembers(sess, vo)); } + @Override + public List getSponsoredMembersAndTheirSponsors(PerunSession sess, Vo vo, List attrNames) throws VoNotExistsException, PrivilegeException, AttributeNotExistsException { + Utils.checkPerunSession(sess); + Utils.notNull(vo, "vo"); + + perunBl.getVosManagerBl().checkVoExists(sess, vo); + + //Authorization + if(!AuthzResolver.authorizedInternal(sess, "getSponsoredMembersAndTheirSponsors_Vo_policy", vo)) { + throw new PrivilegeException(sess, "getSponsoredMembersAndTheirSponsors"); + } + + List attrsDef = new ArrayList<>(); + for (String attrName : attrNames) { + attrsDef.add(getPerunBl().getAttributesManagerBl().getAttributeDefinition(sess, attrName)); + } + + List richMembers = membersManagerBl.convertMembersToRichMembersWithAttributes(sess, getSponsoredMembers(sess, vo), attrsDef); + richMembers = membersManagerBl.filterOnlyAllowedAttributes(sess, richMembers, null, true); + + return richMembers.stream() + .filter(member -> AuthzResolver.authorizedInternal(sess, "filter-getSponsoredMembersAndTheirSponsors_Vo_policy", member, vo)) + .map(member -> convertMemberToMemberWithSponsors(sess, member)) + .collect(Collectors.toList()); + } + @Override public String extendExpirationForSponsoredMember(PerunSession sess, Member sponsoredMember, User sponsorUser) throws PrivilegeException, MemberNotExistsException, UserNotExistsException { Utils.checkPerunSession(sess); @@ -1381,6 +1407,20 @@ public void removeSponsor(PerunSession sess, Member sponsoredMember, User sponso membersManagerBl.removeSponsor(sess,sponsoredMember, sponsorToRemove); } + /** + * Converts member to member with sponsors and sets all his sponsors. + * + * @param sess perun session + * @param member sponsored member + * @return member with sponsors + */ + private MemberWithSponsors convertMemberToMemberWithSponsors(PerunSession sess, RichMember member) { + MemberWithSponsors memberWithSponsors = new MemberWithSponsors(member); + List sponsors = getPerunBl().getUsersManagerBl().getSponsors(sess, member); + memberWithSponsors.setSponsors(sponsors); + return memberWithSponsors; + } + /** * Gets the membersManagerBl for this instance. * diff --git a/perun-core/src/test/java/cz/metacentrum/perun/core/entry/MembersManagerEntryIntegrationTest.java b/perun-core/src/test/java/cz/metacentrum/perun/core/entry/MembersManagerEntryIntegrationTest.java index f8bb0eb9a8..a8096d0e38 100644 --- a/perun-core/src/test/java/cz/metacentrum/perun/core/entry/MembersManagerEntryIntegrationTest.java +++ b/perun-core/src/test/java/cz/metacentrum/perun/core/entry/MembersManagerEntryIntegrationTest.java @@ -11,10 +11,12 @@ import cz.metacentrum.perun.core.api.Group; import cz.metacentrum.perun.core.api.GroupsManager; import cz.metacentrum.perun.core.api.Member; +import cz.metacentrum.perun.core.api.MemberWithSponsors; import cz.metacentrum.perun.core.api.MembersManager; import cz.metacentrum.perun.core.api.PerunBean; import cz.metacentrum.perun.core.api.Resource; import cz.metacentrum.perun.core.api.RichMember; +import cz.metacentrum.perun.core.api.RichUser; import cz.metacentrum.perun.core.api.Role; import cz.metacentrum.perun.core.api.SpecificUserType; import cz.metacentrum.perun.core.api.Status; @@ -171,6 +173,31 @@ public void getSponsoredMembers() throws Exception { assertTrue(sponsoredMembers.contains(sponsoredMember2)); } + @Test + public void getSponsoredMembersAndTheirSponsors() throws Exception { + System.out.println(CLASS_NAME + "getSponsoredMembersAndTheirSponsors"); + + Member sponsorMember = setUpSponsor(createdVo); + User sponsorUser = perun.getUsersManagerBl().getUserByMember(sess, sponsorMember); + Group sponsors = new Group("sponsors","users able to sponsor"); + sponsors = perun.getGroupsManagerBl().createGroup(sess,createdVo,sponsors); + AuthzResolverBlImpl.setRole(sess, sponsors, createdVo, Role.SPONSOR); + perun.getGroupsManagerBl().addMember(sess,sponsors,sponsorMember); + + Map userName = new HashMap<>(); + userName.put("guestName", "Ing. Jan Novák"); + Member sponsoredMember = perun.getMembersManagerBl().createSponsoredMember(sess, createdVo, "dummy", userName, "secret", sponsorUser, false); + + ArrayList attrNames = new ArrayList<>(); + attrNames.add("urn:perun:user:attribute-def:def:preferredMail"); + + List memberWithSponsors = perun.getMembersManager().getSponsoredMembersAndTheirSponsors(sess, createdVo, attrNames); + + assertEquals(memberWithSponsors.get(0).getMember(), sponsoredMember); + assertEquals(memberWithSponsors.get(0).getSponsors().get(0), sponsorUser); + assertTrue(memberWithSponsors.get(0).getSponsors().size() == 1); + } + @Test public void createMember() throws Exception { System.out.println(CLASS_NAME + "createMemberSync"); diff --git a/perun-openapi/openapi.yml b/perun-openapi/openapi.yml index 7e4c70e432..9fbdefb834 100644 --- a/perun-openapi/openapi.yml +++ b/perun-openapi/openapi.yml @@ -924,6 +924,12 @@ components: items: type: integer + MemberWithSponsors: + type: object + properties: + member: { $ref: '#/components/schemas/RichMember' } + sponsors: { type: array, items: { $ref: '#/components/schemas/User' }} + RTMessage: type: object properties: @@ -997,6 +1003,15 @@ components: items: type: string + ListOfMemberWithSponsorsResponse: + description: "returns List" + content: + application/json: + schema: + type: array + items: + $ref: "#/components/schemas/MemberWithSponsors" + MapStringStringResponse: description: "returns Map" content: @@ -7843,6 +7858,22 @@ paths: default: $ref: '#/components/responses/ExceptionResponse' + /json/membersManager/getSponsoredMembersAndTheirSponsors: + get: + tags: + - MembersManager + operationId: getSponsoredMembersAndTheirSponsors + summary: Gets list of members with sponsors. + parameters: + - $ref: '#/components/parameters/voId' + - $ref: '#/components/parameters/attrNames' + responses: + '200': + $ref: '#/components/responses/ListOfMemberWithSponsorsResponse' + default: + $ref: '#/components/responses/ExceptionResponse' + + /json/membersManager/createSponsoredMember/withFullName: post: tags: diff --git a/perun-rpc/src/main/java/cz/metacentrum/perun/rpc/methods/MembersManagerMethod.java b/perun-rpc/src/main/java/cz/metacentrum/perun/rpc/methods/MembersManagerMethod.java index 3a912fe3d9..f0b5292772 100644 --- a/perun-rpc/src/main/java/cz/metacentrum/perun/rpc/methods/MembersManagerMethod.java +++ b/perun-rpc/src/main/java/cz/metacentrum/perun/rpc/methods/MembersManagerMethod.java @@ -378,6 +378,23 @@ public List call(ApiCaller ac, Deserializer params) throws PerunExce } }, + /*# + * Gets list of sponsored members with sponsors. + * + * @param vo int id of virtual organization from which are the sponsored members chosen + * @param attrNames List list of attribute names + * @throw VoNotExistsException if given VO does not exist + * @return List list of members with sponsors + */ + getSponsoredMembersAndTheirSponsors { + @Override + public List call(ApiCaller ac, Deserializer params) throws PerunException { + Vo vo = ac.getVoById(params.readInt("vo")); + List attrNames = params.contains("attrNames") ? params.readList("attrNames",String.class) : null; + return ac.getMembersManager().getSponsoredMembersAndTheirSponsors(ac.getSession(), vo, attrNames); + } + }, + /*# * Gets users sponsoring a given user in a VO. *