Table of contents


Official Content

The purpose of the GAM Events subscription is to allow the automatic triggering of additional (external) code when a GAM event is executed. That is, being able to execute a custom event automatically after a GAM event is executed (i.e: the creation of a GAM user).

Consider a scenario where you have a Users table, and the user information is redundant with the GAM Users table. You need to 
keep the Users table up to date; that is, any time a GAM User is updated (created or removed) the Users table should be updated accordingly.

The following pseudo-code would be used in such a case: 

&GAMUser.Save()
//Call a procedure to make the necessary changes in the Users table.

To avoid considering this piece of code everywhere you update a GAM User, the code may be automatically triggered immediately after the GAM user is updated.

So the GAM User insert, update, and delete are considered to be events that automatically trigger the piece of code declared to be executed.

In other words, you subscribe to some events, so that (external) code can be triggered as any of these events is executed.

Events you may subscribe to:

  • User_Insert: Insert of a GAM User
  • User_Update: Update of a GAM User
  • User_Delete: Delete of a GAM User
  • User_UpdateRoles: Change of roles of a list of users
  • User_GetCustomInfo: This event allows to customize the information that the Identity Provider sends to the Client, and it’s executed when the User’s authenticate (SSO Web) or request a token (OAuth 2.0). For this purpose, the Output oh the procedure must return a JSON. It’s recommended to use an SDT that has the structure of the information to be shared. 
  • User_SaveCustomInfo: This event is executed on the client when the GAM Remote or Remote Rest Authentication type (OAuth 2.0) login is successfully finished.
  • Role_Insert: Insert of a role
  • Role_Update: Update of a role
  • Role_Delete: Delete of a role
  • Repository_Login: GAM User login (any Authentication Types is supported)
  • Repository_LoginFailed: User login fails (GAM Error 11 or GAM Error 18)
  • Repository_Logout: GAM log out
  • Repository_RememberAuthentication: This event is triggered when the user's session doesn't exist or the token has been expired, and only when the user was authenticated using the 'Keep me logged in'.
  • User_OneTimePasswordValidUser. Check that the user that asked for an OTP code is allowed to do it.
  • User_OneTimePasswordGenerateCode. Developer event to generate the OTP code.
  • User_OneTimePasswordSendCode. Developer event to send the OTP code.
  • User_OneTimePasswordValidateCode. Developer event to validate the OTP code.

Requirements of a program that subscribes to an event

The way to subscribe to an event is to configure a program that will be triggered when the event is executed. The configuration may be done using the GAM API(1) or the Web Backoffice(2). We'll go over this topic in more detail below.

The program that considers the GAM events may be developed using GeneXus or not, and it has to fulfill some requirements.

First, the signature of the program has to be as follows:

(in Character &EventName, in Character &jsonIn, out Character &jsonOut)

