Like what you see? Have a play with our trial version.

Users can be added to one or more Groups. Groups in Yellowfin are predominately used for defining access to content or for broadcasting content. Using Groups can be more convenient than dealing with each individual user.

Group Definitions are defined by components, which could be individual users, or other components that represent multiple users, like other groups, LDAP groups or Roles.  

The REST API allows for the management of the group components and for retrieving the resultant group members of the expanded group components. 

When onboarding new users programmatically, it may be necessary to grant a new user access to certain content based on external criteria.  A user may have access to a module in the host application that Yellowfin is connected to. Access to this module grants access to specific domain-related reports. For example, users with access to the Finance module may be added to a “Finance Users” group, and that Group can be given access to all Finance related reports and dashboards. 

Group membership can be implemented during user on-boarding, however if a user’s access can change arbitrarily it may be necessary to update group membership periodically. There are different ways in which this could be implemented. The lazy paradigm involves updating group membership as a user attempts to access Yellowfin, and this could be part of the SSO login process.  Alternatively, group members could be updated directly when the user’s permissions change in the host application.

Listing Groups

A list of groups can be retrieved from the GET /api/user-groups end-point User Groups. This can also be used to check whether a group already exists, or to find a group by another identifier, like its name. 

 The following examples illustrate how to retrieve a list groups for a user in various programming languages.

Java
package rest.code.examples;
import java.io.IOException;
import java.util.Random;
import org.apache.hc.client5.http.fluent.Content;
import org.apache.hc.client5.http.fluent.Request;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
 * Create a user using the Yellowfin REST API
 */
public class ListUserGroups {
    public static void main(String[] args) throws Exception {

        System.out.println(""List Groups"");

        String host = ""http://localhost:8080/Yellowfin"";
        String restUsername = ""admin@yellowfin.com.au"";
        String restPassword = ""test"";

        String token = generateToken(host, restUsername, restPassword);

        Content c = Request.get(host + ""/api/user-groups"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement groupList = jsonObject.get(""items"");
        JsonArray groups = groupList.getAsJsonArray();

        System.out.println(groups.size() + "" groups retrieved."");

        for (int i=0; i < groups.size(); i++ ) {
            JsonObject group = groups.getAsJsonArray().get(i).getAsJsonObject();
            System.out.println(""Group "" + group.get(""userGroupId"").getAsInt() + "": "" + group.get(""shortDescription"").getAsString());
        }

    }


    /*
     *  This function generates an access token for a user that will grant them access to
     *  call REST API endpoints.
     */

    public static String generateToken(String host, String username, String password) throws IOException {

        Content c = Request.post(host + ""/api/refresh-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong())
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""}"", null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement accessToken = jsonObject.getAsJsonObject(""_embedded"").getAsJsonObject(""accessToken"").get(""securityToken"");

        if (accessToken!=null) {
            System.out.println(""Access Token: "" + accessToken);
        } else {
            System.out.println(""Token not retrieved successfully"");
            System.exit(-1);
        }
        return accessToken.getAsString();

    }

}
C#
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace YellowfinAPIExamples
{
    public class ListUserGroups
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine(""List Groups"");

            string host = ""http://localhost:8080/Yellowfin"";
            string restUsername = ""admin@yellowfin.com.au"";
            string restPassword = ""test"";

            string token = await GenerateToken(host, restUsername, restPassword);

            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", ""ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "" , nonce="" + new Random().NextInt64() + "", token="" + token);
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                HttpResponseMessage response = await httpClient.GetAsync(host + ""/api/user-groups"");
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                    JArray groups = (JArray)jsonObject[""items""];

                    Console.WriteLine(groups.Count + "" groups retrieved."");

                    foreach (JObject group in groups)
                    {
                        Console.WriteLine(""Group "" + group[""userGroupId""] + "": "" + group[""shortDescription""]);
                    }
                }
                else
                {
                    Console.WriteLine(""Failed to retrieve user groups. Status code: "" + response.StatusCode);
                }
            }
        }

        static async Task<string> GenerateToken(string host, string restUsername, string restPassword)
        {
            using (var httpClient = new HttpClient())
            {
                // Generate nonce
                long nonce = new Random().NextInt64();

                // Create HTTP request
                var request = new HttpRequestMessage(HttpMethod.Post, host + ""/api/refresh-tokens"");
                request.Headers.Add(""Authorization"", ""YELLOWFIN ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "", nonce="" + nonce);
                request.Headers.Add(""Accept"", ""application/vnd.yellowfin.api-v1+json"");
                request.Content = new StringContent(
                    JsonConvert.SerializeObject(new { userName = restUsername, password = restPassword }),
                    System.Text.Encoding.UTF8,
                    ""application/json""
                );

                // Send request and get response
                HttpResponseMessage response = await httpClient.SendAsync(request);
                if (response.IsSuccessStatusCode)
                {
                    string responseContent = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseContent);
                    string accessToken = jsonObject[""_embedded""][""accessToken""][""securityToken""].ToString();

                    if (!string.IsNullOrEmpty(accessToken))
                    {
                        Console.WriteLine(""Access Token: "" + accessToken);
                        return accessToken;
                    }
                }
                else
                {
                    Console.WriteLine(""Token not retrieved successfully. Status code: "" + response.StatusCode);
                }
                
                Environment.Exit(-1);
                return null; // Just to satisfy compiler, this won't be reached.
            }
        }
    }
}
Go
package main

import (
	""bytes""
	""encoding/json""
	""fmt""
	""io/ioutil""
	""math/rand""
	""net/http""
	""time""
)

func main() {
	host := ""http://localhost:8080/Yellowfin""
	restUsername := ""admin@yellowfin.com.au""
	restPassword := ""test""

	token, err := generateToken(host, restUsername, restPassword)
	if err != nil {
		fmt.Println(""Error generating token:"", err)
		return
	}

	fmt.Println(""List Groups"")

	client := &http.Client{}
	req, err := http.NewRequest(""GET"", host+""/api/user-groups"", nil)
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return
	}

	nonce := rand.Int63()

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(body, &jsonResponse)
	if err != nil {
		fmt.Println(""Error parsing JSON response:"", err)
		return
	}

	groupList := jsonResponse[""items""].([]interface{})
	groups := make([]map[string]interface{}, len(groupList))
	for i, v := range groupList {
		groups[i] = v.(map[string]interface{})
	}

	fmt.Printf(""%d groups retrieved.\n"", len(groups))

	for _, group := range groups {
		fmt.Printf(""Group %v: %v\n"", group[""userGroupId""], group[""shortDescription""])
	}
}

func generateToken(host, username, password string) (string, error) {
	nonce := rand.Int63()

	requestBody, err := json.Marshal(map[string]string{
		""userName"": username,
		""password"": password,
	})
	if err != nil {
		return """", err
	}

	client := &http.Client{}
	req, err := http.NewRequest(""POST"", host+""/api/refresh-tokens"", bytes.NewBuffer(requestBody))
	if err != nil {
		return """", err
	}

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d"", time.Now().UnixMilli(), nonce))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return """", err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return """", err
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(body, &jsonResponse)
	if err != nil {
		return """", err
	}

	accessToken, ok := jsonResponse[""_embedded""].(map[string]interface{})[""accessToken""].(map[string]interface{})[""securityToken""].(string)
	if !ok {
		return """", fmt.Errorf(""Token not retrieved successfully"")
	}

	return accessToken, nil
}
JavaScript
const fetch = require(""node-fetch"");

