Managing themes

Introduction

In this guide you will learn how to manage themes in your IBM Security Verify tenant. Themes allow you to customise the look and feel of web pages and notification e-mails seen by your end users.

You can have multiple themes in your tenant and you can assign themes to one or more applications. There is also a default theme which is used to render pages that are not associated with an application.

At the time of writing there is no UI associated with managing import and export of themes within the administration UI. Instead, you must use REST calls. This article will show how to make the required REST class using curl.

Assigning an imported theme to an application is part of the administration UI. This process will also be described in this guide.

Pre-requisites

You will need to get an access token that is authorized to manage themes. The easiest way to do this is to create an API client with the Manage Templates entitlement and then run the Client Credentials grant type flow to get an access token.

In order to fully appreciate themes, you will need to have at least one application defined in your IBM Security Verify tenant. If you don't have an application yet you can Connect a sample application.

You will need the curl command-line utility. This is built into most Linux systems and MacOS. However, if necessary, you can download curl here.

Optionally, if you want to automate parsing of JSON API responses, you will need the jq utility. You can download jq here.

Variables

In this guide the following variables are used:

NameExample valueDescription
tenant_urltenant.verify.ibm.comThe URL of your IBM Security Verify tenant.
access_tokeniZ5Gfz66HsNYSoJxhVe7N3u6cdBCHFYWgDOCAsNFThe access token obtained from your tenant's token service that has the Manage templates permission.

You should set these variables on the command line like this:

export tenant_url=tenant.verify.ibm.com
export access_token=iZ5Gfz66HsNYSoJxhVe7N3u6cdBCHFYWgDOCAsNF

Get a list of available themes

First you will use your access token to get a list of the available themes in your tenant. This will also serve to test the access token.

curl -H "Authorization: Bearer ${access_token}" -X GET "https://${tenant_url}/v1.0/branding/themes"

The result will have this format:

