Jira Tempo users are pseudonymised - rest

I am trying to obtain the worklogs using the Jira Tempo REST API.
The server I am working with is an on-premises one.
The data extraction is straightforward with one exception: some users are renamed from john.doe to JIRAUSER12345.
I could not find any rule for this and I also couldn't find any way to map the JIRAUSER12345 to the actual username.
Is there any way of getting the real user name? Is it possible that I am missing some access rights (probably at team level) that forbid me seeing the real user names?

Reading this article gives the reason for the anonymization:
https://tempo-io.atlassian.net/wiki/spaces/KB/pages/1196327022/Why+do+I+see+JIRAUSERxxxx+as+worklog+author
In order to get the correct user id I did something like:
usersCache = {}
def getUserbyKey(key):
if not key in usersCache:
query = {
'key': key
}
response = requests.get(f"{JIRA_BASE_URL}/rest/api/latest/user",auth=authorization, headers=headers, params=query)
j = response.json()
usersCache[key]=j["displayName"]
j = usersCache.get(key)
return j
...
for wl in worklogs:
user = getUserbyKey(wl["worker"])
key = wl["issue"]["key"]
timeSpent = wl["timeSpent"]

Related

MSCRM Retrieve Multiple PlugIn limits the other Retrievemultiple uery

In my scenario, there is a plugin (Retrieve Multiple) on Annotation. This plugin is nothing just a part of BLOB Storage solution(used for Attachment Management solution provided by Microsoft). So, it is clear that in our CRM, MicrosoftlLabsAzureBlobstorage is being used.
Now, I am executing a console app which retrieves multiple annotations through Query Expression. When it tries to fetch records around 500 or 600, it throws below error.
{The plug-in execution failed because no Sandbox Hosts are currently
available. Please check that you have a Sandbox server configured and
that it is running.\r\nSystem.ServiceModel.CommunicationException:
Microsoft Dynamics CRM has experienced an error. Reference number for
administrators or support: #AFF51A0F"}
When I fetch specific records or very less records, it executes fine.
So, I my question is that is there any limitation in number for Rerieve Multiple Query ? if retrievemultiple PlugIn exists ?
Is there any other clue that I am not able to find ?
To work around this conflict, in your console application code you may want to try retrieving smaller pages of annotations, say 50 at a time, and loop through the pages to process them all.
This article provides sample code for paging a QueryExpression.
Here's the abridged version of that sample:
// The number of records per page to retrieve.
int queryCount = 3;
// Initialize the page number.
int pageNumber = 1;
// Initialize the number of records.
int recordCount = 0;
// Create the query expression
QueryExpression pagequery = new QueryExpression();
pagequery.EntityName = "account";
pagequery.ColumnSet.AddColumns("name", "emailaddress1");
// Assign the pageinfo properties to the query expression.
pagequery.PageInfo = new PagingInfo();
pagequery.PageInfo.Count = queryCount;
pagequery.PageInfo.PageNumber = pageNumber;
// The current paging cookie. When retrieving the first page,
// pagingCookie should be null.
pagequery.PageInfo.PagingCookie = null;
while (true)
{
// Retrieve the page.
EntityCollection results = _serviceProxy.RetrieveMultiple(pagequery);
if (results.Entities != null)
{
// Retrieve all records from the result set.
foreach (Account acct in results.Entities)
{
Console.WriteLine("{0}.\t{1}\t{2}", ++recordCount, acct.Name,
acct.EMailAddress1);
}
}
// Check for more records, if it returns true.
if (results.MoreRecords)
{
// Increment the page number to retrieve the next page.
pagequery.PageInfo.PageNumber++;
// Set the paging cookie to the paging cookie returned from current results.
pagequery.PageInfo.PagingCookie = results.PagingCookie;
}
else
{
// If no more records are in the result nodes, exit the loop.
break;
}
}
This page has more info and another sample.

Facebook Graph API Ad Report Run - Message: Unsupported get request

I'm making an async batch request with 50 report post request on it.
The first batch request returns me the Report Ids
1st Step
dynamic report_ids = await fb.PostTaskAsync(new
{
batch = batch,
access_token = token
});
Next I'm getting the reports info, to get the async status to see if they are ready to be downloaded.
2st Step
var tListBatchInfo = new List<DataTypes.Request.Batch>();
foreach (var report in report_ids)
{
if (report != null)
tListBatchInfo.Add(new DataTypes.Request.Batch
{
name = !ReferenceEquals(report.report_run_id, null) ? report.report_run_id.ToString() : report.id,
method = "GET",
relative_url = !ReferenceEquals(report.report_run_id, null) ? report.report_run_id.ToString() : report.id,
});
}
dynamic reports_info = await fb.PostTaskAsync(new
//dynamic results = fb.Post(new
{
batch = JsonConvert.SerializeObject(tListBatchInfo),
access_token = token
});
Some of the ids generated in the first step are returning this error, once I call them in the second step
Message: Unsupported get request. Object with ID '6057XXXXXX'
does not exist, cannot be loaded due to missing permissions, or does
not support this operation. Please read the Graph API documentation at
https://developers.facebook.com/docs/graph-api
I know the id is correct because I can see it in using facebook api explorer. What am I doing wrong?
This may be caused by Facebook's replication lag. That typically happens when your POST request is routed to server A, returning report ID, but query to that ID gets routed to server B, which doesn't know about the report existence yet.
If you try to query the ID later and it works, then it's the lag. Official FB advice for this is to simply wait a bit longer before querying the report.
https://developers.facebook.com/bugs/250454108686614/

GitHub API get user's last login

I have a GitHub organization and I am trying to determine the last login dates for all of the users in the organization.
I see that there is a way to get last commits, but there are some users that only do pulls so this would not work.
The /users/:user/events call doesn't return any results for me.
Neither the GitHub User API nor Event API would include that information.
I suspect a user's last login time is considered "private", meaning you are not suppose to know when a user last logged or not. (privacy issue)
The GitHub privacy statement which states "User Personal Information does not include aggregated, non-personally identifying information". A user's last login time likely is included under this statement.
If you have GitHub Enterprise Cloud, you may be able to use the Audit log to determine if there has been activity in the last 90 days.
Untested but a sample approach:
"""
Script to retrieve all audit events for a user.
Note need GitHub enterprise cloud
"""
import csv
import os
import requests
# Fetch required values from environment variables
github_username = os.environ.get('GITHUB_USERNAME')
github_password = os.environ.get('GITHUB_PASSWORD')
github_base_url = os.environ.get('GITHUB_BASE_URL', 'https://api.github.com')
github_org = os.environ.get('GITHUB_ORG', 'my-org')
per_page = int(os.environ.get('PER_PAGE', 100))
csv_path = os.environ.get('CSV_PATH', 'output/permissions_for_team_repos.csv')
# Check credentials have been supplied
if not github_username or not github_password:
raise ValueError('GITHUB_USERNAME and GITHUB_PASSWORD must be supplied')
# Prepare a requests session to reuse authentication configuration
# auth parameter will use basic auth automatically
session = requests.Session()
session.auth = (github_username, github_password)
session.headers = {'accept': 'application/vnd.github.v3+json'}
def generate_members():
"""
Generator function to paginate through all organisation members (users)
https://docs.github.com/en/rest/reference/orgs#list-organization-members
"""
# Fetch the repositories for the specified team
url = f"{github_base_url}/orgs/{github_org}/members"
# Set pagination counters
page = 1
paginate = True
# Paginate until there are no repos left
while paginate:
response = session.get(url, params={'per_page': per_page, 'page': page})
if response.status_code > 399:
raise Exception(f"GitHub API response code: {response.status_code}")
members = response.json()
records = len(members)
# Check if the current page contains any records, if not continue looping
if records == 0:
paginate = False
# Fetch source repo permissions
for member in members:
yield member
# Increment page counter for next loop
page += 1
def generate_member_audit_events(member_name):
"""
Generator function to fetch organisation audit events for a specific member
https://docs.github.com/en/rest/reference/orgs#get-the-audit-log-for-an-organization
https://docs.github.com/en/organizations/keeping-your-organization-secure/reviewing-the-audit-log-for-your-organization
"""
url = f"{github_base_url}/orgs/{github_org}/audit-log"
# Set pagination counters
page = 1
paginate = True
# Paginate until there are no teams left
while paginate:
response = session.get(url, params={'per_page': per_page, 'page': page, 'phrase': f'actor:{member_name}'})
if response.status_code > 399:
raise Exception(f"GitHub API response code: {response.status_code}")
audit_events = response.json()
records = len(audit_events)
# Check if the current page contains any records, if not continue looping
if records == 0:
paginate = False
# Fetch source repo permissions
for audit_event in audit_events:
yield audit_event
# Increment page counter for next loop
page += 1
with open(csv_path, 'w', newline='') as csvfile:
fieldnames = ['member', 'member_type', 'site_admin', 'action', 'created_at']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()
for member in generate_members():
row = {'member': member['login'], 'member_type': member['type'], 'site_admin': member['site_admin']}
for audit_event in generate_member_audit_events(member['login']):
row['action'] = audit_event['action']
row['created_at'] = audit_event['created_at']
writer.writerow(row)

Python Retrieving all Groups from a domain using OAuth2

Using PYTHON, To get all groups in a domain, in OAuth1 had a command like:
groupfeed = api(lambda: GROUPS_SERVICE.RetrieveAllGroups())
In OAuth2, will it be
allGrps = client.groups().list(customer='my_company').execute()
I am looking for the equivalent code to get ALL groups in a domain. Thanks for your help and attention.
If you have more than 200 groups, the results will be paged and returned over multiple API calls. You need to keep retrieving pages until none are left:
all_groups = []
request = client.groups().list(customer='my_customer')
while True: # loop until no nextPageToken
this_page = request.execute()
if 'items' in this_page:
all_groups += this_page['items']
if 'nextPageToken' in this_page:
request = client.groups().list(
customer='my_customer',
pageToken=this_page['nextPageToken'])
else:
break
also notice that it's my_customer, not my_company.

How to make a REST delete method with cfhttp

I have never done it before and now when the need arise, things are not working.
I have to send an ID to delete a DB record with RESTful service. Here is the code I am trying:
<cfhttp url="http://127.0.0.1:8500/rest/test/something" method="DELETE" port="8500" result="qryRes1">
<cfhttpparam type="body" value="36"/>
</cfhttp>
and in the REST function
remote any function someName() httpmethod="DELETE"{
var testID = ToString(getHTTPRequestData().content);
//make db call to delete
return testid;
}
The result comes as blank [empty string]. I am not able to retrieve the sent value in function. What I am missing?
Edit: one slightly different but related to CF rest, is it necessary to convert query to an array before sending it back to client? Directly serializing won't solve the purpose same way?
you may want to take a look at deleteUser() in http://www.anujgakhar.com/2012/02/20/using-rest-services-in-coldfusion-10/ as an example of how to support DELETE in REST API style.
remote any function deleteUser(numeric userid restargsource="Path") httpmethod="DELETE" restpath="{userid}"
{
var response = "";
var qry = new Query();
var userQry = "";
qry.setSQl("delete from tbluser where id = :userid");
qry.addParam(name="userid", value="#arguments.userid#", cfsqltype="cf_sql_numeric");
userQry = qry.execute().getPrefix();
if(userQry.recordcount)
{
response = "User Deleted";
} else {
throw(type="Restsample.UserNotFoundError", errorCode='404', detail='User not found');
}
return response;
}
As for the 2nd part of your question, it'd be best to first turn a query into a array of structs first unless you're using CF11 which does it for you. See: http://www.raymondcamden.com/index.cfm/2014/5/8/ColdFusion-11s-new-Struct-format-for-JSON-and-how-to-use-it-in-ColdFusion-10
The default JSON structure for query in CF 8 to 10 were designed for <cfgrid> in ColdFusion on top of Adobe's discontinued Spry framework.