async function main() {
    console.log(""List Groups"");

    const host = ""http://localhost:8080/Yellowfin"";
    const restUsername = ""admin@yellowfin.com.au"";
    const restPassword = ""test"";

    const token = await generateToken(host, restUsername, restPassword);

    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/user-groups`, {
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const responseBody = await response.json();
        const groups = responseBody.items;

        console.log(`${groups.length} groups retrieved.`);

        groups.forEach(group => {
            console.log(`Group ${group.userGroupId}: ${group.shortDescription}`);
        });
    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

async function generateToken(host, username, password) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    const body = JSON.stringify({
        userName: username,
        password: password
    });

    try {
        const response = await fetch(`${host}/api/refresh-tokens`, {
            method: 'POST',
            headers: headers,
            body: body
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const accessToken = jsonResponse._embedded.accessToken.securityToken;

        if (accessToken) {
            console.log(`Access Token: ${accessToken}`);
            return accessToken;
        } else {
            console.log(""Token not retrieved successfully"");
            process.exit(-1);
        }
    } catch (error) {
        console.error(""Error:"", error.message);
    }

    return null;
}

main();
PHP
<?php
function main() {
    echo ""List Groups\n"";

    $host = ""http://localhost:8080/Yellowfin"";
    $restUsername = ""admin@yellowfin.com.au"";
    $restPassword = ""test"";

    try {
        $token = generateToken($host, $restUsername, $restPassword);
    } catch (Exception $e) {
        echo ""Error generating token: "" . $e->getMessage();
        return;
    }

    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    try {
        $response = httpRequest('GET', ""$host/api/user-groups"", $headers);
        $jsonResponse = json_decode($response, true);
        $groups = $jsonResponse[""items""];
        echo count($groups) . "" groups retrieved.\n"";

        foreach ($groups as $group) {
            echo ""Group "" . $group[""userGroupId""] . "": "" . $group[""shortDescription""] . ""\n"";
        }
    } catch (Exception $e) {
        echo ""Error sending request: "" . $e->getMessage();
    }
}

function generateToken($host, $restUsername, $restPassword) {
    $nonce = mt_rand();

    $requestBody = json_encode(array(
        ""userName"" => $restUsername,
        ""password"" => $restPassword
    ));

    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('POST', ""$host/api/refresh-tokens"", $headers, $requestBody);
    $jsonResponse = json_decode($response, true);

    if (isset($jsonResponse[""_embedded""][""accessToken""][""securityToken""])) {
        $accessToken = $jsonResponse[""_embedded""][""accessToken""][""securityToken""];
        echo ""Access Token: "" . $accessToken;

        return $accessToken;
    } else {
        throw new Exception(""Token not retrieved successfully"");
    }
}

function httpRequest($method, $url, $headers, $data = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception('Error: ' . curl_error($ch));
    }

    curl_close($ch);

    return $response;
}

main();
?>
Python
import json
import random
import time

import requests

def main():
    print(""List Groups"")

    host = ""http://localhost:8080/Yellowfin""
    rest_username = ""admin@yellowfin.com.au""
    rest_password = ""test""

    try:
        token = generate_token(host, rest_username, rest_password)

        # Create headers
        nonce = random.randint(0, 2 ** 63 - 1)
        headers = {
            'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
            'Accept': 'application/vnd.yellowfin.api-v1+json',
            'Content-Type': 'application/json'
        }

        # Send request to get user groups
        response = requests.get(host + ""/api/user-groups"", headers=headers)
        response.raise_for_status()

        # Parse response
        groups = response.json()[""items""]
        print(f""{len(groups)} groups retrieved."")

        # Print group details
        for group in groups:
            print(f""Group {group['userGroupId']}: {group['shortDescription']}"")
    except Exception as e:
        print(f""Error: {e}"")

def generate_token(host, rest_username, rest_password):
    # Generate nonce
    nonce = random.randint(0, 2 ** 63 - 1)

    # Create request body
    request_body = json.dumps({
        ""userName"": rest_username,
        ""password"": rest_password
    })

    # Create request headers
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    # Send HTTP request
    response = requests.post(host + ""/api/refresh-tokens"", headers=headers, data=request_body)
    response.raise_for_status()

    # Parse JSON response
    json_response = response.json()
    access_token = json_response[""_embedded""][""accessToken""][""securityToken""]
    print(""Access Token:"", access_token)

    return access_token

if __name__ == ""__main__"":
    main()

Creating a User Group

Groups can be created using the POST /api/user-groups end-point Create User Group. The model for User Group creation is:

{
  "groupName": "New Group",
  "groupDescription": "This a new group",
  "groupStatus": "OPEN",
  "isSecureGroup": "false"
}

After the successful creation of a group, the service will return a User Group model that contains the unique userGroupId of the new group. The userGroupId can then be used for identifying the group in other services. This service creates an empty group, group member components need to be added with the POST /api/user-groups/{groupId}/members end-point.

The following examples illustrate how to create a user group in various programming languages.

Java
package rest.code.examples;
import java.io.IOException;
import java.util.Random;
import org.apache.hc.client5.http.fluent.Content;
import org.apache.hc.client5.http.fluent.Request;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
 * Create a user using the Yellowfin REST API
 */
public class CreateUserGroup {
    public static void main(String[] args) throws Exception {

        String host = ""http://localhost:8080/Yellowfin"";
        String restUsername = ""admin@yellowfin.com.au"";
        String restPassword = ""test"";

        String newGroupName = ""New Group"";
        String newGroupDescription = ""This is a new group"";

        String token = generateToken(host, restUsername, restPassword);

        String createGroupPayload =
                ""{"" +
                        ""  \""groupName\"": \"""" + newGroupName + ""\"","" +
                        ""  \""groupDescription\"": \"""" + newGroupDescription + ""\"","" +
                        ""  \""groupStatus\"": \""OPEN\"","" +
                        ""  \""isSecureGroup\"": \""false\"" "" +
                        ""}"";

        System.out.println(""Payload: "" + createGroupPayload);

        Content c = Request.post(host + ""/api/user-groups"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(createGroupPayload, null)
                .execute().returnContent();

        System.out.print(c.asString());

    }



    /*
     *  This function generates an access token for a user that will grant them access to
     *  call REST API endpoints.
     */

    public static String generateToken(String host, String username, String password) throws IOException {

        Content c = Request.post(host + ""/api/refresh-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong())
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""}"", null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement accessToken = jsonObject.getAsJsonObject(""_embedded"").getAsJsonObject(""accessToken"").get(""securityToken"");

        if (accessToken!=null) {
            System.out.println(""Access Token: "" + accessToken);
        } else {
            System.out.println(""Token not retrieved successfully"");
            System.exit(-1);
        }
        return accessToken.getAsString();

    }

}
C#
using System.Net.Http.Headers;
using Newtonsoft.Json.Linq;

namespace rest.code.examples
{
    public class CreateUserGroup
    {
        static async Task Main(string[] args)
        {
            string host = ""http://localhost:8080/Yellowfin"";
            string restUsername = ""admin@yellowfin.com.au"";
            string restPassword = ""test"";

            string newGroupName = ""New Group"";
            string newGroupDescription = ""This is a new group"";

            string token = await GenerateToken(host, restUsername, restPassword);

            string createGroupPayload = ""{"" +
                    ""  \""groupName\"": \"""" + newGroupName + ""\"","" +
                    ""  \""groupDescription\"": \"""" + newGroupDescription + ""\"","" +
                    ""  \""groupStatus\"": \""OPEN\"","" +
                    ""  \""isSecureGroup\"": \""false\"" "" +
                    ""}"";

            Console.WriteLine(""Payload: "" + createGroupPayload);

            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", ""ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "" , nonce="" + new Random().NextInt64() + "", token="" + token);
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));
                var content = new StringContent(createGroupPayload);
                content.Headers.ContentType = new MediaTypeHeaderValue(""application/json"");

                var response = await httpClient.PostAsync(host + ""/api/user-groups"", content);
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(responseBody);
                }
                else
                {
                    Console.WriteLine(""Failed to create user group. Status code: "" + response.StatusCode);
                }
            }
        }

        static async Task<string> GenerateToken(string host, string restUsername, string restPassword)
        {
            using (var client = new HttpClient())
            {
                // Generate nonce
                long nonce = new Random().NextInt64();

                // Create HTTP request
                var request = new HttpRequestMessage(HttpMethod.Post, host + ""/api/refresh-tokens"");
                request.Headers.Add(""Authorization"", ""YELLOWFIN ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "", nonce="" + nonce);
                request.Headers.Add(""Accept"", ""application/vnd.yellowfin.api-v1+json"");
                request.Content = new StringContent(
                    $""{{\""userName\"": \""{restUsername}\"", \""password\"": \""{restPassword}\""}}"",
                    System.Text.Encoding.UTF8,
                    ""application/json""
                );

                // Send request and get response
                HttpResponseMessage response = await client.SendAsync(request);
                string responseContent = await response.Content.ReadAsStringAsync();

                // Parse JSON response
                JObject jsonObject = JObject.Parse(responseContent);
                string accessToken = jsonObject[""_embedded""][""accessToken""][""securityToken""].ToString();

                if (!string.IsNullOrEmpty(accessToken))
                {
                    Console.WriteLine(""Access Token: "" + accessToken);
                }
                else
                {
                    Console.WriteLine(""Token not retrieved successfully"");
                    Environment.Exit(-1);
                }

                return accessToken;
            }
        }
    }
}
Go
package main

import (
	""bytes""
	""encoding/json""
	""fmt""
	""io/ioutil""
	""math/rand""
	""net/http""
	""time""
)

func main() {
	host := ""http://localhost:8080/Yellowfin""
	restUsername := ""admin@yellowfin.com.au""
	restPassword := ""test""

	newGroupName := ""New Group""
	newGroupDescription := ""This is a new group""

	token, err := generateToken(host, restUsername, restPassword)
	if err != nil {
		fmt.Println(""Error generating token:"", err)
		return
	}

	createGroupPayload := fmt.Sprintf(`{
		""groupName"": ""%s"",
		""groupDescription"": ""%s"",
		""groupStatus"": ""OPEN"",
		""isSecureGroup"": ""false""
	}`, newGroupName, newGroupDescription)

	fmt.Println(""Payload:"", createGroupPayload)

	client := &http.Client{}
	req, err := http.NewRequest(""POST"", host+""/api/user-groups"", bytes.NewBufferString(createGroupPayload))
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return
	}

	nonce := rand.Int63()

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return
	}

	fmt.Println(string(body))
}

func generateToken(host, restUsername, restPassword string) (string, error) {
	// Generate nonce
	nonce := rand.Int63()

	// Create request body
	requestBody, err := json.Marshal(map[string]string{
		""userName"": restUsername,
		""password"": restPassword,
	})
	if err != nil {
		fmt.Println(""Error marshaling request body:"", err)
		return """", err
	}

	// Create HTTP client
	client := &http.Client{}

	// Create HTTP request
	request, err := http.NewRequest(""POST"", host+""/api/refresh-tokens"", bytes.NewBuffer(requestBody))
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return """", err
	}

	// Add request headers
	request.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d"", time.Now().UnixMilli(), nonce))
	request.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	request.Header.Set(""Content-Type"", ""application/json"")

	// Send HTTP request
	response, err := client.Do(request)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return """", err
	}
	defer response.Body.Close()

	// Read response body
	responseBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return """", err
	}

	// Parse JSON response
	var jsonResponse map[string]interface{}
	err = json.Unmarshal(responseBody, &jsonResponse)
	if err != nil {
		fmt.Println(""Error parsing JSON response:"", err)
		return """", err
	}

	// Get access token from response
	accessToken, ok := jsonResponse[""_embedded""].(map[string]interface{})[""accessToken""].(map[string]interface{})[""securityToken""].(string)
	if !ok {
		fmt.Println(""Token not retrieved"")
		return """", fmt.Errorf(""Token not retrieved successfully"")
	}

	return accessToken, nil
}
JavaScript
const fetch = require(""node-fetch"");

async function main() {
    const host = ""http://localhost:8080/Yellowfin"";
    const restUsername = ""admin@yellowfin.com.au"";
    const restPassword = ""test"";

    const newGroupName = ""New Group"";
    const newGroupDescription = ""This is a new group"";

    const token = await generateToken(host, restUsername, restPassword);

    if (token === null) {
        console.error(""Failed to retrieve access token"");
        return;
    }

    const createGroupPayload = `{
        ""groupName"": ""${newGroupName}"",
        ""groupDescription"": ""${newGroupDescription}"",
        ""groupStatus"": ""OPEN"",
        ""isSecureGroup"": ""false""
    }`;

    console.log(""Payload:"", createGroupPayload);

    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/user-groups`, {
            method: 'POST',
            headers: headers,
            body: createGroupPayload
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const responseBody = await response.text();
        console.log(responseBody);
    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

async function generateToken(host, restUsername, restPassword) {
    // Generate nonce
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    // Create request headers
    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    // Create request body
    const body = `{
        ""userName"": ""${restUsername}"",
        ""password"": ""${restPassword}""
    }`;

    try {
        // Make POST request
        const response = await fetch(`${host}/api/refresh-tokens`, {
            method: 'POST',
            headers: headers,
            body: body
        });

        // Check if request was successful
        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        // Parse JSON response
        const jsonResponse = await response.json();
        const accessToken = jsonResponse._embedded.accessToken.securityToken;

        if (accessToken) {
            console.log(`Access Token: ${accessToken}`);
        } else {
            console.log(""Token not retrieved"");
        }

        return accessToken;
    } catch (error) {
        console.error(""Error:"", error.message);
    }

    return null;
}

main();
PHP
<?php
function main() {
    $host = ""http://localhost:8080/Yellowfin"";
    $restUsername = ""admin@yellowfin.com.au"";
    $restPassword = ""test"";

    $newGroupName = ""New Group"";
    $newGroupDescription = ""This is a new group"";

    try {
        $token = generateToken($host, $restUsername, $restPassword);
    } catch (Exception $e) {
        echo ""Error generating token: "" . $e->getMessage();
        return;
    }

    $createGroupPayload = '{""groupName"":""' . $newGroupName . '"",""groupDescription"":""' . $newGroupDescription . '"",""groupStatus"":""OPEN"",""isSecureGroup"":""false""}';

    echo ""Payload: "" . $createGroupPayload . ""\n"";

    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    try {
        $response = httpRequest('POST', ""$host/api/user-groups"", $headers, $createGroupPayload);
        echo $response;
    } catch (Exception $e) {
        echo ""Error sending request: "" . $e->getMessage();
    }
}

function generateToken($host, $restUsername, $restPassword) {
    // Generate nonce
    $nonce = mt_rand();

    // Create request body
    $requestBody = '{""userName"":""' . $restUsername . '"",""password"":""' . $restPassword . '""}';

    // Create request headers
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('POST', ""$host/api/refresh-tokens"", $headers, $requestBody);

    // Parse JSON response
    $jsonResponse = json_decode($response, true);

    // Get access token from response
    if (isset($jsonResponse[""_embedded""][""accessToken""][""securityToken""])) {
        $accessToken = $jsonResponse[""_embedded""][""accessToken""][""securityToken""];
        echo ""Access Token: "" . $accessToken;

        return $accessToken;
    } else {
        throw new Exception(""Token not retrieved successfully"");
    }
}

function httpRequest($method, $url, $headers, $data = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception('Error: ' . curl_error($ch));
    }

    curl_close($ch);

    return $response;
}

main()
?>
Python
import json
import random
import time

import requests

def main():
    host = ""http://localhost:8080/Yellowfin""
    rest_username = ""admin@yellowfin.com.au""
    rest_password = ""test""

    new_group_name = ""New Group""
    new_group_description = ""This is a new group""

    try:
        token = generate_token(host, rest_username, rest_password)

        create_group_payload = (
            ""{""
            f""  \""groupName\"": \""{new_group_name}\"",""
            f""  \""groupDescription\"": \""{new_group_description}\"",""
            ""  \""groupStatus\"": \""OPEN\"",""
            ""  \""isSecureGroup\"": \""false\""""
            ""}""
        )

        print(""Payload:"", create_group_payload)

        nonce = random.randint(0, 2 ** 63 - 1)
        headers = {
            'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
            'Accept': 'application/vnd.yellowfin.api-v1+json',
            'Content-Type': 'application/json'
        }

        response = requests.post(host + ""/api/user-groups"", headers=headers, data=create_group_payload)
        response.raise_for_status()
        print(response.text)
    except Exception as e:
        print(f""Error: {e}"")

def generate_token(host, rest_username, rest_password):
    nonce = random.randint(0, 2 ** 63 - 1)

    request_body = json.dumps({
        ""userName"": rest_username,
        ""password"": rest_password
    })

    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    response = requests.post(host + ""/api/refresh-tokens"", headers=headers, data=request_body)
    response.raise_for_status()

    json_response = response.json()
    access_token = json_response[""_embedded""][""accessToken""][""securityToken""]
    print(""Access Token:"", access_token)

    return access_token

if __name__ == ""__main__"":
    main()

Add Members to a Group

Members can be added to a group using the POST /api/user-groups/{groupId}/members end-point Bulk-add User Group Members.

A list of new members can be posted using this end-point. The model that represents a group member is:

{
    "entityType": "PERSON",
    "entityCode": "",
    "entityId": 13235,
    "membershipType": "INCLUDED"
}

EntityType can be one of PERSON,  GROUP,  LDAP or ROLE.

EntityCode needs to be populated with a Role Code or LDAP group DN.

EntityId needs to be populated with either a user’s IpId, or a group’s IpId (where the IpId is the integer identifier for the member).

MembershipType can be one of INCLUDED or EXCLUDED. This determines whether the group member is included or explicitly excluded from the group.

The following examples illustrate how to add a user (identified by username), to a group (identified by its name) in various programming languages.

Java
package rest.code.examples;
import java.io.IOException;
import java.util.Random;
import org.apache.hc.client5.http.fluent.Content;
import org.apache.hc.client5.http.fluent.Request;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
 * Create a user using the Yellowfin REST API
 */
public class AddMemberToGroup {
    public static void main(String[] args) throws Exception {

        String host = ""http://localhost:8080/Yellowfin"";
        String restUsername = ""admin@yellowfin.com.au"";
        String restPassword = ""test"";

        String userGroupToAddUserTo = ""New Group"";
        String usernameOfUserToAdd = ""user1@yellowfin.com.au"";

        String token = generateToken(host, restUsername, restPassword);

        Integer userIpId = retrieveUserIpIdForUsername(host, token, usernameOfUserToAdd);

        Integer groupId = retrieveGroupIpIdForGroupName(host, token, userGroupToAddUserTo);

        String groupMembersPayload =
                ""[\n""
                        + ""    {\n""
                        + ""    \""entityType\"": \""PERSON\"",\n""
                        + ""    \""entityId\"": "" +  userIpId + "",\n""
                        + ""    \""membershipType\"": \""INCLUDED\""\n""
                        + ""    }\n""
                        + ""]"";

        System.out.println(""UserIpId: "" + userIpId);
        System.out.println(""GroupId: "" + groupId);
        System.out.println(""Payload: "" + groupMembersPayload);

        Content c = Request.post(host + ""/api/user-groups/"" + groupId + ""/members"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(groupMembersPayload, null)
                .execute().returnContent();

        System.out.println(""User "" + usernameOfUserToAdd +  "" added to group "" + userGroupToAddUserTo + "" successfully"");
        System.out.println(""Response: "" + c.asString());

    }

    public static Integer retrieveGroupIpIdForGroupName(String host, String token, String groupName) throws IOException {

        Content c = Request.get(host + ""/api/user-groups"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement groupList = jsonObject.get(""items"");
        JsonArray groups = groupList.getAsJsonArray();

        for (int i=0; i < groups.size(); i++ ) {
            JsonObject group = groups.getAsJsonArray().get(i).getAsJsonObject();
            if (groupName.equals(group.get(""shortDescription"").getAsString())) return group.get(""userGroupId"").getAsInt();
        }

        System.out.println(""Group could not be found for name:"" + groupName);
        System.exit(-1);

        return null;
    }

    public static Integer retrieveUserIpIdForUsername(String host, String token, String userName) throws IOException {

        Content c = Request.get(host + ""/api/rpc/users/user-details-by-username/"" + userName)
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong()+ "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement userIpJsonAttribute = jsonObject.get(""userId"");
        Integer userIpId = userIpJsonAttribute.getAsInt();

        return userIpId;

    }


    /*
     *  This function generates an access token for a user that will grant them access to
     *  call REST API endpoints.
     */

    public static String generateToken(String host, String username, String password) throws IOException {

        Content c = Request.post(host + ""/api/refresh-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong())
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""}"", null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement accessToken = jsonObject.getAsJsonObject(""_embedded"").getAsJsonObject(""accessToken"").get(""securityToken"");

        if (accessToken!=null) {
            System.out.println(""Access Token: "" + accessToken);
        } else {
            System.out.println(""Token not retrieved successfully"");
            System.exit(-1);
        }
        return accessToken.getAsString();

    }

}
C#
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace rest.code.examples
{
    public class AddMemberToGroup
    {
        static async Task Main(string[] args)
        {
            string host = ""http://localhost:8080/Yellowfin"";
            string restUsername = ""admin@yellowfin.com.au"";
            string restPassword = ""test"";

            string userGroupToAddUserTo = ""New Group"";
            string usernameOfUserToAdd = ""user1@yellowfin.com.au"";

            string token = await GenerateToken(host, restUsername, restPassword);

            int userIpId = await RetrieveUserIpIdForUsername(host, token, usernameOfUserToAdd);
            int groupId = await RetrieveGroupIpIdForGroupName(host, token, userGroupToAddUserTo);

            string groupMembersPayload = ""[{\""entityType\"": \""PERSON\"",\""entityId\"": "" + userIpId + "",\""membershipType\"": \""INCLUDED\""}]"";

            Console.WriteLine(""UserIpId: "" + userIpId);
            Console.WriteLine(""GroupId: "" + groupId);
            Console.WriteLine(""Payload: "" + groupMembersPayload);

            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", ""ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "" , nonce="" + new Random().NextInt64() + "", token="" + token);
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));
                var content = new StringContent(groupMembersPayload);
                content.Headers.ContentType = new MediaTypeHeaderValue(""application/json"");

                var response = await httpClient.PostAsync(host + ""/api/user-groups/"" + groupId + ""/members"", content);
                if (response.IsSuccessStatusCode)
                {
                    Console.WriteLine(""User "" + usernameOfUserToAdd + "" added to group "" + userGroupToAddUserTo + "" successfully"");
                    string responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(""Response: "" + responseBody);
                }
                else
                {
                    Console.WriteLine(""Failed to add user to group. Status code: "" + response.StatusCode);
                }
            }
        }

        static async Task<int> RetrieveGroupIpIdForGroupName(string host, string token, string groupName)
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", ""ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "" , nonce="" + new Random().NextInt64() + "", token="" + token);
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                var response = await httpClient.GetAsync(host + ""/api/user-groups"");
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JObject.Parse(responseBody);
                    JArray groupList = (JArray)jsonObject[""items""];

                    foreach (var group in groupList)
                    {
                        if (groupName.Equals(group[""shortDescription""].ToString()))
                        {
                            return Convert.ToInt32(group[""userGroupId""]);
                        }
                    }

                    Console.WriteLine(""Group could not be found for name: "" + groupName);
                    Environment.Exit(-1);
                }
                else
                {
                    Console.WriteLine(""Failed to retrieve groups. Status code: "" + response.StatusCode);
                }
            }

            return -1;
        }

        static async Task<int> RetrieveUserIpIdForUsername(string host, string token, string userName)
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", ""ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "" , nonce="" + new Random().NextInt64() + "", token="" + token);
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                var response = await httpClient.GetAsync(host + ""/api/rpc/users/user-details-by-username/"" + userName);
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JObject.Parse(responseBody);
                    return Convert.ToInt32(jsonObject[""userId""]);
                }
                else
                {
                    Console.WriteLine(""Failed to retrieve user. Status code: "" + response.StatusCode);
                }
            }

            return -1;
        }

        static async Task<string> GenerateToken(string host, string username, string password)
        {
            using (var client = new HttpClient())
            {
                // Generate nonce
                long nonce = new Random().NextInt64();

                // Create HTTP request
                var request = new HttpRequestMessage(HttpMethod.Post, host + ""/api/refresh-tokens"");
                request.Headers.Add(""Authorization"", ""YELLOWFIN ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "", nonce="" + nonce);
                request.Headers.Add(""Accept"", ""application/vnd.yellowfin.api-v1+json"");
                request.Content = new StringContent(
                    JsonConvert.SerializeObject(new { userName = username, password = password }),
                    MediaTypeHeaderValue.Parse(""application/json"")
                );

                // Send request and get response
                HttpResponseMessage response = await client.SendAsync(request);
                string responseContent = await response.Content.ReadAsStringAsync();

                // Parse JSON response
                JObject jsonObject = JObject.Parse(responseContent);
                string accessToken = jsonObject[""_embedded""][""accessToken""][""securityToken""].ToString();

                if (!string.IsNullOrEmpty(accessToken))
                {
                    Console.WriteLine(""Access Token: "" + accessToken);
                }
                else
                {
                    Console.WriteLine(""Token not retrieved successfully"");
                    Environment.Exit(-1);
                }

                return accessToken;
            }
        }
    }
}
Go
package main

import (
	""bytes""
	""encoding/json""
	""fmt""
	""io/ioutil""
	""math/rand""
	""net/http""
	""time""
)

func main() {
	host := ""http://localhost:8080/Yellowfin""
	restUsername := ""admin@yellowfin.com.au""
	restPassword := ""test""
	userGroupToAddUserTo := ""New Group""
	usernameOfUserToAdd := ""user1@yellowfin.com.au""

	token, err := generateToken(host, restUsername, restPassword)
	if err != nil {
		fmt.Println(""Error generating token:"", err)
		return
	}

	userIpId, err := retrieveUserIpIdForUsername(host, token, usernameOfUserToAdd)
	if err != nil {
		fmt.Println(""Error retrieving user IP ID:"", err)
		return
	}

	groupId, err := retrieveGroupIpIdForGroupName(host, token, userGroupToAddUserTo)
	if err != nil {
		fmt.Println(""Error retrieving group IP ID:"", err)
		return
	}

	groupMembersPayload := fmt.Sprintf(`[
    {
    ""entityType"": ""PERSON"",
    ""entityId"": %d,
    ""membershipType"": ""INCLUDED""
    }
]`, userIpId)

	fmt.Println(""UserIpId:"", userIpId)
	fmt.Println(""GroupId:"", groupId)
	fmt.Println(""Payload:"", groupMembersPayload)

	client := &http.Client{}
	req, err := http.NewRequest(""POST"", fmt.Sprintf(""%s/api/user-groups/%d/members"", host, groupId), bytes.NewBufferString(groupMembersPayload))
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return
	}

	nonce := rand.Int63()
	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return
	}

	fmt.Printf(""User %s added to group %s successfully\n"", usernameOfUserToAdd, userGroupToAddUserTo)
	fmt.Println(""Response:"", string(body))
}

func retrieveGroupIpIdForGroupName(host, token, groupName string) (int, error) {
	client := &http.Client{}
	req, err := http.NewRequest(""GET"", host+""/api/user-groups"", nil)
	if err != nil {
		return 0, err
	}

	nonce := rand.Int63()
	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return 0, err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return 0, err
	}

	var data map[string]interface{}
	err = json.Unmarshal(body, &data)
	if err != nil {
		return 0, err
	}

	groups := data[""items""].([]interface{})
	for _, g := range groups {
		group := g.(map[string]interface{})
		if groupName == group[""shortDescription""].(string) {
			return int(group[""userGroupId""].(float64)), nil
		}
	}

	return 0, fmt.Errorf(""Group could not be found for name: %s"", groupName)
}

func retrieveUserIpIdForUsername(host, token, userName string) (int, error) {
	client := &http.Client{}
	req, err := http.NewRequest(""GET"", host+""/api/rpc/users/user-details-by-username/""+userName, nil)
	if err != nil {
		return 0, err
	}

	nonce := rand.Int63()
	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return 0, err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return 0, err
	}

	var data map[string]interface{}
	err = json.Unmarshal(body, &data)
	if err != nil {
		return 0, err
	}

	return int(data[""userId""].(float64)), nil
}

func generateToken(host, username, password string) (string, error) {
	nonce := rand.Int63()

	requestBody, err := json.Marshal(map[string]string{
		""userName"": username,
		""password"": password,
	})
	if err != nil {
		return """", err
	}

	client := &http.Client{}
	req, err := http.NewRequest(""POST"", host+""/api/refresh-tokens"", bytes.NewBuffer(requestBody))
	if err != nil {
		return """", err
	}

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d"", time.Now().UnixMilli(), nonce))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return """", err
	}
	defer resp.Body.Close()

	responseBody, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return """", err
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(responseBody, &jsonResponse)
	if err != nil {
		return """", err
	}

	accessToken := jsonResponse[""_embedded""].(map[string]interface{})[""accessToken""].(map[string]interface{})[""securityToken""].(string)

	return accessToken, nil
}
JavaScript
const fetch = require(""node-fetch"");