{
  "count": 1,
  "limit": 200,
  "page": 1,
  "total": 1,
  "themeRegistrations": [
    {
      "name": "default",
      "description": "Default Theme",
      "id": "default"
    }
  ]

The output above was from a clean tenant. You can see that only a single default theme exists.

Download a theme package and extract

A theme package is downloaded by making a GET request to the REST endpoint for that theme.
The REST endpoint for a theme includes the theme ID. The theme package is returned as a ZIP archive.

📘

Get original theme

You can specify master as the theme ID to download the original theme package. This is useful if you have updated the default theme and need to get an unmodified version.

Use the following curl command to download the default theme to a file named default-theme.zip:

curl -H "Authorization: Bearer ${access_token}" -X GET "https://${tenant_url}/v1.0/branding/themes/default" -o default-theme.zip

You now need to extract the ZIP file to get at the template files it contains. You can use your own favourite archive tool or, if you have unzip, use this command to unzip to a directory called extracted-theme:

unzip -d extracted-theme default-theme.zip

You now have an extracted-theme directory containing the exported theme templates.

Explore the theme folder structure

If you look in the extracted-theme directory that you just created, you'll see it contains a single templates directory. This is the root directory for the theme package. Inside this directory you'll find the following folders which divide up the template files by purpose:

FolderPurpose
authenticationHTML pages used during authentication to IBM Security Verify. This includes federation from identity sources, initial authentication, and multi-factor authentication. Password change and logout pages are also found here.
commonAssets used by all pages in the theme.
Importantly, the page_style.css can be used to override CSS to change the look and feel of end user pages that are not otherwise editible.
notificationse-mail messages used to send notifications. This includes notifications related to user management, certification campaigns, and access require processing.
user_flowsHTML pages used to present user flows. These are just HTML wrappers around the page content designed in the user flow designer.

The last folder in the directory structure is the locale folder. In the default theme, most locale-specific content is stored within the templates/common/labels folder. You'll see that there are many language folders there. In most other places there is only a default folder. This folder is used when no other folder matches the requested locale. The default folder is used to present US English content.

Make changes to common files

The assets in the /templates/common directory are used by other pages in the theme package. You will now make changes to some of these files.

Update a label

The template_labels.properties file contains labels that are used in the default template pages. You can identify these labels in other template files because they are surrounded by dollar ($) signs (e.g. $PRODUCT_NAME$).

Open the file templates/common/default/template_labels.properties in a text editor.

Find the LOGIN_USER_NAME definition and change it to something new:

# A label for the username input
$LOGIN_USER_NAME$=Email address

Update page header

Open the file /templates/common/page_components/page_header.html in a text editor. This HTML snippet is included at the top of each page of the theme.

You can see that this snippet is simply loading a logo image. This image is actually loaded from the /templates/common/logo/default directory. Notice the ?themeId=@THEME_ID@ at the end of the URL. This query string controls which theme will be used when loading the file. The THEME_ID macro will be set to the current theme. Macros are identified because they are surrounded by at (@) signs.

Add an additional line to the file so it looks like this:

<div class='heading'>
      <img src="template/v1.0/static/logo.svg?themeId=@THEME_ID@">
      <p>Customized by themes</p>
</div>

Save the updated file.

Create new theme package and upload as new theme

You will now ZIP up the updated theme package and upload it to your IBM Security Verify tenant as a new theme.

To create the package, use your favourite archive tool to ZIP the templates directory. If you have the zip utility, make sure you are in the default-theme directory and use this command:

zip -r test-theme.zip templates

This will save the test-theme.zip file to the current directory.

To register a new theme using the new theme package, use the following curl command.
If your access token has expired you may need to run the OAuth token flow again to get a new one.

curl -H "Authorization: Bearer ${access_token}" -X POST "https://${tenant_url}/v1.0/branding/themes" -F [email protected] -F configuration='{"name":"test","description":"Test Theme"}'

Look up theme ID

Each theme has a theme ID. You need this theme ID in order to manually specify a theme for page rendering (useful for testing) or to update a theme that already exists. Use the following curl command to lookup the theme ID for your new test theme:

curl -H "Authorization: Bearer ${access_token}" -X GET "https://${tenant_url}/v1.0/branding/themes"

The output will look like this:

{
  "count": 2,
  "limit": 200,
  "page": 1,
  "total": 2,
  "themeRegistrations": [
    {
      "name": "test",
      "id": "b18d817b-6409-4fa1-8de4-308519937d25"
    },
    {
      "name": "default",
      "description": "Default Theme",
      "id": "default"
    }
  ]
}

Look for the id associated with the test theme. In the example above it is b18d817b-6409-4fa1-8de4-308519937d25. Yours will be different. Save this to environment variable theme_id:

export theme_id=b18d817b-6409-4fa1-8de4-308519937d25

It you have jq available, you can run this command which will make the REST call, parse the JSON response and populate the theme_id environment variable:

export theme_name=test
export theme_id=`curl -H "Authorization: Bearer ${access_token}" -X GET "https://${tenant_url}/v1.0/branding/themes" | jq -r ".themeRegistrations[] | select(.name==\"${theme_name}\") | .id"`
echo ${theme_id}

Test the updated theme

Connect to your tenant using a URL like this:

https://{tenant_url}/idaas/mtfim/sps/idaas/login?runtime=true&themeId={theme_id}

When the page renders the themeId specified in the query string will be used. You should see the changes from your test theme reflected in the displayed page:

1027

Login page with test theme applied

Assign a theme to an application

A theme can be applied to an application using the administration UI of your IBM Security Verify tenant. If you open the properties for an application you will find the theme selector on the General tab:

1014

Theme selector in application definition

Select your new test theme as the Theme and save the application definition.

Test an application-specific theme

The theme associated with an application is used when IBM Security Verify performs actions that are directly associated with the application. For example:

  • Performing an initial authentication triggered by accessing the application
  • Performing multi-factor authentication when attempting to access the application
  • Receiving an e-mail related to authorization workflow for the application
  • Receiving e-mails related to a certification campaign for the application

To test the application-specific theme, log out of all IBM Security Verify sessions (or use a clean browser session) and then trigger authentication from the application where you have assigned the test theme.

If you are using the IBM Security Verify Sample SAML application, you can access
https://verifyapp.mybluemix.net and then click Login. This will trigger an authentication in IBM Security Verify and the theme associated with the application will be used.

Updating a theme package

A theme that already exists can be updated by calling the REST endpoint for that theme.

The REST endpoint for a theme includes the theme ID. For the commands below it is assumed that the theme ID is held in an environment variable named theme_id. If you need to look this up, check out the instructions above.

After creating an updated theme package ZIP file, use the following curl command to apply the update:

curl -H "Authorization: Bearer ${access_token}" -X PUT "https://${tenant_url}/v1.0/branding/themes/${theme_id}" -F [email protected]

Manipulating individual files

In addition to importing and exporting theme packages, it is also possible to import and export individual theme files.

Export a single file

You can download a single file from a theme. The REST endpoint used for this includes the theme ID and the path of the file to be exported. For example, to download only the page footer template, use the following curl command:

curl -H "Authorization: Bearer ${access_token}" -X GET "https://${tenant_url}/v1.0/branding/themes/${theme_id}/common/page_components/default/page_footer.html" -o test-page_footer.html

Edit the downloaded file

Open the downloaded test-page_footer.html file and edit it so that it contains the following:

<footer class="login-footer" role="contentinfo">
<p>Themed for sample application</p>
</footer> 

Save the updated file.

Import a single file

You can replace (or add) a single file in a theme. The REST endpoint used for this includes the theme ID and the path of the file to be replaced. For example, to replace only page footer within the theme use the following curl command:

curl -H "Authorization: Bearer ${access_token}" -X PUT "https://${tenant_url}/v1.0/branding/themes/${theme_id}/common/page_components/default/page_footer.html" -F file="@test-page_footer.html"

At this point you can test the updated theme, either by specifying the theme ID directly or triggering a login using an application that has the theme configured.

Revert a file to default

You can revert a customized file back to its original state by calling its endpoint with the DELETE method. For example, to revert the page_footer.html file, use the following curl command:

curl -H "Authorization: Bearer ${access_token}" -X DELETE "https://${tenant_url}/v1.0/branding/themes/${theme_id}/common/page_components/default/page_footer.html"

Download a ZIP file containing only updated files

If you want to download only the modified files from a theme, this can be done using the following curl command:

curl -H "Authorization: Bearer ${access_token}" -X GET "https://${tenant_url}/v1.0/branding/themes/${theme_id}?customized_only=true" -o test-theme-updates-only.zip

You can also PUT an archive containing only a subset of theme files. This will replace only these files in the theme.

Delete a theme

You can delete a theme using the DELETE method on the theme REST endpoint. A call like this will delete a theme:

🚧

Theme files will be deleted

This API call will remove the theme including all files associated with the theme. Make sure you have a local copy of any theme files you might want to use again in the future.

curl -H "Authorization: Bearer ${access_token}" -X DELETE "https://${tenant_url}/v1.0/branding/themes/${theme_id}"

Note that a theme cannot be deleted if it is referenced in one or more application definitions. If this is the case you will receive an error (with 405 status code):

{
  "messageId":"CSIAZ3024E",
  "messageDescription":"The system cannot delete the theme with the ID [b18d817b-6409-4fa1-8de4-308519937d25] because it is used by an application."
}

Reset default theme to original state

To reset the default theme to its original state, export the original theme package and then use it to replace the default theme package. These two curl commands will perform these steps:

🚧

Theme files will be overwritten

These API calls will overwrite all the files in the default theme. Make sure you have a local copy of any theme files you might want to use again in the future.

curl -H "Authorization: Bearer ${access_token}" -X GET "https://${tenant_url}/v1.0/branding/themes/master" -o original-theme.zip
curl -H "Authorization: Bearer ${access_token}" -X PUT "https://${tenant_url}/v1.0/branding/themes/default" -F [email protected]

Reset all branding

If you want to reset all branding back to its original state, you can use the following templates API. This API request will delete all themes and reset the default theme back to its original state.

Before you use this API, all applications must be configured to use the default theme. This API will return an error if any theme is in use.

❗️

This API request will delete all themes

Make sure you have exported any themes that you might want to restore later.

curl -H "Authorization: Bearer ${access_token}" -X DELETE "https://${tenant_url}/v1.0/branding/reset"

💎

Jon Harry, IBM Security