Where: 

  • &EventName: belongs to the GAMEvents Domain.
  • &jsonIN: JSON string whose format depends on the GAM event that the program is subscribed to (see the table below for more details).
  • &jsonOUT: JSON string used to print information in the GAM trace (if it's enabled).

Main program property has to be on True.

Secondly, consider how the &jsonIN format should be:

Event GAM object received parameters
User_Insert GAMUser (i.e., the jsonIN format is derived from the GAMUser object)
User_Update GAMUser
User_Delete GAMUser
User_UpdateRoles GAMGUID collection representing the list of users whose roles were changed.
User_GetCustomInfo  GAMSession
User_SaveCustomInfo (free format)
Role_Insert GAMRole (i.e., the jsonIN format is derived from the GAMRole object)
Role_Update GAMRole
Role_Delete GAMRole
Repository_Login GAMSession (i.e., the jsonIN format is derived from the GAMSession object)
Repository_Logout GAMSession
Repository_LoginFailed GAMSession
Application_CheckPermissionFail GAMSessionLogCheckPermissionFail
User_OneTimePasswordValidUser GAMOTPEventSubscription
User_OneTimePasswordGenerateCode GAMOTPEventSubscription
User_OneTimePasswordSendCode GAMOTPEventSubscription
User_OneTimePasswordValidateCode GAMOTPEventSubscription

Example I

In the following example, we have subscribed to the User_Insert event.

In the Web Backoffice(2), go through Settings > Event Subscriptions and define the Event as shown in the following figure.

Net configuration

Net Environment event subscription example

 

Java configuration (in this example the Java Package Name=com.gameventssubscription)

Java environment event subscription example

Status It may be {subscribed,unsubscribed}. It has to be subscribed for the procedure to be triggered when the event is executed.
Event

It's a combo box where you can select any of the events available.

image_2017124114711_1_png

File Name The name of the .dll or .class file which listens to the event execution.
Class Name The name of the program including its package.
Method Name The method of the program in GeneXus is always "execute".

The code of the notifyuserinsert procedure is as follows:

Rules: Parm(in:&EventName, in:&jsonIN, out:&jsonOUT);
&GAMUser.FromJsonString(&jsonIN)

&MyUser.Load(&GAMUser.GUID)  //&Myuser is based on a BC.
If &MyUser.Fail()
    &MyUser = new()    
Endif
&MyUser.MyUserGUID    =&GAMUser.GUID
&MyUser.MyUserEmail    = &GAMUser.EMail
&MyUser.MyUserName    = &GAMUser.FirstName.Trim() +" "+ &GAMUser.LastName.Trim()
&MyUser.Save()
If &MyUser.Success()
    //Ok
Else
    //load &jsonOUT parameter with information about the error.
Endif

Example II

See HowTo: Get user's additional information from the GAM Identity Provider for an example of User_GetCustomInfo and User_SaveCustomInfo events.

Example III

In the case of the login event, the proc subscribed will be triggered at login (regardless of whether the login is local or not).
In that procedure, you can make additional controls that allow you to cancel the login and prevent a session from being generated.

Consider the following example code that triggers at login:

&GAMSession.FromJsonString(&JsonIN)
For each
    Where  CustomerGUID = &GAMSession.User.GUID
    Where  CustomerActiveSubscription = True

         //OK
     When none
      &GAMError.Code        = GAMErrorMessages.UserInactive
      &GAMError.Message    = "The user's subscription is not valid."
      &JsonOUT = &GAMError.ToJsonString()
Endfor

The JsonOut format must be GAMError. Only if it is empty, it does not cancel the login.
What happens internally is that the session is created and revoked immediately.

(1)   How to subscribe to an event using the GAM API

You can define the event subscription as shown in the following example:

&GAMEventSubscription = new()    // &GAMEventSubscription is GAMEventSubscription data type
&GAMEventSubscription.Description =  "Inspecting the User Login"
&GAMEventSubscription.Event       =  GAMEvents.Repository_Login
&GAMEventSubscription.FileName    = "aNotifyUserLogin.dll"
&GAMEventSubscription.ClassName   = "GeneXus.Programs.anotifyuserlogin"
&GAMEventSubscription.MethodName  =  "execute"
&GAMEventSubscription.Save()
If &GAMEventSubscription.Success()
  Commit
  // Subscription activation:
  &isOK = GAMRepository.SubscribeEvent(&GAMEventSubscription.Id, &GAMErrors)
  If &isOK
     Commit
  Endif
Endif

You may define more than one program to be triggered when the event is executed.

Note that the subscription must be activated using the SubscribeEvent method of GAMRepository.

Considerations about the logic Transaction

Case 1. The program was developed using GeneXus 

To include the program subscribed to the event in the same LUW (Logical Unit of Work) of the event, include the Commit command after the code that triggers the event (i.e., &GAMUser.save() or &GAMRole.save()).

On the contrary, if you don't want to include the program in the same LUW, just configure Execute in new LUW property = True for the program.

The Repository_Login and Repository_Logout methods execute an implicit commit, so you don't need to execute it.

Case 2. The program was not developed using GeneXus

It will not be in the same LUW. 


Last update: February 2024 | © GeneXus. All rights reserved. GeneXus Powered by Globant