async function main() {
    const host = ""http://localhost:8080/Yellowfin"";
    const restUsername = ""admin@yellowfin.com.au"";
    const restPassword = ""test"";

    const userGroupToAddUserTo = ""New Group"";
    const usernameOfUserToAdd = ""user1@yellowfin.com.au"";

    const token = await generateToken(host, restUsername, restPassword);

    if (token === null) {
        console.error(""Failed to retrieve access token"");
        return;
    }

    const userIpId = await retrieveUserIpIdForUsername(host, token, usernameOfUserToAdd);
    const groupId = await retrieveGroupIpIdForGroupName(host, token, userGroupToAddUserTo);

    const groupMembersPayload = JSON.stringify([
        {
            entityType: ""PERSON"",
            entityId: userIpId,
            membershipType: ""INCLUDED""
        }
    ]);

    console.log(""UserIpId:"", userIpId);
    console.log(""GroupId:"", groupId);
    console.log(""Payload:"", groupMembersPayload);

    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/user-groups/${groupId}/members`, {
            method: 'POST',
            headers: headers,
            body: groupMembersPayload
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const responseBody = await response.text();
        console.log(`User ${usernameOfUserToAdd} added to group ${userGroupToAddUserTo} successfully`);
        console.log(""Response:"", responseBody);
    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

async function retrieveGroupIpIdForGroupName(host, token, groupName) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/user-groups`, {
            method: 'GET',
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const groups = jsonResponse.items;

        for (const group of groups) {
            if (group.shortDescription === groupName) {
                return group.userGroupId;
            }
        }

        console.log(`Group could not be found for name: ${groupName}`);
        process.exit(-1);
    } catch (error) {
        console.error(""Error:"", error.message);
    }

    return null;
}

