Scripting
The scripting interface allows you to customize the behavior of Groove.id to suite your needs. You write scripts in TypeScript. Groove.id runs the scripts you provide whenever an event occurs. Your script can reject, modify, or ignore the event as you see fit. Scripts have read-only access to objects in the Groove.id API. You must be an Administrator to create, edit, or view scripts.
To get started, navigate to Settings, then Scripts and click New to create a new script.
A simple script
The script created is a simple example, which ensures that each user has a FullName
property specified.
class Users implements UserPlugin {
Create(ctx: Context, user: User) {
if (!user.Name.FullName) {
throw new BadRequestException('user must have a name')
}
return null
}
}
const plugin: GrooveidPlugin = {
Users: new Users()
}
export default plugin
Let’s try it out. Check the Enabled box and press Save.
Then navigate to People > New and try to create a user with no name. You will see an error message, and the user will not be created.
Navigate back to the script and check the logs tab to see what happened. You should see an error message in the output.
Modifying the object
Perhaps instead of failing when a user doesn’t have a name, we want to make one up somehow. Let’s modify the script so it looks like this:
class Users implements UserPlugin {
Create(ctx: Context, user: User) {
if (!user.Name.FullName) {
user.Name.FullName = 'Anonymous Coward'
return user // return the user because we want to apply changes.
}
return null // indicates that we don't want to change the user.
}
}
const plugin: GrooveidPlugin = {
Users: new Users()
}
export default plugin
Try creating a nameless user again. This time it will work, and a user named Anonymous Coward
will appear. You can also check the script log and note a successful invocation.
Reading other objects
If we did a lot of this, we’d have a lot of people all named Anonymous Coward, which isn’t super useful. Let’s say we want to name the anonymous users as “Anonymous Coward 2”, “Anonymous Coward 3,” etc. Update the script so it looks like this:
class Users implements UserPlugin {
Create(ctx: Context, user: User) {
if (user.Name.FullName) {
return null
}
let name = 'Anonymous Coward'
for (let counter = 1; counter < 100; counter++) {
// Now we are using the global `data` to examine other objects in the system.
let nameExists = false
data.Users.List({}, (existingUser: User) => {
if (existingUser.Name.FullName == name) {
console.log(
'a user named ' +
name +
' already exists: ' +
existingUser.Metadata.ID +
' name: ' +
existingUser.Name.FullName
)
nameExists = true
}
})
if (!nameExists) {
user.Name.FullName = name
return user
}
if (nameExists) {
name = 'Anonymous Coward ' + counter
}
}
throw new Error('There are already 100 Anonymous Cowards')
}
}
const plugin: GrooveidPlugin = {
Users: new Users()
}
export default plugin
Reference
Groove.id plugins are typescript modules that export a single default export of type GrooveidPlugin.
Globals
- data - Data - an interface to read and list all objects stored by Groove.id.
- console - provides a
log
method to emit messages which are captured in the script log.
Types
GrooveidPlugin
GrooveidPlugin is top-level interface implemented by all Groove.id scripts. A Groove.id script must have a single default export that is of type GrooveidPlugin.
- Accounts - AccountPlugin - optional. Plugins can implement this interface to monitor or modify creating, deleting and updating Account objects.
- AccountChanges AccountChangePlugin - optional. Plugins can implement this interface to monitor or modify creating, deleting and updating AccountChange objects.
- Apps AppPlugin - optional. Plugins can implement this interface to monitor or modify creating, deleting and updating App objects.
- Groups GroupPlugin - optional. Plugins can implement this interface to monitor or modify creating, deleting and updating Group objects.
- Users UserPlugin - optional. Plugins can implement this interface to monitor or modify creating, deleting and updating User objects.
- SSH SSHPlugin - optional. Plugins can implement this interface to modify how SSH keys and sessions are handled.
- Lifecycle LifecyclePlugin - optional. Plugins can implement this interface to modify account lifecycle operations.
AccountPlugin
Plugins can implement this interface to monitor or modify creating, deleting and updating Account objects.
- Create - optional
(ctx: Context, account: Account) => Account| null
Create is a function that is invoked when someone is creating an Account.
If you return null from this function, then the Account will be created as specified by the caller.
If you wish to modify the Account that will be created, then the function should return the modified account.
If the account should not be created then the function should throw an exception, e.g. UnauthorizedException.
- Update - optional
(ctx: Context, oldAccount: Account, account: Account) => Account| null
Update is a function that is invoked when someone is updating an Account. The oldAccount parameter contains the previous value of the account. The account parameter contains the new value of the account.
If you return null from this function, then the Account will be created as specified by the caller.
If you wish to modify the Account, then the function should modify the Account and return the modified account.
If the account should not be created then the function should throw an exception, e.g. UnauthorizedException.
- Delete - optional
(ctx: Context, oldAccount: Account) => void
Delete is invoked when someone is deleting an Account. The ‘oldAccount’ parameter is the Account that will be deleted.
If the account should not be deleted, throw an exception, e.g. UnauthorizedException.
AccountChangePlugin
Plugins can implement this interface to monitor or modify creating, deleting and updating AccountChange objects.
- Create - optional
(ctx: Context, accountchange: AccountChange) => AccountChange| null
Create is a function that is invoked when someone is creating an AccountChange.
If you return null from this function, then the AccountChange will be created as specified by the caller.
If you wish to modify the AccountChange that will be created, then the function should return the modified accountchange.
If the account change should not be created then the function should throw an exception, e.g. UnauthorizedException.
- Update - optional
(ctx: Context, oldAccountChange: AccountChange, accountchange: AccountChange) => AccountChange| null
Update is a function that is invoked when someone is updating an AccountChange. The oldAccountChange parameter contains the previous value of the account change. The accountchange parameter contains the new value of the account change.
If you return null from this function, then the AccountChange will be created as specified by the caller.
If you wish to modify the AccountChange, then the function should modify the AccountChange and return the modified accountchange.
If the account change should not be created then the function should throw an exception, e.g. UnauthorizedException.
- Delete - optional
(ctx: Context, oldAccountChange: AccountChange) => void
Delete is invoked when someone is deleting an Account. The ‘oldAccount’ parameter is the AccountChange that will be deleted.
If the account change should not be deleted, throw an exception, e.g. UnauthorizedException.
AppPlugin
Plugins can implement this interface to monitor or modify creating, deleting and updating App objects.
- Create - optional
(ctx: Context, app: App) => App| null
Create is a function that is invoked when someone is creating an App.
If you return null from this function, then the App will be created as specified by the caller.
If you wish to modify the App that will be created, then the function should return the modified app.
If the app should not be created then the function should throw an exception, e.g. UnauthorizedException.
- Update - optional
(ctx: Context, oldApp: App, app: App) => App| null
Update is a function that is invoked when someone is updating an App. The oldApp parameter contains the previous value of the app. The app parameter contains the new value of the app.
If you return null from this function, then the App will be created as specified by the caller.
If you wish to modify the App, then the function should modify the App and return the modified app.
If the app should not be created then the function should throw an exception, e.g. UnauthorizedException.
- Delete - optional
(ctx: Context, oldApp: App) => void
Delete is invoked when someone is deleting an App. The ‘oldApp’ parameter is the App that will be deleted.
If the app should not be deleted, throw an exception, e.g. UnauthorizedException.
GroupPlugin
Plugins can implement this interface to monitor or modify creating, deleting and updating Group objects.
- Create - optional
(ctx: Context, group: Group) => Group| null
Create is a function that is invoked when someone is creating a Group.
If you return null from this function, then the Group will be created as specified by the caller.
If you wish to modify the Group that will be created, then the function should return the modified group.
If the group should not be created then the function should throw an exception, e.g. UnauthorizedException.
- Update - optional
(ctx: Context, oldGroup: Group, group: Group) => Group| null
Update is a function that is invoked when someone is updating a Group. The oldGroup parameter contains the previous value of the group. The group parameter contains the new value of the group.
If you return null from this function, then the Group will be created as specified by the caller.
If you wish to modify the Group, then the function should modify the Group and return the modified group.
If the group should not be created then the function should throw an exception, e.g. UnauthorizedException.
- Delete - optional
(ctx: Context, oldGroup: Group) => void
Delete is invoked when someone is deleting a Group. The ‘oldGroup’ parameter is the Group that will be deleted.
If the group should not be deleted, throw an exception, e.g. UnauthorizedException.
UserPlugin
Plugins can implement this interface to monitor or modify creating, deleting and updating User objects.
- Create - optional
(ctx: Context, user: User) => User| null
Create is a function that is invoked when someone is creating a User.
If you return null from this function, then the User will be created as specified by the caller.
If you wish to modify the User that will be created, then the function should return the modified user.
If the user should not be created then the function should throw an exception, e.g. UnauthorizedException.
- Update - optional
(ctx: Context, oldUser: User, user: User) => User| null
Update is a function that is invoked when someone is updating a User. The oldUser parameter contains the previous value of the user. The user parameter contains the new value of the user.
If you return null from this function, then the User will be created as specified by the caller.
If you wish to modify the User, then the function should modify the User and return the modified user.
If the user should not be created then the function should throw an exception, e.g. UnauthorizedException.
- Delete - optional
(ctx: Context, oldUser: User) => void
Delete is invoked when someone is deleting a User. The ‘oldUser’ parameter is the User that will be deleted.
If the user should not be deleted, throw an exception, e.g. UnauthorizedException.
SSHPlugin
Plugins can implement this interface to modify how SSH keys and sessions are handled.
- AuthorizedKeys - optional
(ctx: Context, user: User, account: Account, authorizedKeys: Array<string>) => Array<string> | undefined
AuthorizedKeys is used when determining which SSH keys should be assigned to the specified account. To modify the SSH keys, return a array. If the keys should not be modified, return undefined.
LifecyclePlugin
Plugins can implement this interface to modify how SSH keys and sessions are handled.
- GetUserForAccount - optional
(ctx: Context, app: App, account: Account) => User | undefined
GetUserForAccount in invoked when an unknown account is discovered in an app. If this function returns an existing user, then the account is associated with the account. If you return a new User then that user is created and the account associated with it. If the function returns undefined, then the default mapping is applied.
Context
Context is the first argument passed to each of the interception functions. This class provides information about the user attempting the operation.
- Tenant - Tenant
- AuthorizedUser - User
- IntegrityLevel - IntegrityLevel
- Intent - IntegrityLevelChangeIntent (optional)
Data
Data is the type of the global data
variable that describes other objects in the system.
- Tenant - TenantData
- Accounts - AccountsData
- AccountChanges - AccountChangesData
- Apps - AppsData
- Groups - GroupsData
- Users - UsersData
TenantData
TenantData is the type of the global object data.Tenant
which provides access to the global Tenant object.
- Get
(): Tenant
Fetch the Tenant with the specified object ID.
AccountsData
AccountsData is the type of the global object data.Accounts
which provides access to Account objects.
- Get
(id: string): Account
Fetch the Account with the specified object ID.
- List
(opts: ListOptions, cb: (account: Account) => void): void
List invokes the caller-provided callback with each account that matches the filters specified in opts.
AccountChangesData
AccountChangesData is the type of the global object data.AccountChanges
which provides access to AccountChange objects.
- Get
(id: string): AccountChange
Fetch the AccountChange with the specified object ID.
- List
(opts: ListOptions, cb: (accountChange: AccountChange) => void): void
List invokes the caller-provided callback with each account that matches the filters specified in opts.
AppsData
AppsData is the type of the global object data.Apps
which provides access to App objects.
- Get
(id: string): App
Fetch the App with the specified object ID.
- List
(opts: ListOptions, cb: (app: App) => void): void
List invokes the caller-provided callback with each account that matches the filters specified in opts.
GroupsData
GroupsData is the type of the global object data.Groups
which provides access to Group objects.
- Get
(id: string): Group
Fetch the Group with the specified object ID.
- List
(opts: ListOptions, cb: (group: Group) => void): void
List invokes the caller-provided callback with each account that matches the filters specified in opts.
UsersData
UsersData is the type of the global object data.Users
which provides access to User objects.
- Get
(id: string): User
Fetch the User with the specified object ID.
- List -
(opts: ListOptions, cb: (user: User) => void): void
Exceptions
The following exception classes may be used to signal certain rejection conditions. You are free to throw your own exceptions, but these may trigger specific behavior.
UnauthorizedException
UnauthorizedException should be thrown by functions when the authorization context lacks sufficient authorization to proceed.
- message - string
ForbiddenException
ForbiddenException should be thrown by functions when the called is prohibited from taking the action requested.
- message - string
BadRequestException
BadRequestException should be thrown by functions when the object modification is malformed, for example, if an email address doesn’t match a convention.
- message - string
ListOptions
ListOptions is the type of the opts argument to the List methods for each data object. It specifies which objects to return.
- Limit - number - the maximum number of items to return
- Order - Array<string> - order the returned objects by the specified field names. Prefix a string with a dash to reverse the order.
- Filter - Array<ListFilter> - filter objects to only those that match the filter expression. (Note: although the API implies that multiple filters may be specified, for most objects, only one filter expression is allowed. This may change in future versions of the interface.)
ListFilter
ListFilter specifies an object filter that can be applied.
- Field - string - the name of the field. Nested fields can be specified by separating field names by a dot, e.g.
Name.FullName
. - Operator - string - the match operation to apply, one of
<
,<=
,=
,>
, or>=
. - Value - any - the value to match against.
Metadata
Metadata describes information about the state of the object.
- ID - string - The unique identifier of the object.
- Etag - string - An opaque string that changes whenever the object changes.
- Created - Date - The date & time when the object was created.
- Updated - Date - The data & time when the object was last modified.