If you are unable to create a new account, please email support@bspsoftware.com

 

News:

MetaManager - Administrative Tools for IBM Cognos
Pricing starting at $2,100
Download Now    Learn More

Main Menu

REST API users call

Started by patternghost, 26 May 2021 10:28:18 AM

Previous topic - Next topic

patternghost

Not sure which forum this belongs in, but has anyone successfully implemented a GET /users call using the Cognos 11.1.7 REST API?  I am trying to use the call to return the ID of a user, but I can't figure out what the call wants.  According to the documentation, it wants a parameter of:
identifier (string(query))
Unique id from Cognos Access Manager Identifier or CAMID of the user. I.e., if a user's CAMID value is CAMID("APPID:u:jdoe@ibm.com"), the value of identifier is jdoe@ibm

Is this a URL parameter sent with a question mark?  Is this a body param?  I have tried many variations an nothing has worked.  I have to assume it is a URL param, when I don't sent it as such I get a 400 and "may not be null".  But it doesn't like anything I send it. 

In the process, all I have is the user name.  I need to call this to get the user ID to send to other endpoints.

Thanks!

patternghost

After trial and error, I found that if I send /users?identifier=<namespace> will return all users in the namespace.  I can work with that.

macsir

Quote from: patternghost on 27 May 2021 09:56:54 AM
After trial and error, I found that if I send /users?identifier=<namespace> will return all users in the namespace.  I can work with that.

Hi, I am tying to do the same but actually haven't got session yet to pass the authentication using the format which IBM suggests. Could you share how you did that? Thanks.
https://www.ibm.com/docs/en/cognos-analytics/11.1.0?topic=apis-rest-api

jackson.eyton

#3
You certainly can use the credentials method as specified for 11.2.4, however I found the CAMAPI method as documented for 12 does function for 11.2.4 and is much easier to use. You'll have to create an API key for the user within the Cognos interface. Logged into Cognos as the user, at the top right click the account profile icon, then click 'profile and settings'. From there click the 'manage' link next to 'My API keys'. Here you can create your API key, don't lose it or you'll have to create a new one.

12 Documentation

Here is a super simple proof of concept in powershell (I'm forced to use powershell, please... someone help me...)
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# Define authentication parameters
$authParams = @{
    parameters = @(
        @{
            name = "CAMAPILoginKey"
            value = "YourKeyHere"
        }
    )
}
# Convert the authentication parameters to JSON
$authParamsJson = $authParams | ConvertTo-Json
# Send the PUT request to authenticate
$auth = Invoke-RestMethod -Method PUT -Uri 'http://yourCognosURL.com:9300/api/v1/session' -Body $authParamsJson -ContentType 'application/json' -UseBasicParsing

# Define headers
$headers = @{
    'accept' = 'application/json'
    'IBM-BA-Authorization' = $auth.session_key
    'Cache-Control' = 'no-cache'
}

# Send the GET request to the /api/v1/session endpoint
Invoke-RestMethod -Method GET -Uri 'http://yourCognosURL.com:9300/api/v1/session' -Headers $headers -UseBasicParsing

If you want to use credentials you sure can, but you need to know your CAMNamespace name as shown in the Cognos Administration Console application (cogstart.xml) on the server itself. Here is the authparams structure that you could drop in replace to the previous code example:
# Define authentication parameters
$authParams = @{
    parameters = @(
        @{
            name = "CAMNamespace"
            value = "yourNamespace.com"
        },
        @{
            name = "CAMUsername"
            value = "yourUsername"
        },
        @{
            name = "CAMPassword"
            value = "yourPassword"
        }
    )
}

I hope that helps! Now if only I could figure out how to do the auth using the DataDirect Autonomous REST connector... I'm close... I can feel it.

jackson.eyton

Quote from: patternghost on 27 May 2021 09:56:54 AMAfter trial and error, I found that if I send /users?identifier=<namespace> will return all users in the namespace.  I can work with that.


Can you confirm this still works? I cant seem to get this to work on 11.2.4

dougp

#5
I somehow missed this thread.  Maybe could have helped speed my learning...

I can't get this working in 12.0.4 (didn't try in 11.2.4).  My problem is a timeout.  I am using an Active Directory external directory namespace with probably 14,000 users and many many groups.  I'd guess only users are being listed by this call because this seems to be about user profiles.  But 14,000 seems to be too much.  Although, I can get all 14,000 users and count them using Get-ADUser in PowerShell in about 12 seconds.  So I don't know where the slowdown is using the Cognos REST API.

If patternghost is still watching this thread...  How many users in the directory namespace where you had success?

I'm not seeing in the thin documentation IBM provides...  Is there an option to restrict the number of items returned per call, and iterate through to the next group of results?  Maybe something like:

$uriBase/api/v1/users?identifier=$namespace&top=$top&skip=$skip
I see in 12.0.x there is a new option under Accounts:  /namespace_folder/{id}/items

That looks promising.  I should be able to use...
$uriBase/api/v1/namespace_folder/$namespace/items?limit=$limit&offset=$offset...to limit my call to something of a reasonable size that should return in a reasonable time.

But...

id is required and is also labeled Folder id.  But nowhere is "Folder id" defined.  I tried using my namespace name (which has the appearance of a folder in the Security tab in Cognos Administration) and got:

Invalid id format.

Is anyone here aware of any actual documentation for the Cognos Analytics REST API?

dougp

#6
Quote from: jackson.eyton on 16 Apr 2024 02:39:19 PMYou certainly can use the credentials method as specified for 11.2.4, ...