async function retrieveUserIpIdForUsername(host, token, userName) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/rpc/users/user-details-by-username/${userName}`, {
            method: 'GET',
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        return jsonResponse.userId;
    } catch (error) {
        console.error(""Error:"", error.message);
    }

    return null;
}

async function generateToken(host, username, password) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);

    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    const body = JSON.stringify({
        userName: username,
        password: password
    });

    try {
        const response = await fetch(`${host}/api/refresh-tokens`, {
            method: 'POST',
            headers: headers,
            body: body
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const accessToken = jsonResponse._embedded.accessToken.securityToken;

        if (accessToken) {
            console.log(`Access Token: ${accessToken}`);
        } else {
            console.log(""Token not retrieved"");
        }

        return accessToken;
    } catch (error) {
        console.error(""Error:"", error.message);
    }

    return null;
}

main();
PHP
<?php
function main() {
    $host = ""http://localhost:8080/Yellowfin"";
    $restUsername = ""admin@yellowfin.com.au"";
    $restPassword = ""test"";

    $userGroupToAddUserTo = ""New Group"";
    $usernameOfUserToAdd = ""user1@yellowfin.com.au"";

    try {
        $token = generateToken($host, $restUsername, $restPassword);
    } catch (Exception $e) {
        echo ""Error generating token: "" . $e->getMessage();
        return;
    }

    try {
        $userIpId = retrieveUserIpIdForUsername($host, $token, $usernameOfUserToAdd);
        $groupId = retrieveGroupIpIdForGroupName($host, $token, $userGroupToAddUserTo);
    } catch (Exception $e) {
        echo ""Error: "" . $e->getMessage();
        return;
    }

    $groupMembersPayload = '[{""entityType"": ""PERSON"",""entityId"": ' . $userIpId . ',""membershipType"": ""INCLUDED""}]';

    echo ""UserIpId: "" . $userIpId . ""\n"";
    echo ""GroupId: "" . $groupId . ""\n"";
    echo ""Payload: "" . $groupMembersPayload . ""\n"";

    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    try {
        $response = httpRequest('POST', $host . ""/api/user-groups/"" . $groupId . ""/members"", $headers, $groupMembersPayload);
        echo $response;
    } catch (Exception $e) {
        echo ""Error sending request: "" . $e->getMessage();
    }
}

function generateToken($host, $restUsername, $restPassword) {
    // Generate nonce
    $nonce = mt_rand();

    // Create request body
    $requestBody = json_encode(array(
        ""userName"" => $restUsername,
        ""password"" => $restPassword
    ));

    // Create request headers
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('POST', $host . ""/api/refresh-tokens"", $headers, $requestBody);

    // Parse JSON response
    $jsonResponse = json_decode($response, true);

    // Get access token from response
    if (isset($jsonResponse[""_embedded""][""accessToken""][""securityToken""])) {
        $accessToken = $jsonResponse[""_embedded""][""accessToken""][""securityToken""];
        echo ""Access Token: "" . $accessToken;

        return $accessToken;
    } else {
        throw new Exception(""Token not retrieved successfully"");
    }
}

function retrieveGroupIpIdForGroupName($host, $token, $groupName) {
    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('GET', $host . ""/api/user-groups"", $headers);

    // Parse JSON response
    $jsonResponse = json_decode($response, true);

    $groups = $jsonResponse[""items""];

    foreach ($groups as $group) {
        if ($group[""shortDescription""] === $groupName) {
            return $group[""userGroupId""];
        }
    }

    echo ""Group could not be found for name:"" . $groupName;
    exit(-1);
}

function retrieveUserIpIdForUsername($host, $token, $userName) {
    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('GET', $host . ""/api/rpc/users/user-details-by-username/"" . $userName, $headers);

    // Parse JSON response
    $jsonResponse = json_decode($response, true);

    return $jsonResponse[""userId""];
}

function httpRequest($method, $url, $headers, $data = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception('Error: ' . curl_error($ch));
    }

    curl_close($ch);

    return $response;
}

main();
?>
Python
import json
import random
import time
import requests

def main():
    host = ""http://localhost:8080/Yellowfin""
    rest_username = ""admin@yellowfin.com.au""
    rest_password = ""test""

    user_group_to_add_user_to = ""New Group""
    username_of_user_to_add = ""user1@yellowfin.com.au""

    try:
        token = generate_token(host, rest_username, rest_password)
    except Exception as e:
        print(f""Error generating token: {e}"")
        return

    try:
        user_ip_id = retrieve_user_ip_id_for_username(host, token, username_of_user_to_add)
        group_id = retrieve_group_ip_id_for_group_name(host, token, user_group_to_add_user_to)
    except Exception as e:
        print(f""Error: {e}"")
        return

    group_members_payload = f""[{{\""entityType\"": \""PERSON\"", \""entityId\"": {user_ip_id}, \""membershipType\"": \""INCLUDED\""}}]""

    print(f""UserIpId: {user_ip_id}"")
    print(f""GroupId: {group_id}"")
    print(f""Payload: {group_members_payload}"")

    nonce = random.randint(0, 2**63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    try:
        response = requests.post(f""{host}/api/user-groups/{group_id}/members"", headers=headers, data=group_members_payload)
        response.raise_for_status()
        print(response.text)
    except requests.RequestException as e:
        print(f""Error sending request: {e}"")

def generate_token(host, rest_username, rest_password):
    nonce = random.randint(0, 2**63 - 1)
    request_body = json.dumps({
        ""userName"": rest_username,
        ""password"": rest_password
    })
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }
    response = requests.post(f""{host}/api/refresh-tokens"", headers=headers, data=request_body)

    if response.status_code == 200:
        json_response = response.json()
        access_token = json_response[""_embedded""][""accessToken""][""securityToken""]
        print(""Access Token:"", access_token)
        return access_token
    else:
        raise Exception(""Token not retrieved successfully"")

def retrieve_group_ip_id_for_group_name(host, token, group_name):
    nonce = random.randint(0, 2**63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }
    response = requests.get(f""{host}/api/user-groups"", headers=headers)

    if response.status_code == 200:
        json_response = response.json()
        groups = json_response[""items""]
        for group in groups:
            if group[""shortDescription""] == group_name:
                return group[""userGroupId""]
        print(f""Group could not be found for name: {group_name}"")
        exit(-1)
    else:
        raise Exception(""Error retrieving group"")

def retrieve_user_ip_id_for_username(host, token, username):
    nonce = random.randint(0, 2**63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }
    response = requests.get(f""{host}/api/rpc/users/user-details-by-username/{username}"", headers=headers)

    if response.status_code == 200:
        json_response = response.json()
        return json_response[""userId""]
    else:
        raise Exception(""Error retrieving user ID"")

if __name__ == ""__main__"":
    main()

Remove Members from a Group

Members can be removed from a user group using DELETE /api/user-groups/{groupId}/members end-point Bulk-Delete User Group Members.

Members are removed by supplying a query parameter that contains a list of memberIds to be removed. This is of the form: 

memberIds=['ROLE|YFADMIN','PERSON|13235']

The following examples illustrate removing a user (identified by username), from a group (identified by its name). 

Java
package rest.code.examples;
import java.io.IOException;
import java.util.Random;
import org.apache.hc.client5.http.fluent.Content;
import org.apache.hc.client5.http.fluent.Request;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
 * Remove users from a User Group using the Yellowfin REST API
 */
public class RemoveMemberFromGroup {
    public static void main(String[] args) throws Exception {

        System.out.println(""Remove User from Group"");

        String host = ""http://localhost:8080/Yellowfin"";
        String restUsername = ""admin@yellowfin.com.au"";
        String restPassword = ""test"";

        String userGroupToAddRemoveUserFrom = ""New Group"";
        String usernameOfUserToRemove = ""user1@yellowfin.com.au"";

        String token = generateToken(host, restUsername, restPassword);

        Integer userIpId = retrieveUserIpIdForUsername(host, token, usernameOfUserToRemove);

        Integer groupId = retrieveGroupIpIdForGroupName(host, token, userGroupToAddRemoveUserFrom);

        // The pipe ""|"" symbol is URL escaped in the following line.
        String groupMembersPayload = ""memberIds=%5B'PERSON%7C""+  userIpId + ""'%5D"";

        System.out.println(""UserIpId: "" + userIpId);
        System.out.println(""GroupId: "" + groupId);
        System.out.println(""Payload: "" + groupMembersPayload);

        Content c = Request.delete(host + ""/api/user-groups/"" + groupId + ""/members/?"" + groupMembersPayload)
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();

        System.out.println(""User "" + usernameOfUserToRemove +  "" removed from group "" + userGroupToAddRemoveUserFrom + "" successfully"");
        System.out.println(""Response: "" + c.asString());

    }

    public static Integer retrieveGroupIpIdForGroupName(String host, String token, String groupName) throws IOException {

        Content c = Request.get(host + ""/api/user-groups"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement groupList = jsonObject.get(""items"");
        JsonArray groups = groupList.getAsJsonArray();

        for (int i=0; i < groups.size(); i++ ) {
            JsonObject group = groups.getAsJsonArray().get(i).getAsJsonObject();
            if (groupName.equals(group.get(""shortDescription"").getAsString())) return group.get(""userGroupId"").getAsInt();
        }

        System.out.println(""Group could not be found for name:"" + groupName);
        System.exit(-1);

        return null;
    }

    public static Integer retrieveUserIpIdForUsername(String host, String token, String userName) throws IOException {

        Content c = Request.get(host + ""/api/rpc/users/user-details-by-username/"" + userName)
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong()+ "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement userIpJsonAttribute = jsonObject.get(""userId"");
        Integer userIpId = userIpJsonAttribute.getAsInt();

        return userIpId;

    }


    /*
     *  This function generates an access token for a user that will grant them access to
     *  call REST API endpoints.
     */

    public static String generateToken(String host, String username, String password) throws IOException {

        Content c = Request.post(host + ""/api/refresh-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong())
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""}"", null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement accessToken = jsonObject.getAsJsonObject(""_embedded"").getAsJsonObject(""accessToken"").get(""securityToken"");

        if (accessToken!=null) {
            System.out.println(""Access Token: "" + accessToken);
        } else {
            System.out.println(""Token not retrieved successfully"");
            System.exit(-1);
        }
        return accessToken.getAsString();

    }

}
C#
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace YellowfinAPIExamples
{
    public class RemoveMemberFromGroup
    {
        public static async Task Main(string[] args)
        {
            Console.WriteLine(""Remove User from Group"");

            string host = ""http://localhost:8080/Yellowfin"";
            string restUsername = ""admin@yellowfin.com.au"";
            string restPassword = ""test"";

            string userGroupToAddRemoveUserFrom = ""New Group"";
            string usernameOfUserToRemove = ""user1@yellowfin.com.au"";

            string token = await GenerateToken(host, restUsername, restPassword);

            int userIpId = await RetrieveUserIpIdForUsername(host, token, usernameOfUserToRemove);

            int groupId = await RetrieveGroupIpIdForGroupName(host, token, userGroupToAddRemoveUserFrom);

            string groupMembersPayload = $""memberIds=%5B'PERSON%7C{userIpId}'%5D"";

            Console.WriteLine(""UserIpId: "" + userIpId);
            Console.WriteLine(""GroupId: "" + groupId);
            Console.WriteLine(""Payload: "" + groupMembersPayload);

            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", 
                    $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={new Random().NextInt64()}, token={token}"");
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                HttpResponseMessage response = await httpClient.DeleteAsync($""{host}/api/user-groups/{groupId}/members/?{groupMembersPayload}"");
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine($""User {usernameOfUserToRemove} removed from group {userGroupToAddRemoveUserFrom} successfully"");
                    Console.WriteLine(""Response: "" + responseBody);
                }
                else
                {
                    Console.WriteLine(""Failed to remove user from group. Status code: "" + response.StatusCode);
                }
            }
        }

        public static async Task<int> RetrieveGroupIpIdForGroupName(string host, string token, string groupName)
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", 
                    $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={new Random().NextInt64()}, token={token}"");
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                HttpResponseMessage response = await httpClient.GetAsync($""{host}/api/user-groups"");
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                    JArray groups = (JArray)jsonObject[""items""];

                    foreach (var group in groups)
                    {
                        if (group[""shortDescription""].ToString() == groupName)
                        {
                            return group[""userGroupId""].Value<int>();
                        }
                    }

                    Console.WriteLine(""Group could not be found for name:"" + groupName);
                    Environment.Exit(-1);
                }
                else
                {
                    Console.WriteLine(""Failed to retrieve group list. Status code: "" + response.StatusCode);
                    Environment.Exit(-1);
                }

                return -1;
            }
        }

        public static async Task<int> RetrieveUserIpIdForUsername(string host, string token, string userName)
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", 
                    $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={new Random().NextInt64()}, token={token}"");
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                HttpResponseMessage response = await httpClient.GetAsync($""{host}/api/rpc/users/user-details-by-username/{userName}"");
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                    int userIpId = jsonObject[""userId""].Value<int>();

                    return userIpId;
                }
                else
                {
                    Console.WriteLine(""Failed to retrieve user IP ID. Status code: "" + response.StatusCode);
                    Environment.Exit(-1);
                }

                return -1;
            }
        }

        public static async Task<string> GenerateToken(string host, string username, string password)
        {
            using (var client = new HttpClient())
            {
                var request = new HttpRequestMessage(HttpMethod.Post, $""{host}/api/refresh-tokens"");
                request.Headers.Add(""Authorization"", $""YELLOWFIN ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={new Random().NextInt64()}"");
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));
                request.Content = new StringContent(
                    JsonConvert.SerializeObject(new { userName = username, password = password }),
                    System.Text.Encoding.UTF8,
                    ""application/json""
                );

                HttpResponseMessage response = await client.SendAsync(request);
                string responseContent = await response.Content.ReadAsStringAsync();

                JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseContent);
                string accessToken = jsonObject[""_embedded""][""accessToken""][""securityToken""].ToString();

                if (!string.IsNullOrEmpty(accessToken))
                {
                    Console.WriteLine(""Access Token: "" + accessToken);
                }
                else
                {
                    Console.WriteLine(""Token not retrieved successfully"");
                    Environment.Exit(-1);
                }

                return accessToken;
            }
        }
    }
}
Go
package main

import (
	""bytes""
	""encoding/json""
	""fmt""
	""io/ioutil""
	""math/rand""
	""net/http""
	""time""
)

func main() {
	fmt.Println(""Remove User from Group"")

	host := ""http://localhost:8080/Yellowfin""
	restUsername := ""admin@yellowfin.com.au""
	restPassword := ""test""

	userGroupToAddRemoveUserFrom := ""New Group""
	usernameOfUserToRemove := ""user1@yellowfin.com.au""

	token, err := generateToken(host, restUsername, restPassword)
	if err != nil {
		fmt.Println(""Error generating token:"", err)
		return
	}

	userIpId, err := retrieveUserIpIdForUsername(host, token, usernameOfUserToRemove)
	if err != nil {
		fmt.Println(""Error retrieving user IP ID:"", err)
		return
	}

	groupId, err := retrieveGroupIpIdForGroupName(host, token, userGroupToAddRemoveUserFrom)
	if err != nil {
		fmt.Println(""Error retrieving group ID:"", err)
		return
	}

	groupMembersPayload := fmt.Sprintf(""memberIds=%%5B'PERSON%%7C%d'%%5D"", userIpId)

	fmt.Println(""UserIpId:"", userIpId)
	fmt.Println(""GroupId:"", groupId)
	fmt.Println(""Payload:"", groupMembersPayload)

	client := &http.Client{}
	req, err := http.NewRequest(""DELETE"", host+""/api/user-groups/""+fmt.Sprint(groupId)+""/members/?""+groupMembersPayload, nil)
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return
	}

	nonce := rand.Int63()

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return
	}

	fmt.Printf(""User %s removed from group %s successfully\n"", usernameOfUserToRemove, userGroupToAddRemoveUserFrom)
	fmt.Println(""Response:"", string(body))
}

func retrieveGroupIpIdForGroupName(host, token, groupName string) (int, error) {
	client := &http.Client{}
	req, err := http.NewRequest(""GET"", host+""/api/user-groups"", nil)
	if err != nil {
		return 0, err
	}

	nonce := rand.Int63()

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return 0, err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return 0, err
	}

	var jsonObject map[string]interface{}
	err = json.Unmarshal(body, &jsonObject)
	if err != nil {
		return 0, err
	}

	groups := jsonObject[""items""].([]interface{})

	for _, group := range groups {
		groupMap := group.(map[string]interface{})
		if groupMap[""shortDescription""] == groupName {
			return int(groupMap[""userGroupId""].(float64)), nil
		}
	}

	fmt.Println(""Group could not be found for name:"", groupName)
	return 0, fmt.Errorf(""group not found"")
}

func retrieveUserIpIdForUsername(host, token, userName string) (int, error) {
	client := &http.Client{}
	req, err := http.NewRequest(""GET"", host+""/api/rpc/users/user-details-by-username/""+userName, nil)
	if err != nil {
		return 0, err
	}

	nonce := rand.Int63()

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return 0, err
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return 0, err
	}

	var jsonObject map[string]interface{}
	err = json.Unmarshal(body, &jsonObject)
	if err != nil {
		return 0, err
	}

	return int(jsonObject[""userId""].(float64)), nil
}

func generateToken(host, restUsername, restPassword string) (string, error) {
	nonce := rand.Int63()

	requestBody, err := json.Marshal(map[string]string{
		""userName"": restUsername,
		""password"": restPassword,
	})
	if err != nil {
		return """", err
	}

	client := &http.Client{}
	request, err := http.NewRequest(""POST"", host+""/api/refresh-tokens"", bytes.NewBuffer(requestBody))
	if err != nil {
		return """", err
	}

	request.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d"", time.Now().UnixMilli(), nonce))
	request.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	request.Header.Set(""Content-Type"", ""application/json"")

	response, err := client.Do(request)
	if err != nil {
		return """", err
	}
	defer response.Body.Close()

	responseBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return """", err
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(responseBody, &jsonResponse)
	if err != nil {
		return """", err
	}

	accessToken, ok := jsonResponse[""_embedded""].(map[string]interface{})[""accessToken""].(map[string]interface{})[""securityToken""].(string)
	if !ok {
		return """", fmt.Errorf(""Token not retrieved successfully"")
	}

	return accessToken, nil
}
JavaScript
const fetch = require(""node-fetch"");

async function main() {
    console.log(""Remove User from Group"");

    const host = ""http://localhost:8080/Yellowfin"";
    const restUsername = ""admin@yellowfin.com.au"";
    const restPassword = ""test"";

    const userGroupToAddRemoveUserFrom = ""New Group"";
    const usernameOfUserToRemove = ""user1@yellowfin.com.au"";

    const token = await generateToken(host, restUsername, restPassword);
    if (!token) {
        console.error(""Failed to retrieve access token"");
        return;
    }

    const userIpId = await retrieveUserIpIdForUsername(host, token, usernameOfUserToRemove);
    if (userIpId === null) {
        console.error(""Failed to retrieve user IP ID"");
        return;
    }

    const groupId = await retrieveGroupIpIdForGroupName(host, token, userGroupToAddRemoveUserFrom);
    if (groupId === null) {
        console.error(""Failed to retrieve group ID"");
        return;
    }

    const groupMembersPayload = `memberIds=%5B'PERSON%7C${userIpId}'%5D`;

    console.log(""UserIpId:"", userIpId);
    console.log(""GroupId:"", groupId);
    console.log(""Payload:"", groupMembersPayload);

    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/user-groups/${groupId}/members/?${groupMembersPayload}`, {
            method: 'DELETE',
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const responseBody = await response.text();
        console.log(`User ${usernameOfUserToRemove} removed from group ${userGroupToAddRemoveUserFrom} successfully`);
        console.log(""Response:"", responseBody);
    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

async function retrieveGroupIpIdForGroupName(host, token, groupName) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/user-groups`, {
            method: 'GET',
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonObject = await response.json();
        const groups = jsonObject.items;

        for (let group of groups) {
            if (group.shortDescription === groupName) {
                return group.userGroupId;
            }
        }

        console.error(""Group could not be found for name:"", groupName);
        return null;
    } catch (error) {
        console.error(""Error:"", error.message);
        return null;
    }
}

async function retrieveUserIpIdForUsername(host, token, userName) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/rpc/users/user-details-by-username/${userName}`, {
            method: 'GET',
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonObject = await response.json();
        return jsonObject.userId;
    } catch (error) {
        console.error(""Error:"", error.message);
        return null;
    }
}

