This recipe illustrates how to use Service Panel to front end the MIM Portal for allowing users to make self-service requests to join and leave a group.
Prerequisites
- Service Panel, configured with People and Groups virtual silos
- MIM Portal authoritative for groups with manual membership
- Parent Silo set to Active Directory or MIM Metaverse for both People and Groups (if allowing mixed membership)
- Group ownership is populated in the MIM Portal, and in AD/Metaverse on the managedBy attribute
Strategy Overview
- The Join and Leave forms capture the group display name and user account name for updating Portal groups. Otherwise the form only has a justification message and a confirmation checkbox
- An attribute on the group displays a hyperlink to the user to trigger the appropriate form based on whether the group has manual membership, and whether the user is currently a member.
- A MIM Test fixture uses the group name and user account name from the form to build XPath filters to update the group and modify the membership.
- An Identity Panel workflow triggers when the Join Group or Leave Group form is submitted. It processes an approval flow, emailing the group's owner to seek permission to add or remove the user. If permission is denied the user is emailed.
Form Settings
- Name: JoinGroup
- Label: Join Group
- Icon: group
- Virtual Silo: Groups
- Audience Rules: Everyone
- Form Page:
- Name: Group
- Label: Join Group
- Next Label: Submit Request
- Section 1: Join Group?
- Description:
Click confirm below if you want to request to have your account added to the listed group. This request must be approved by the group owner ([ResolveId(Last(Split(Identity.Attributes.Owner, "_")), special.Identity Silo.UKLAB AD).Attributes.displayName]).
Join Group? Section
- Row 1: Label
- Name: NameL
- Size: 2
- Text: Group Name:
- Row 1: Label
- Name: Name
- Size: 10
- Text:
[Identity.Parent.Attributes.displayName]
- Row 1: Label
- Name: AccountName
- Text:
[Identity.Parent.Attributes.sAMAccountName]
- Visible: False
- Row 1: Label
- Name: OwnerMail
- Text:
[FirstNotNull(ResolveId(Last(Split(Identity.Attributes.Owner, "_")), special.Identity Silo.UKLAB AD).Attributes.mail, "fallbackaddress@uklab.identitypanel.com")]
- Visible: False
- Row 1: Label
- Name: OwnerName
- Text:
[ResolveId(Last(Split(Identity.Attributes.Owner, "_")), special.Identity Silo.UKLAB AD).Attributes.displayName]
- Visible: False
- Row 1: Label
- Name: UserAccountName
- Text:
[SelfServiceObject().Parent.Attributes.sAMAccountName]
- Visible: False
- Row 1: Label
- Name: UserMail
- Text: [FirstNotNull(SelfServiceObject().Parent.Attributes.mail, SelfServiceObject().Parent.Attributes.userPrincipalName)]
- Visible: False
- Row 1: Label
- Name: UserDisplayName
- Text: [SelfServiceObject().Parent.Attributes.displayName]
- Visible: False
- Row 2: Checkbox
- Name: Confirm
- Size: 12
- Value: true
- Selected: false
- Validate Required: yes
- Label: Confirm Request to Join?
- Row 2: Textarea
- Name: Justification
- Size: 6
- Validate Required: yes
- Label: Request Justification
- Hint: Please say why you would like to be added to this group
The Leave Group form is identical to the Join Group form, with the caveat that all "Join" verbage is replaced with "Leave"
Virtual Attribute
The virtual attribute displays on the Group and gives a link to either the Join or Leave form
- Name: Join Group
- Value Silo: MIM: Portal
NOTE: If the group and user silos are mastered off of AD or Metaverse, the Value rule should return a simple string, e.g. "Link" and the actual link should be in the Label rule with Silo set to match the Parent silo. - Value Rule:
Explanation: If there's a Portal filter just return null because we can't add the user anyway. Otherwise use ResolveMulti() to figure out if the user is already a member, and return the appropriate text.
If( Attributes.Filter, null, If( ResolveMulti(Id, SelfServiceObject().Id, special.Identity Silo.UKLAB AD, "member"), "Request to Leave this Group", "Request to Join this Group" ) )
Or:If( Attributes.Filter, null, "Link Here" )
- Detail Decorators
- Position: Replace
- Mode: All
- URL Silo: AD
- URL Rule:
If( ResolveMulti(Id, SelfServiceObject().Id, special.Identity Silo.UKLAB AD, "member"), ServiceForm("LeaveGroup", Id), ServiceForm("JoinGroup", Id) )
- Label Silo: AD
- Label Rule:
If( ResolveMulti(Id, SelfServiceObject().Id, special.Identity Silo.UKLAB AD, "member"), "Request to Leave this Group", "Request to Join this Group" )
- In the Virtual Silo Grid Display section add the attribute after the Group Type
MIM Test Fixtures
The fixtures are responsible for actually joining the user to the group or removing them.
- Name: Join User to Group
- System: Portal (MIM Portal system)
- Search Filter:
[$"/Group[DisplayName='{Memo("Data").Group.Name}']"]
- Multivalue Attributes:
- Name: ExplicitMember
- Mode: Append
- Value:
[PortalResolve($"/Person[AccountName='{Memo("Data").Group.UserAccountName}']", "Portal")]
- Name: Leave User from Group
- System: Portal
- Search Filter:
[$"/Group[DisplayName='{Memo("Data").Group.Name}']"]
- Multivalue Attributes:
- Name: ExplicitMember
- Mode: Remove
- Value:
[PortalResolve($"/Person[AccountName='{Memo("Data").Group.UserAccountName}']", "Portal")]
Workflow Configuration
The workflow handles the approval process and triggering the fixture.
- Name: Join Group
- Trigger Rule:
And(Name == "JoinGroup", Completed)
- Steps:
- Request
- Type: Send Email
- Name: Request
- To:
[Data.Group.OwnerMail]
- cc: (additional email address for debug)
- Subject: Approval request to join group
[Data.Group.Name]
- Message: See Appendix
- Send as HTML: Yes
- Next: <Empty>
- Join (triggered by link click)
- Type: MIM Test Fixture Step
- Name: Join
- Fixture: Join user to Group
- Memos: Name: Data, Value:
[Data]
, Scope: Test - Next: Approved
- Approved
- Type: Send Email
- Name: Approved
- To:
[Data.Group.UserMail]
- cc: (additional email address for debug)
- Subject: Group request approved
- Message: See Appendix
- Send as HTML: Yes
- Next: <empty>
- Reject (triggered by link click or timeout)
- Type: Send Email
- Name: Reject
- To:
[Data.Group.UserMail]
- cc: (additional email address for debug)
- Subject: Group request denied
- Message: See Appendix
- Send as HTML: yes
- Next: <empty>
- Request
Request Email Appendix
<html> <head> <style> body{ font-family: "Segoe UI",opensans,sans-serif; color: #2c3944; font-size: 14px; } a { color: #ee5f3d; } </style> </head> <body> <p> Dear [Data.Group.OwnerName] </p> <p> A user has requested to join a group that you manage (<strong>[Data.Group.Name]</strong>). </p> <p> The user is <strong>[Data.Group.UserName]</strong> ([Data.Group.UserAccountName]) and their justification for the request is: </p> <p>[Data.Group.Justification]</p> <p><a href="[Link("Join", "1.00:00:00", null, "Thank you for approving the request", "servicepanel")]">Click this link to <strong>APPROVE</strong> the request.</a></p> <p><a href="[Link("Reject", "1.00:00:00", null, "The request has been rejected", "servicepanel")]">Click this link to <strong>REJECT</strong> the request.</a></p> <p>— Identity Notifications</p> </body> </html>
Approved Email Appendix
<html> <head> <style> body{ font-family: "Segoe UI",opensans,sans-serif; color: #2c3944; font-size: 14px; } a { color: #ee5f3d; } </style> </head> <body> <p> Dear [Data.Group.UserName] </p> <p> Your request to join a group ([Data.Group.Name]) has been approved by the group owner ([Data.Group.OwnerName]) and you have been added to the group. Please wait 30 minutes for changes to flow through the system. </p> <p>— Identity Notifications</p> </body> </html>
Reject Email Appendix
<html> <head> <style> body{ font-family: "Segoe UI",opensans,sans-serif; color: #2c3944; font-size: 14px; } a { color: #ee5f3d; } </style> </head> <body> <p> Dear [Data.Group.UserName] </p> <p> Your request to join a group ([Data.Group.Name]) has been denied by the group owner ([Data.Group.OwnerName]). </p> <p>— Identity Notifications</p> </body> </html>
Comments
0 comments
Please sign in to leave a comment.