...(I'm forced to use powershell, please... someone help me...)...

I put my code between calls to these functions.  It asks for my user name and password when I run it.  Using a CA API key could improve this.  It should probably require the namespace name as a parameter rather than hard-coding it.  But I have only one namespace, so this works for me.

function start-CognosSession {<#
    .SYNOPSIS
    Start a Cognos REST API session.
 
    .DESCRIPTION
    docs at http://<cognos_analytics_server>:<port>/api/api-docs
    Asks for user name and password
    Exits on empty password

    .PARAMETER serverName
    Cognos server to use.
 
    .EXAMPLE
    start-CognosSession "CognosServer.company.com"
 
    #>
    [CmdletBinding()]
    param(
        [parameter(position=0, mandatory=$true)]
        [PSCustomObject]$serverName
    )
    # Write-Host "start-CognosSession start"
    $CognosSession = [PSCustomObject]@{}

    $protocol = "https"
    $port = "9300"
    $uriBase = "$protocol`://$serverName`:$port"
    $contentType = "application/json; charset=utf-8"

    $CognosSession | Add-Member -MemberType NoteProperty -Name 'protocol' -Value $protocol
    $CognosSession | Add-Member -MemberType NoteProperty -Name 'serverName' -Value $serverName
    $CognosSession | Add-Member -MemberType NoteProperty -Name 'port' -Value $port
    $CognosSession | Add-Member -MemberType NoteProperty -Name 'uriBase' -Value $uriBase
    $CognosSession | Add-Member -MemberType NoteProperty -Name 'contentType' -Value $contentType
   
    $userNamespace = "MyNamespaceName"
    $userName = Read-Host "User Name"
    $UserPwd = Read-Host "Password" -AsSecureString
   
    $err = $false

    try {
        $userPassword = ConvertFrom-SecureString -SecureString $UserPwd -AsPlainText
    }
    catch {
        Write-Host "Empty password.  Quitting."
        $err = $true
    }

    if (!$err) {
        $bdy = [PSCustomObject]@{}
        $paramarray = @()
        $param = [PSCustomObject]@{}
            $param | Add-Member -MemberType NoteProperty -Name 'name'  -Value "CAMNamespace"
            $param | Add-Member -MemberType NoteProperty -Name 'value' -Value $userNamespace
            $paramarray += $param
        $param = [PSCustomObject]@{}
            $param | Add-Member -MemberType NoteProperty -Name 'name'  -Value "CAMUsername"
            $param | Add-Member -MemberType NoteProperty -Name 'value' -Value $userName
            $paramarray += $param
        $param = [PSCustomObject]@{}
            $param | Add-Member -MemberType NoteProperty -Name 'name'  -Value "CAMPassword"
            $param | Add-Member -MemberType NoteProperty -Name 'value' -Value $userPassword
            $paramarray += $param
        $bdy | Add-Member -MemberType NoteProperty -Name 'parameters' -Value $paramarray
        $body = ConvertTo-Json $bdy
        $uri = "$uriBase/api/v1/session"
       
        $a = Invoke-RestMethod `
                -Uri $uri `
                -Method Put `
                -contentType $contentType `
                -SessionVariable "Session" `
                -Body $body
       
        # next line throws error, but retrieves a XSRF-Token cookie
        Write-Host "Ignore the next error.  The next line throws an error, but retrieves a XSRF-Token cookie."
        $a = Invoke-RestMethod -Uri $uri -Method Get -contentType $contentType -WebSession $Session
        $CognosSession | Add-Member -MemberType NoteProperty -Name 'Session' -Value $Session -TypeName 'Microsoft.PowerShell.Commands.WebRequestSession'
       
        $Cookies = $Session.Cookies.GetCookies($uri)
        $XSRFTOKEN = $Cookies["XSRF-TOKEN"].Value
       
        [System.Collections.IDictionary]$headers = @{
            'x-xsrf-token' = $XSRFTOKEN
            'accept' = 'application/json'
            'Cache-Control' = 'no-cache'
        }
       
        $CognosSession | Add-Member -MemberType NoteProperty -Name 'Headers' -Value $headers

        $CognosSession
    }
    else {
        $null
    }
    # Write-Host "start-CognosSession end"
}

function stop-CognosSession {<#
    .SYNOPSIS
    End a Cognos REST API session.
 
    .DESCRIPTION

    .PARAMETER CognosSession
    CognosSession object created by start-CognosSession
 
    .EXAMPLE
    end-CognosSession -CognosSession $CognosSession
 
    #>
    [CmdletBinding()]
    param(
        [parameter(position=0, mandatory=$true)]
        [PSCustomObject]$CognosSession
    )
    # Write-Host "stop-CognosSession start"
    # log out
    $uri = "$($CognosSession.uriBase)/api/v1/session"
    Invoke-RestMethod -Uri $uri -Method Delete -WebSession $CognosSession.Session
    # Write-Host "stop-CognosSession end"
}

start-CognosSession returns an object with environment parameters, so I can use that later, like this...

$CognosSession = start-CognosSession -serverName $serverName
$uriBase     = $CognosSession.uriBase
$protocol    = $CognosSession.protocol
$serverName  = $CognosSession.serverName
$port        = $CognosSession.port
$Session     = $CognosSession.Session
$headers     = $CognosSession.Headers
$contentType = $CognosSession.contentType
$uri = "$uriBase/api/v1/content"
$content = Invoke-RestMethod -Uri $uri -Method Get -Headers $headers -contentType $contentType -WebSession $Session
$content.content | Format-List
stop-CognosSession -CognosSession $CognosSession