async function generateToken(host, restUsername, restPassword) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    const body = JSON.stringify({
        userName: restUsername,
        password: restPassword
    });

    try {
        const response = await fetch(`${host}/api/refresh-tokens`, {
            method: 'POST',
            headers: headers,
            body: body
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const accessToken = jsonResponse._embedded.accessToken.securityToken;

        if (accessToken) {
            console.log(`Access Token: ${accessToken}`);
            return accessToken;
        } else {
            console.log(""Token not retrieved"");
            return null;
        }
    } catch (error) {
        console.error(""Error:"", error.message);
        return null;
    }
}

main();
PHP
<?php

function main() {
    echo ""Remove User from Group\n"";

    $host = ""http://localhost:8080/Yellowfin"";
    $restUsername = ""admin@yellowfin.com.au"";
    $restPassword = ""test"";

    $userGroupToAddRemoveUserFrom = ""New Group"";
    $usernameOfUserToRemove = ""user1@yellowfin.com.au"";

    try {
        $token = generateToken($host, $restUsername, $restPassword);
    } catch (Exception $e) {
        echo ""Error generating token: "" . $e->getMessage();
        return;
    }

    try {
        $userIpId = retrieveUserIpIdForUsername($host, $token, $usernameOfUserToRemove);
        $groupId = retrieveGroupIpIdForGroupName($host, $token, $userGroupToAddRemoveUserFrom);
    } catch (Exception $e) {
        echo ""Error retrieving IDs: "" . $e->getMessage();
        return;
    }

    // The pipe ""|"" symbol is URL escaped in the following line.
    $groupMembersPayload = ""memberIds=%5B'PERSON%7C"" . $userIpId . ""'%5D"";

    echo ""UserIpId: "" . $userIpId . ""\n"";
    echo ""GroupId: "" . $groupId . ""\n"";
    echo ""Payload: "" . $groupMembersPayload . ""\n"";

    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    try {
        $response = httpRequest('DELETE', ""$host/api/user-groups/$groupId/members/?$groupMembersPayload"", $headers);
        echo ""User $usernameOfUserToRemove removed from group $userGroupToAddRemoveUserFrom successfully\n"";
        echo ""Response: "" . $response;
    } catch (Exception $e) {
        echo ""Error sending request: "" . $e->getMessage();
    }
}

function retrieveGroupIpIdForGroupName($host, $token, $groupName) {
    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('GET', ""$host/api/user-groups"", $headers);

    $jsonObject = json_decode($response, true);
    $groups = $jsonObject['items'];

    foreach ($groups as $group) {
        if ($group['shortDescription'] === $groupName) {
            return $group['userGroupId'];
        }
    }

    echo ""Group could not be found for name: "" . $groupName . ""\n"";
    exit(-1);
}

function retrieveUserIpIdForUsername($host, $token, $userName) {
    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('GET', ""$host/api/rpc/users/user-details-by-username/$userName"", $headers);

    $jsonObject = json_decode($response, true);
    return $jsonObject['userId'];
}

function generateToken($host, $restUsername, $restPassword) {
    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $requestBody = json_encode(array(
        ""userName"" => $restUsername,
        ""password"" => $restPassword
    ));

    $response = httpRequest('POST', ""$host/api/refresh-tokens"", $headers, $requestBody);

    $jsonResponse = json_decode($response, true);
    if (isset($jsonResponse[""_embedded""][""accessToken""][""securityToken""])) {
        $accessToken = $jsonResponse[""_embedded""][""accessToken""][""securityToken""];
        echo ""Access Token: "" . $accessToken . ""\n"";
        return $accessToken;
    } else {
        throw new Exception(""Token not retrieved successfully"");
    }
}

function httpRequest($method, $url, $headers, $data = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception('Error: ' . curl_error($ch));
    }

    curl_close($ch);

    return $response;
}

