Introduction
ForgeRock® Identity Management (IDM) is part of the ForgeRock® Identity Platform. The ForgeRock Identity Platform manages the identity lifecycle, and automates the on-boarding, administration, provisioning, relationship management, and off-boarding of digital identities. It is a centralized service that lets you collect appropriate levels of information from HR systems, users…
Still here? Good! In this article, rather than provide a garden variety use case about provisioning, approvals, and password management (to name a few), we will explore a (hopefully) more interesting use case for IDM: a multi-user, turn-based gaming platform!
We will use some of the fantastic features IDM provides, such as:
- Flexible data model
- Self-service dashboard (custom UI)
- Entity relationships
- Custom REST endpoints
- Workflows
- Fine-grained, role-based access control
Assumptions
This article assumes that you are familiar with basic IDM 6.5 concepts, and have some experience customizing IDM workflows, end user UI, and REST endpoints.
The gaming platform
We will create a turn-based game for two players, as it is relatively easy to implement, and leverages the above IDM capabilities. When I think of two-player, turn-based games, tic-tac-toe and chess come to mind, as they are popular, and well-known. Although I decided on chess, it would be just as easy (or easier) to implement tic-tac-toe. Actually, it may be a good exercise for you, the reader, to take this project and develop it into a generic two-player, turn-based game engine, so any appropriate game can be plugged in, like tic-tac-toe, chess, battleship, and others.
For now, here’s how the chess game works.
To participate, the users need to first opt in to IDM for games. This is similar to opting in for marketing communications, giving users a choice. This decision is stored in a new preferences attribute in the managed user object.
The following is a typical flow
- Opted-in users can search for others who have opted in within the organization.
- Anyone from the list of users found can be invited to play.
- The invited user gets a workflow task for accepting or rejecting this invite. This is implemented using the integrated Activiti (IDM 6.5) or Flowable (IDM 7.0) BPMN2 workflow engine.
- Workflows are leveraged to track the game as it progresses. For as long as the game is active, each player will have a user task (BPMN2 construct) assigned to them so they can log in and see the progress of the game any time in their assigned task view on the self-service dashboard view in the UI.
- Once the game is over (checkmate or draw), users will be able to “Complete” their respective user tasks.
- As a result, the completed game will appear in the list of past games in their self-service dashboard. They can load any past games and replay them move-by-move anytime.
Here is a video that shows you what the game will look like to the users/players.
https://www.youtube.com/watch?v=eQ2DCpJCsh0&feature=youtu.be"
Design
In this section, we will show you the details of how IDM was customized to implement this game platform.
Data model and relationships
New managed object
There are two main changes to the data model.
New managed object: A new managed object, game, stores each game’s information. The object contains information about the game (name, start time, state, …), and also stores the current and past chess board positions using a FEN string. The game object also has (reverse) relationships to the players. This is what it looks like:
- is self-explanatory
- name
- status can be “Ongoing” or “Over”
- startts and endtts are time stamps for start and end of the game
- players is a 1-to-many relationship to the user managed object
- currentFEN represents the current chess board positions (in FEN)
- pastFEN is an array representing all the past positions (in FEN)
- seen is a flag for internal purpose (to update the UI)
- winner represents the piece color which won; “w” or “b”, or “d” for draw
The players relationship looks like this:
The relationship has two properties:
- color represents the chess piece color of the user this points to
- opponent not used at the moment
Here is an example of a game object:
and the relationship to the players:
New attributes for managed user: There are two new attributes for the managed user:
- preferences/games: a new boolean property added to the out-of-box “preferences” object. The flag indicates users’ preference for opting in for games.
- games: the reverse relationship from user to the game object, created automatically when the (game)->(managed user) relationship is created.
Workflows
A new workflow is created, which looks like the following:
The workflow uses three custom UI forms:
- startForm: this is displayed when the workflow is started. It lets the user search for other users in the organization and invite them to play.
- acceptForm: this is displayed in a user task to users who have received an invitation from another user.
- gameForm: once an invite is accepted, a new game and two user tasks are created. One of each is assigned to each player. The game form is part of this user task, and has all the custom UI to render the chess board and control the flow of the game. The UI uses chess and chess.js for the actual game play logic and graphics.
Users take turns at making their moves until there is a checkmate or a draw, at which time, the game is over and the users click “Finish Game” to complete the user task and end the workflow. Once the workflow finishes, the completed game appears in the list of past games in each participant’s self-service dashboard…which brings us to the next UI customization…
Self-service dashboard widget
A new widget for the dashboard is created that lets users select from a list of their completed games and replay the game move-by-move, rendering each move on a chess board.
Custom REST endpoint
A custom endpoint is created to provide user search functionality from the workflow. The endpoint can search across all users in an organization by matching a substring in their user name or display name, and by who opted in for games. The endpoint lets us only expose certain functionalities to all the users rather than give all users open access to search anyone else. The endpoint code is as follows:
(function(){
var myid =hmm
context.parent.parent.parent.authorization.authenticationId;
var queryFilter = {
_queryFilter: "/gameOptIn eq true and ! /userName eq '" +
myid +
"' and userName co '" +
request.additionalParameters.searchtext +
"' or /gameOptIn eq true and ! /userName eq '" +
myid +
"' and givenName co '" +
request.additionalParameters.searchtext +
"' or /gameOptIn eq true and ! /userName eq '" +
myid +
"' and sn co '" +
request.additionalParameters.searchtext +
"'"
};
var result = openidm.query("managed/user", queryFilter,
["_id", "userName", "givenName", "sn"]);
return result;
})();
Fine grained, role-based access control
Lastly, we ensure that users can call the custom endpoint above over REST, and also have access to read and update the game custom managed object. For this, the following is added to the script/access.js:
{
"pattern" : "managed/game/*",
"roles" : "internal/role/openidm-authorized",
"methods" : "*",
"actions" : "*"
},
{
"pattern" : "managed/game",
"roles" : "internal/role/openidm-authorized",
"methods" : "*",
"actions" : "*"
},
{
"pattern" : "endpoint/searchUsers",
"roles" : "internal/role/openidm-authorized",
"methods" : "*",
"actions" : "*"
}
You can find all the code for this project at:
- forgerock-idm-chess: this contains the custom IDM configuration with instructions on how to deploy it. There are two branches: “master” is for IDM 6.5 and “idm7” is for IDM 7.0.
- end-use-ui: the “chess2” branch is the one with changes for this project (the same code works on IDM 6.5 and 7.0)
https://github.com/sandman0/forgerock-idm-chess
https://github.com/sandman0/end-user-ui