main();
?>
Python
import json
import random
import time
import requests

def main():
    print(""Remove User from Group"")

    host = ""http://localhost:8080/Yellowfin""
    rest_username = ""admin@yellowfin.com.au""
    rest_password = ""test""

    user_group_to_add_remove_user_from = ""New Group""
    username_of_user_to_remove = ""user1@yellowfin.com.au""

    try:
        token = generate_token(host, rest_username, rest_password)
    except Exception as e:
        print(f""Error generating token: {e}"")
        return

    try:
        user_ip_id = retrieve_user_ip_id_for_username(host, token, username_of_user_to_remove)
        group_id = retrieve_group_ip_id_for_group_name(host, token, user_group_to_add_remove_user_from)
    except Exception as e:
        print(f""Error retrieving IDs: {e}"")
        return

    # The pipe ""|"" symbol is URL escaped in the following line.
    group_members_payload = f""memberIds=%5B'PERSON%7C{user_ip_id}'%5D""

    print(""UserIpId:"", user_ip_id)
    print(""GroupId:"", group_id)
    print(""Payload:"", group_members_payload)

    nonce = random.randint(0, 2**63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    try:
        response = requests.delete(f""{host}/api/user-groups/{group_id}/members/?{group_members_payload}"", headers=headers)
        response.raise_for_status()
        print(f""User {username_of_user_to_remove} removed from group {user_group_to_add_remove_user_from} successfully"")
        print(""Response:"", response.text)
    except requests.RequestException as e:
        print(f""Error sending request: {e}"")

def retrieve_group_ip_id_for_group_name(host, token, group_name):
    nonce = random.randint(0, 2**63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    response = requests.get(f""{host}/api/user-groups"", headers=headers)
    response.raise_for_status()

    json_object = response.json()
    groups = json_object['items']

    for group in groups:
        if group['shortDescription'] == group_name:
            return group['userGroupId']

    print(f""Group could not be found for name: {group_name}"")
    exit(-1)

def retrieve_user_ip_id_for_username(host, token, user_name):
    nonce = random.randint(0, 2**63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    response = requests.get(f""{host}/api/rpc/users/user-details-by-username/{user_name}"", headers=headers)
    response.raise_for_status()

    json_object = response.json()
    return json_object['userId']

def generate_token(host, rest_username, rest_password):
    nonce = random.randint(0, 2**63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    request_body = json.dumps({
        ""userName"": rest_username,
        ""password"": rest_password
    })

    response = requests.post(f""{host}/api/refresh-tokens"", headers=headers, data=request_body)
    response.raise_for_status()

    json_response = response.json()
    access_token = json_response[""_embedded""][""accessToken""][""securityToken""]
    print(""Access Token:"", access_token)

    return access_token

if __name__ == ""__main__"":
    main()

List Group Member Components

Members of existing groups can be returned using the GET /api/user-groups/{groupId}/members end-point Get User Group Member List. This service will return the components of a group. For example, this will return a Group or Role as a member, and not the users that those components represent. There is a separate end-point for getting the final flattened member list, where the individual users within a group or role are retrieved.

The following examples return the JSON payload representing a list of group member components in various programming languages.

Java
package rest.code.examples;
import java.io.IOException;
import java.util.Random;
import org.apache.hc.client5.http.fluent.Content;
import org.apache.hc.client5.http.fluent.Request;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
 * Create a user using the Yellowfin REST API
 */
public class ListGroupMembers {
    public static void main(String[] args) throws Exception {

        System.out.println(""List Group Member Components"");

        String host = ""http://localhost:8080/Yellowfin"";
        String restUsername = ""admin@yellowfin.com.au"";
        String restPassword = ""test"";

        String groupName = ""New Group"";

        String token = generateToken(host, restUsername, restPassword);

        Integer groupId = retrieveGroupIpIdForGroupName(host, token, groupName);

        Content c = Request.get(host + ""/api/user-groups/"" + groupId + ""/members"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();

        System.out.println(c.toString());

    }


    public static Integer retrieveGroupIpIdForGroupName(String host, String token, String groupName) throws IOException {

        Content c = Request.get(host + ""/api/user-groups"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement groupList = jsonObject.get(""items"");
        JsonArray groups = groupList.getAsJsonArray();

        for (int i=0; i < groups.size(); i++ ) {
            JsonObject group = groups.getAsJsonArray().get(i).getAsJsonObject();
            if (groupName.equals(group.get(""shortDescription"").getAsString())) return group.get(""userGroupId"").getAsInt();
        }

        System.out.println(""Group could not be found for name:"" + groupName);
        System.exit(-1);

        return null;
    }

    /*
     *  This function generates an access token for a user that will grant them access to
     *  call REST API endpoints.
     */

    public static String generateToken(String host, String username, String password) throws IOException {

        Content c = Request.post(host + ""/api/refresh-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong())
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""}"", null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement accessToken = jsonObject.getAsJsonObject(""_embedded"").getAsJsonObject(""accessToken"").get(""securityToken"");

        if (accessToken!=null) {
            System.out.println(""Access Token: "" + accessToken);
        } else {
            System.out.println(""Token not retrieved successfully"");
            System.exit(-1);
        }
        return accessToken.getAsString();

    }

}
C#
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace YellowfinAPIExamples
{
    public class ListGroupMembers
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine(""List Group Member Components"");

            string host = ""http://localhost:8080/Yellowfin"";
            string restUsername = ""admin@yellowfin.com.au"";
            string restPassword = ""test"";
            string groupName = ""New Group"";

            string token = await GenerateToken(host, restUsername, restPassword);

            int groupId = await RetrieveGroupIpIdForGroupName(host, token, groupName);

            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", ""ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "", nonce="" + new Random().NextInt64() + "", token="" + token);
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                HttpResponseMessage response = await httpClient.GetAsync(host + ""/api/user-groups/"" + groupId + ""/members"");
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(responseBody);
                }
                else
                {
                    Console.WriteLine(""Failed to retrieve group members. Status code: "" + response.StatusCode);
                }
            }
        }

        static async Task<int> RetrieveGroupIpIdForGroupName(string host, string token, string groupName)
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", ""ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "", nonce="" + new Random().NextInt64() + "", token="" + token);
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                HttpResponseMessage response = await httpClient.GetAsync(host + ""/api/user-groups"");
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                    JArray groups = (JArray)jsonObject[""items""];

                    foreach (var group in groups)
                    {
                        if (groupName == group[""shortDescription""].ToString())
                        {
                            return (int)group[""userGroupId""];
                        }
                    }

                    Console.WriteLine(""Group could not be found for name:"" + groupName);
                    Environment.Exit(-1);
                }
                else
                {
                    Console.WriteLine(""Failed to retrieve group list. Status code: "" + response.StatusCode);
                    Environment.Exit(-1);
                }
            }

            return -1; // Should not reach here due to Environment.Exit
        }

        static async Task<string> GenerateToken(string host, string restUsername, string restPassword)
        {
            using (var client = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                var request = new HttpRequestMessage(HttpMethod.Post, host + ""/api/refresh-tokens"");
                request.Headers.Add(""Authorization"", ""YELLOWFIN ts="" + DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() + "", nonce="" + nonce);
                request.Headers.Add(""Accept"", ""application/vnd.yellowfin.api-v1+json"");
                request.Content = new StringContent(
                    JsonConvert.SerializeObject(new { userName = restUsername, password = restPassword }),
                    System.Text.Encoding.UTF8,
                    ""application/json""
                );

                HttpResponseMessage response = await client.SendAsync(request);
                string responseContent = await response.Content.ReadAsStringAsync();

                JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseContent);
                string accessToken = jsonObject[""_embedded""][""accessToken""][""securityToken""].ToString();

                if (!string.IsNullOrEmpty(accessToken))
                {
                    Console.WriteLine(""Access Token: "" + accessToken);
                    return accessToken;
                }
                else
                {
                    Console.WriteLine(""Token not retrieved successfully"");
                    Environment.Exit(-1);
                }
            }

            return null; // Should not reach here due to Environment.Exit
        }
    }
}
Go
package main

import (
	""bytes""
	""encoding/json""
	""fmt""
	""io/ioutil""
	""math/rand""
	""net/http""
	""time""
)

func main() {
	fmt.Println(""List Group Member Components"")

	host := ""http://localhost:8080/Yellowfin""
	restUsername := ""admin@yellowfin.com.au""
	restPassword := ""test""
	groupName := ""New Group""

	token, err := generateToken(host, restUsername, restPassword)
	if err != nil {
		fmt.Println(""Error generating token:"", err)
		return
	}

	groupId, err := retrieveGroupIpIdForGroupName(host, token, groupName)
	if err != nil {
		fmt.Println(""Error retrieving group ID:"", err)
		return
	}

	err = listGroupMembers(host, token, groupId)
	if err != nil {
		fmt.Println(""Error listing group members:"", err)
	}
}

func retrieveGroupIpIdForGroupName(host, token, groupName string) (int, error) {
	client := &http.Client{}
	nonce := rand.Int63()
	req, err := http.NewRequest(""GET"", fmt.Sprintf(""%s/api/user-groups"", host), nil)
	if err != nil {
		return 0, fmt.Errorf(""error creating request: %v"", err)
	}

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return 0, fmt.Errorf(""error sending request: %v"", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return 0, fmt.Errorf(""error reading response body: %v"", err)
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(body, &jsonResponse)
	if err != nil {
		return 0, fmt.Errorf(""error parsing JSON response: %v"", err)
	}

	items, ok := jsonResponse[""items""].([]interface{})
	if !ok {
		return 0, fmt.Errorf(""error parsing group list from response"")
	}

	for _, item := range items {
		group := item.(map[string]interface{})
		if group[""shortDescription""] == groupName {
			groupId, ok := group[""userGroupId""].(float64)
			if !ok {
				return 0, fmt.Errorf(""error parsing group ID from response"")
			}
			return int(groupId), nil
		}
	}

	fmt.Println(""Group could not be found for name:"", groupName)
	return 0, fmt.Errorf(""group not found"")
}

func listGroupMembers(host, token string, groupId int) error {
	client := &http.Client{}
	nonce := rand.Int63()
	req, err := http.NewRequest(""GET"", fmt.Sprintf(""%s/api/user-groups/%d/members"", host, groupId), nil)
	if err != nil {
		return fmt.Errorf(""error creating request: %v"", err)
	}

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return fmt.Errorf(""error sending request: %v"", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return fmt.Errorf(""error reading response body: %v"", err)
	}

	fmt.Println(string(body))
	return nil
}

func generateToken(host, restUsername, restPassword string) (string, error) {
	nonce := rand.Int63()
	requestBody, err := json.Marshal(map[string]string{
		""userName"": restUsername,
		""password"": restPassword,
	})
	if err != nil {
		return """", fmt.Errorf(""error marshaling request body: %v"", err)
	}

	client := &http.Client{}
	req, err := http.NewRequest(""POST"", fmt.Sprintf(""%s/api/refresh-tokens"", host), bytes.NewBuffer(requestBody))
	if err != nil {
		return """", fmt.Errorf(""error creating request: %v"", err)
	}

	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d"", time.Now().UnixMilli(), nonce))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return """", fmt.Errorf(""error sending request: %v"", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return """", fmt.Errorf(""error reading response body: %v"", err)
	}

	var jsonResponse map[string]interface{}
	err = json.Unmarshal(body, &jsonResponse)
	if err != nil {
		return """", fmt.Errorf(""error parsing JSON response: %v"", err)
	}

	accessToken, ok := jsonResponse[""_embedded""].(map[string]interface{})[""accessToken""].(map[string]interface{})[""securityToken""].(string)
	if !ok {
		return """", fmt.Errorf(""token not retrieved successfully"")
	}

	fmt.Println(""Access Token:"", accessToken)
	return accessToken, nil
}
JavaScript
const fetch = require(""node-fetch"");

async function main() {
    console.log(""List Group Member Components"");

    const host = ""http://localhost:8080/Yellowfin"";
    const restUsername = ""admin@yellowfin.com.au"";
    const restPassword = ""test"";
    const groupName = ""New Group"";

    const token = await generateToken(host, restUsername, restPassword);
    if (token === null) {
        console.error(""Failed to retrieve access token"");
        return;
    }

    try {
        const groupId = await retrieveGroupIpIdForGroupName(host, token, groupName);
        await listGroupMembers(host, token, groupId);
    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

async function retrieveGroupIpIdForGroupName(host, token, groupName) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/user-groups`, { method: 'GET', headers: headers });
        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const groups = jsonResponse.items;

        for (let group of groups) {
            if (group.shortDescription === groupName) {
                return group.userGroupId;
            }
        }

        console.log(`Group could not be found for name: ${groupName}`);
        process.exit(-1);
    } catch (error) {
        console.error(""Error:"", error.message);
        throw error;
    }
}

async function listGroupMembers(host, token, groupId) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/user-groups/${groupId}/members`, { method: 'GET', headers: headers });
        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const responseBody = await response.text();
        console.log(responseBody);
    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

async function generateToken(host, restUsername, restPassword) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    const body = JSON.stringify({ userName: restUsername, password: restPassword });

    try {
        const response = await fetch(`${host}/api/refresh-tokens`, { method: 'POST', headers: headers, body: body });
        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const accessToken = jsonResponse._embedded.accessToken.securityToken;

        if (accessToken) {
            console.log(`Access Token: ${accessToken}`);
            return accessToken;
        } else {
            console.log(""Token not retrieved"");
        }
    } catch (error) {
        console.error(""Error:"", error.message);
    }

    return null;
}

main();
PHP
<?php

function main() {
    echo ""List Group Member Components\n"";

    $host = ""http://localhost:8080/Yellowfin"";
    $restUsername = ""admin@yellowfin.com.au"";
    $restPassword = ""test"";
    $groupName = ""New Group"";

    try {
        $token = generateToken($host, $restUsername, $restPassword);
    } catch (Exception $e) {
        echo ""Error generating token: "" . $e->getMessage();
        return;
    }

    try {
        $groupId = retrieveGroupIpIdForGroupName($host, $token, $groupName);
    } catch (Exception $e) {
        echo ""Error retrieving group ID: "" . $e->getMessage();
        return;
    }

    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    try {
        $response = httpRequest('GET', ""$host/api/user-groups/$groupId/members"", $headers);
        echo $response;
    } catch (Exception $e) {
        echo ""Error sending request: "" . $e->getMessage();
    }
}

function generateToken($host, $restUsername, $restPassword) {
    $nonce = mt_rand();

    $requestBody = json_encode(array(
        ""userName"" => $restUsername,
        ""password"" => $restPassword
    ));

    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('POST', ""$host/api/refresh-tokens"", $headers, $requestBody);

    $jsonResponse = json_decode($response, true);

    if (isset($jsonResponse[""_embedded""][""accessToken""][""securityToken""])) {
        $accessToken = $jsonResponse[""_embedded""][""accessToken""][""securityToken""];
        echo ""Access Token: "" . $accessToken . ""\n"";
        return $accessToken;
    } else {
        throw new Exception(""Token not retrieved successfully"");
    }
}

function retrieveGroupIpIdForGroupName($host, $token, $groupName) {
    $nonce = mt_rand();

    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('GET', ""$host/api/user-groups"", $headers);

    $jsonResponse = json_decode($response, true);

    $groups = $jsonResponse[""items""];
    foreach ($groups as $group) {
        if ($group[""shortDescription""] === $groupName) {
            return $group[""userGroupId""];
        }
    }

    echo ""Group could not be found for name: $groupName\n"";
    exit(-1);
}

function httpRequest($method, $url, $headers, $data = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception('Error: ' . curl_error($ch));
    }

    curl_close($ch);

    return $response;
}

main();

?>
Python
import json
import random
import time
import requests

def main():
    print(""List Group Member Components"")

    host = ""http://localhost:8080/Yellowfin""
    rest_username = ""admin@yellowfin.com.au""
    rest_password = ""test""

    group_name = ""New Group""

    try:
        token = generate_token(host, rest_username, rest_password)
    except Exception as e:
        print(f""Error generating token: {e}"")
        return

    try:
        group_id = retrieve_group_ip_id_for_group_name(host, token, group_name)
    except Exception as e:
        print(f""Error retrieving group ID: {e}"")
        return

    nonce = random.randint(0, 2**63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    try:
        response = requests.get(f""{host}/api/user-groups/{group_id}/members"", headers=headers)
        response.raise_for_status()
        print(response.text)
    except requests.RequestException as e:
        print(f""Error sending request: {e}"")

def generate_token(host, rest_username, rest_password):
    nonce = random.randint(0, 2**63 - 1)
    request_body = json.dumps({
        ""userName"": rest_username,
        ""password"": rest_password
    })
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }
    response = requests.post(f""{host}/api/refresh-tokens"", headers=headers, data=request_body)

    if response.status_code == 200:
        json_response = response.json()
        access_token = json_response[""_embedded""][""accessToken""][""securityToken""]
        print(""Access Token:"", access_token)
        return access_token
    else:
        raise Exception(""Token not retrieved successfully"")

def retrieve_group_ip_id_for_group_name(host, token, group_name):
    nonce = random.randint(0, 2**63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }
    response = requests.get(f""{host}/api/user-groups"", headers=headers)

    if response.status_code == 200:
        json_response = response.json()
        groups = json_response[""items""]
        for group in groups:
            if group[""shortDescription""] == group_name:
                return group[""userGroupId""]
        print(f""Group could not be found for name: {group_name}"")
        exit(-1)
    else:
        raise Exception(""Error retrieving group"")

if __name__ == ""__main__"":
    main()

List Group Members (Flattened)

Members of existing groups can be returned using the GET /api/user-groups/{groupId}/flat-users end-point Get User Group Flat User List. This service will return the individual user members of a group. This service will return an expanded list of users that may have been included by group member components that represent multiple users, like other groups, roles or LDAP groups. 

The following example returns the JSON payload representing a list of group member components.

These code examples use Apache HTTP Client and GSON for handling REST calls and JSON serialization.

Java
package rest.code.examples;
import java.io.IOException;
import java.util.Random;
import org.apache.hc.client5.http.fluent.Content;
import org.apache.hc.client5.http.fluent.Request;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
/**
 * List the flattened group members from a User Group using the Yellowfin REST API
 */
public class ListGroupMembersFlattened {
    public static void main(String[] args) throws Exception {

        System.out.println(""List Group Member Flattened"");

        String host = ""http://localhost:8080/Yellowfin"";
        String restUsername = ""admin@yellowfin.com.au"";
        String restPassword = ""test"";

        String groupName = ""New Group"";

        String token = generateToken(host, restUsername, restPassword);

        Integer groupId = retrieveGroupIpIdForGroupName(host, token, groupName);

        Content c = Request.get(host + ""/api/user-groups/"" + groupId + ""/flat-users"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();

        System.out.println(c.toString());

    }


    public static Integer retrieveGroupIpIdForGroupName(String host, String token, String groupName) throws IOException {

        Content c = Request.get(host + ""/api/user-groups"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong() + "", token="" + token)
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement groupList = jsonObject.get(""items"");
        JsonArray groups = groupList.getAsJsonArray();

        for (int i=0; i < groups.size(); i++ ) {
            JsonObject group = groups.getAsJsonArray().get(i).getAsJsonObject();
            if (groupName.equals(group.get(""shortDescription"").getAsString())) return group.get(""userGroupId"").getAsInt();
        }

        System.out.println(""Group could not be found for name:"" + groupName);
        System.exit(-1);

        return null;
    }

    /*
     *  This function generates an access token for a user that will grant them access to
     *  call REST API endpoints.
     */

    public static String generateToken(String host, String username, String password) throws IOException {

        Content c = Request.post(host + ""/api/refresh-tokens"")
                .addHeader(""Authorization"", ""YELLOWFIN ts="" + System.currentTimeMillis() + "" , nonce="" + new Random().nextLong())
                .addHeader(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
                .addHeader(""Content-Type"", ""application/json"")
                .bodyString(""{ \""userName\"": \""""+ username + ""\"",\""password\"": \""""+ password + ""\""}"", null)
                .execute().returnContent();

        JsonObject jsonObject = new JsonParser().parse(c.asString()).getAsJsonObject();
        JsonElement accessToken = jsonObject.getAsJsonObject(""_embedded"").getAsJsonObject(""accessToken"").get(""securityToken"");

        if (accessToken!=null) {
            System.out.println(""Access Token: "" + accessToken);
        } else {
            System.out.println(""Token not retrieved successfully"");
            System.exit(-1);
        }
        return accessToken.getAsString();

    }

}
C#
using System.Net.Http.Headers;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

namespace YellowfinAPIExamples
{
    public class ListGroupMembersFlattened
    {
        static async Task Main(string[] args)
        {
            Console.WriteLine(""List Group Member Flattened"");

            string host = ""http://localhost:8080/Yellowfin"";
            string restUsername = ""admin@yellowfin.com.au"";
            string restPassword = ""test"";
            string groupName = ""New Group"";

            string token = await GenerateToken(host, restUsername, restPassword);

            int groupId = await RetrieveGroupIpIdForGroupName(host, token, groupName);

            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", 
                    $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={new Random().NextInt64()}, token={token}"");
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                HttpResponseMessage response = await httpClient.GetAsync($""{host}/api/user-groups/{groupId}/flat-users"");
                if (response.IsSuccessStatusCode)
                {
                    string responseBody = await response.Content.ReadAsStringAsync();
                    Console.WriteLine(responseBody);
                }
                else
                {
                    Console.WriteLine(""Failed to retrieve group members. Status code: "" + response.StatusCode);
                }
            }
        }

        static async Task<int> RetrieveGroupIpIdForGroupName(string host, string token, string groupName)
        {
            using (var httpClient = new HttpClient())
            {
                httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", 
                    $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={new Random().NextInt64()}, token={token}"");
                httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                HttpResponseMessage response = await httpClient.GetAsync($""{host}/api/user-groups"");
                if (!response.IsSuccessStatusCode)
                {
                    throw new HttpRequestException($""Failed to retrieve user groups. Status code: {response.StatusCode}"");
                }

                string responseBody = await response.Content.ReadAsStringAsync();
                JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseBody);
                JArray groups = (JArray)jsonObject[""items""];

                foreach (var group in groups)
                {
                    if (group[""shortDescription""].ToString() == groupName)
                    {
                        return (int)group[""userGroupId""];
                    }
                }

                Console.WriteLine(""Group could not be found for name: "" + groupName);
                Environment.Exit(-1);
                return 0;
            }
        }

        static async Task<string> GenerateToken(string host, string username, string password)
        {
            using (var client = new HttpClient())
            {
                long nonce = new Random().NextInt64();

                var request = new HttpRequestMessage(HttpMethod.Post, $""{host}/api/refresh-tokens"")
                {
                    Content = new StringContent(
                        JsonConvert.SerializeObject(new { userName = username, password = password }),
                        System.Text.Encoding.UTF8,
                        ""application/json""
                    )
                };

                request.Headers.Authorization = new AuthenticationHeaderValue(""YELLOWFIN"", $""ts={DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}, nonce={nonce}"");
                request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(""application/vnd.yellowfin.api-v1+json""));

                HttpResponseMessage response = await client.SendAsync(request);
                string responseContent = await response.Content.ReadAsStringAsync();

                JObject jsonObject = JsonConvert.DeserializeObject<JObject>(responseContent);
                string accessToken = jsonObject[""_embedded""][""accessToken""][""securityToken""].ToString();

                if (!string.IsNullOrEmpty(accessToken))
                {
                    Console.WriteLine(""Access Token: "" + accessToken);
                }
                else
                {
                    Console.WriteLine(""Token not retrieved successfully"");
                    Environment.Exit(-1);
                }

                return accessToken;
            }
        }
    }
}
Go
package main

import (
	""bytes""
	""encoding/json""
	""fmt""
	""io/ioutil""
	""math/rand""
	""net/http""
	""os""
	""time""
)

func main() {
	fmt.Println(""List Group Member Flattened"")

	host := ""http://localhost:8080/Yellowfin""
	restUsername := ""admin@yellowfin.com.au""
	restPassword := ""test""
	groupName := ""New Group""

	token, err := generateToken(host, restUsername, restPassword)
	if err != nil {
		fmt.Println(""Error generating token:"", err)
		return
	}

	groupId, err := retrieveGroupIpIdForGroupName(host, token, groupName)
	if err != nil {
		fmt.Println(""Error retrieving group ID:"", err)
		return
	}

	client := &http.Client{}
	req, err := http.NewRequest(""GET"", fmt.Sprintf(""%s/api/user-groups/%d/flat-users"", host, groupId), nil)
	if err != nil {
		fmt.Println(""Error creating request:"", err)
		return
	}

	nonce := rand.Int63()
	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		fmt.Println(""Error sending request:"", err)
		return
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		fmt.Println(""Error reading response body:"", err)
		return
	}

	fmt.Println(string(body))
}

func retrieveGroupIpIdForGroupName(host, token, groupName string) (int, error) {
	client := &http.Client{}
	req, err := http.NewRequest(""GET"", fmt.Sprintf(""%s/api/user-groups"", host), nil)
	if err != nil {
		return 0, fmt.Errorf(""error creating request: %v"", err)
	}

	nonce := rand.Int63()
	req.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d, token=%s"", time.Now().UnixMilli(), nonce, token))
	req.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	req.Header.Set(""Content-Type"", ""application/json"")

	resp, err := client.Do(req)
	if err != nil {
		return 0, fmt.Errorf(""error sending request: %v"", err)
	}
	defer resp.Body.Close()

	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return 0, fmt.Errorf(""error reading response body: %v"", err)
	}

	var jsonObject map[string]interface{}
	if err := json.Unmarshal(body, &jsonObject); err != nil {
		return 0, fmt.Errorf(""error parsing JSON response: %v"", err)
	}

	items, ok := jsonObject[""items""].([]interface{})
	if !ok {
		return 0, fmt.Errorf(""items not found in response"")
	}

	for _, item := range items {
		group := item.(map[string]interface{})
		if group[""shortDescription""] == groupName {
			return int(group[""userGroupId""].(float64)), nil
		}
	}

	fmt.Println(""Group could not be found for name:"", groupName)
	os.Exit(-1)
	return 0, fmt.Errorf(""group not found"")
}

func generateToken(host, username, password string) (string, error) {
	nonce := rand.Int63()
	requestBody, err := json.Marshal(map[string]string{
		""userName"": username,
		""password"": password,
	})
	if err != nil {
		return """", fmt.Errorf(""error marshaling request body: %v"", err)
	}

	client := &http.Client{}
	request, err := http.NewRequest(""POST"", fmt.Sprintf(""%s/api/refresh-tokens"", host), bytes.NewBuffer(requestBody))
	if err != nil {
		return """", fmt.Errorf(""error creating request: %v"", err)
	}

	request.Header.Set(""Authorization"", fmt.Sprintf(""YELLOWFIN ts=%d, nonce=%d"", time.Now().UnixMilli(), nonce))
	request.Header.Set(""Accept"", ""application/vnd.yellowfin.api-v1+json"")
	request.Header.Set(""Content-Type"", ""application/json"")

	response, err := client.Do(request)
	if err != nil {
		return """", fmt.Errorf(""error sending request: %v"", err)
	}
	defer response.Body.Close()

	responseBody, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return """", fmt.Errorf(""error reading response body: %v"", err)
	}

	var jsonResponse map[string]interface{}
	if err := json.Unmarshal(responseBody, &jsonResponse); err != nil {
		return """", fmt.Errorf(""error parsing JSON response: %v"", err)
	}

	accessToken, ok := jsonResponse[""_embedded""].(map[string]interface{})[""accessToken""].(map[string]interface{})[""securityToken""].(string)
	if !ok {
		return """", fmt.Errorf(""token not retrieved successfully"")
	}

	fmt.Println(""Access Token:"", accessToken)
	return accessToken, nil
}
JavaScript
const fetch = require('node-fetch');

async function main() {
    console.log(""List Group Member Flattened"");

    const host = ""http://localhost:8080/Yellowfin"";
    const restUsername = ""admin@yellowfin.com.au"";
    const restPassword = ""test"";
    const groupName = ""New Group"";

    const token = await generateToken(host, restUsername, restPassword);

    if (token === null) {
        console.error(""Failed to retrieve access token"");
        return;
    }

    const groupId = await retrieveGroupIpIdForGroupName(host, token, groupName);

    if (groupId === null) {
        console.error(""Failed to retrieve group ID"");
        return;
    }

    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/user-groups/${groupId}/flat-users`, {
            method: 'GET',
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const responseBody = await response.text();
        console.log(responseBody);
    } catch (error) {
        console.error(""Error:"", error.message);
    }
}

async function retrieveGroupIpIdForGroupName(host, token, groupName) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}, token=${token}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    try {
        const response = await fetch(`${host}/api/user-groups`, {
            method: 'GET',
            headers: headers
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonObject = await response.json();
        const groups = jsonObject.items;

        for (const group of groups) {
            if (group.shortDescription === groupName) {
                return group.userGroupId;
            }
        }

        console.error(""Group could not be found for name: "" + groupName);
        process.exit(-1);
    } catch (error) {
        console.error(""Error:"", error.message);
    }

    return null;
}

async function generateToken(host, username, password) {
    const nonce = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
    const headers = {
        'Authorization': `YELLOWFIN ts=${Date.now()}, nonce=${nonce}`,
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    };

    const body = JSON.stringify({
        userName: username,
        password: password
    });

    try {
        const response = await fetch(`${host}/api/refresh-tokens`, {
            method: 'POST',
            headers: headers,
            body: body
        });

        if (!response.ok) {
            throw new Error(`HTTP error! Status: ${response.status}`);
        }

        const jsonResponse = await response.json();
        const accessToken = jsonResponse._embedded.accessToken.securityToken;

        if (accessToken) {
            console.log(`Access Token: ${accessToken}`);
        } else {
            console.error(""Token not retrieved successfully"");
            process.exit(-1);
        }

        return accessToken;
    } catch (error) {
        console.error(""Error:"", error.message);
    }

    return null;
}

main();
PHP
<?php

function main() {
    echo ""List Group Member Flattened\n"";

    $host = ""http://localhost:8080/Yellowfin"";
    $restUsername = ""admin@yellowfin.com.au"";
    $restPassword = ""test"";

    $groupName = ""New Group"";

    try {
        $token = generateToken($host, $restUsername, $restPassword);
    } catch (Exception $e) {
        echo ""Error generating token: "" . $e->getMessage() . ""\n"";
        return;
    }

    try {
        $groupId = retrieveGroupIpIdForGroupName($host, $token, $groupName);
    } catch (Exception $e) {
        echo ""Error retrieving group ID: "" . $e->getMessage() . ""\n"";
        return;
    }

    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    try {
        $response = httpRequest('GET', ""$host/api/user-groups/$groupId/flat-users"", $headers);
        echo $response;
    } catch (Exception $e) {
        echo ""Error sending request: "" . $e->getMessage() . ""\n"";
    }
}

function retrieveGroupIpIdForGroupName($host, $token, $groupName) {
    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce . ', token=' . $token,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $response = httpRequest('GET', ""$host/api/user-groups"", $headers);

    $jsonObject = json_decode($response, true);
    $groups = $jsonObject['items'];

    foreach ($groups as $group) {
        if ($group['shortDescription'] === $groupName) {
            return $group['userGroupId'];
        }
    }

    echo ""Group could not be found for name: "" . $groupName . ""\n"";
    exit(-1);
}

function generateToken($host, $username, $password) {
    $nonce = mt_rand();
    $headers = array(
        'Authorization: YELLOWFIN ts=' . intval(microtime(true) * 1000) . ', nonce=' . $nonce,
        'Accept: application/vnd.yellowfin.api-v1+json',
        'Content-Type: application/json'
    );

    $requestBody = json_encode(array(
        ""userName"" => $username,
        ""password"" => $password
    ));

    $response = httpRequest('POST', ""$host/api/refresh-tokens"", $headers, $requestBody);

    $jsonResponse = json_decode($response, true);
    if (isset($jsonResponse[""_embedded""][""accessToken""][""securityToken""])) {
        $accessToken = $jsonResponse[""_embedded""][""accessToken""][""securityToken""];
        echo ""Access Token: "" . $accessToken . ""\n"";
        return $accessToken;
    } else {
        throw new Exception(""Token not retrieved successfully"");
    }
}

function httpRequest($method, $url, $headers, $data = null) {
    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

    if ($data !== null) {
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    }

    $response = curl_exec($ch);

    if (curl_errno($ch)) {
        throw new Exception('Error: ' . curl_error($ch));
    }

    curl_close($ch);

    return $response;
}

main();

?>
Python
import json
import random
import time
import requests

def main():
    print(""List Group Member Flattened"")

    host = ""http://localhost:8080/Yellowfin""
    rest_username = ""admin@yellowfin.com.au""
    rest_password = ""test""

    group_name = ""New Group""

    try:
        token = generate_token(host, rest_username, rest_password)
    except Exception as e:
        print(f""Error generating token: {e}"")
        return

    try:
        group_id = retrieve_group_ip_id_for_group_name(host, token, group_name)
    except Exception as e:
        print(f""Error retrieving group ID: {e}"")
        return

    nonce = random.randint(0, 2**63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    try:
        response = requests.get(f""{host}/api/user-groups/{group_id}/flat-users"", headers=headers)
        response.raise_for_status()
        print(response.text)
    except requests.RequestException as e:
        print(f""Error sending request: {e}"")

def retrieve_group_ip_id_for_group_name(host, token, group_name):
    nonce = random.randint(0, 2**63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}, token={token}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    response = requests.get(f""{host}/api/user-groups"", headers=headers)
    response.raise_for_status()

    json_object = response.json()
    groups = json_object['items']

    for group in groups:
        if group['shortDescription'] == group_name:
            return group['userGroupId']

    print(f""Group could not be found for name: {group_name}"")
    exit(-1)

def generate_token(host, rest_username, rest_password):
    nonce = random.randint(0, 2**63 - 1)
    headers = {
        'Authorization': f'YELLOWFIN ts={int(time.time() * 1000)}, nonce={nonce}',
        'Accept': 'application/vnd.yellowfin.api-v1+json',
        'Content-Type': 'application/json'
    }

    request_body = json.dumps({
        ""userName"": rest_username,
        ""password"": rest_password
    })

    response = requests.post(f""{host}/api/refresh-tokens"", headers=headers, data=request_body)
    response.raise_for_status()

    json_response = response.json()
    access_token = json_response[""_embedded""][""accessToken""][""securityToken""]
    print(""Access Token:"", access_token)

    return access_token

if __name__ == ""__main__"":
    main()
  • No labels