2022-05-11

script to export in CSV all the users and groups from microstrategy intelligence server

 https://community.microstrategy.com/s/article/Getting-information-about-all-users-that-belong-to-a-User-Group-including-subgroups?language=en_US

import requests
from datetime import datetime
import copy
import itertools
import pandas as pd
import csv

#### Parameters ####
api_login = 'garbiaa'
api_password = 'garbiaa123'
base_url = 'https://bi-mdl-test.conti.de:8080/MicroStrategyLibrary/api/';
env_id = 'GROUPS_' #CSV files will be saved with this prefix

#### FUNCTIONS MSTR ###
def login(base_url,api_login,api_password):
    print("Getting token...")
    data_get = {'username': api_login,
                'password': api_password,
                'loginMode'1}
    r = requests.post(base_url + 'auth/login'data=data_get)
    if r.ok:
        authToken = r.headers['X-MSTR-AuthToken']
        cookies = dict(r.cookies)
        print("Token: " + authToken)
        return authToken, cookies
    else:
        print("HTTP %i - %s, Message %s" % (r.status_code, r.reason, r.text))
        
def logout(authTokencookies):
    headers = set_headers(authToken)
    print("\nLogging out...")
    r = requests.post(base_url + "auth/logout"headers=headers, cookies=cookies)
    if r.ok:
        print("OK")
    else:
        print("HTTP %i - %s, Message %s" % (r.status_code, r.reason, r.text))    

def set_headers(authToken):
    headers = {'X-MSTR-AuthToken': authToken, 'Content-Type''application/json'}
    return headers
        
def getGroupsAll(authTokencookies):
    headers = set_headers(authToken)
    usersAll_url = (base_url  + "usergroups?limit=-1")
    print("\nGetting All User Groups info...")
    r = requests.get(usersAll_url, headers=headers, cookies=cookies)
    if r.ok:
        print("Error: " + str(r.raise_for_status()) + "   ||   HTTP Status Code: " + str(r.status_code))
        groupsAll = r.json()
        print("Number of MSTR groups: ", str(len(groupsAll)), " ")
        return groupsAll
    else:
        print("HTTP %i - %s, Message %s" % (r.status_code, r.reason, r.text))
        
def getGroupMembers(auth_token, group_id, cookies, print_fl):
    headers = set_headers(auth_token)
    usergroup_url = (base_url  + "usergroups/" + group_id + '/members?includeAccess=false')
    if print_fl:
        print("\nGetting MSTR User Group info...")
    r = requests.get(usergroup_url, headers=headers, cookies=cookies)
    if r.ok:
        usergroup_members = r.json()
        if print_fl:
            print("Error: " + str(r.raise_for_status()) + "   ||   HTTP Status Code: " + str(r.status_code))
            print("Number of users in the selected MSTR group: ", str(len(usergroup_members)), " ")
        return usergroup_members
    else:
        print("HTTP %i - %s, Message %s" % (r.status_code, r.reason, r.text))

#### FUNCTIONS for User Groups ###
def group_children(group_ID, group_list): #provide Group ID and get a list of children
    gc=[]
    for pair in group_list:
        if pair[0]==group_ID:
            gc.append(pair[1])
    return gc

def group_parent(group_ID, group_list): #provide Group ID and get a list of parents
    gp=[]
    for pair in group_list:
        if pair[1]==group_ID:
            gp.append(pair[0])
    return gp

### MAIN
authToken, cookies = login(base_url,api_login,api_password)

# Getting users for each User Group
dt1=datetime.now() # This can be a long process that can take minutes, so we will measure it.
print("\n", dt1)
groupsAll =getGroupsAll(authToken, cookies)
groupsDict={} # this will store ID of every UserGroup and all direct children objects
count_ug=0
for i in groupsAll:
    ug_members=[]
    usergroup_members = getGroupMembers(authToken, i["id"], cookies, False)
    for j in usergroup_members:
        ug_members.append([j['id'],j['name'],j['subtype']])
    groupsDict[i["id"]]=ug_members
    count_ug+=1 # this counter will give you hints how long the whole process will take
    if (count_ug % 100) == 0:
        eta = (len(groupsAll)/count_ug)*(datetime.now()-dt1)
        print(count_ug, "user groups processed / ETA: ", eta)
print("##  Execution time:", datetime.now()-dt1, "\n")


# Creating a few lists for Groups and users. It will make it easier to perform counts.
GG, GU, GUG = [],[],[] #Group-Group, Group_User, Group_(User+Group)
for x in groupsDict:
    for y in groupsDict[x]:
        GUG.append([x, y[0], y[2]]) #both children Users and Groups
        if y[2] == 8704:
            GU.append([x, y[0]]) #only children Users
        if y[2] == 8705:
            GG.append([x, y[0]]) #only children subgroups

#remove groups that are empty dead ends
GG_copy = copy.deepcopy(GG) # working on copies to preserve original lists
GG_dupl = copy.deepcopy(GG_copy)

print("GG pairs= ", len(GG_dupl))
for pair in GG_copy: 
    if not group_children(pair[1], GUG): # no children users or groups
        GG_dupl.remove(pair)
print("GG pairs= ", len(GG_dupl))
GG_copy = copy.deepcopy(GG_dupl)


# Assign users from Level X, to one level up: Level X+1
# It will analyze all users of the GG structure bottom up
# It will remove processed group. It will loop until the list is empty
GU_copy = copy.deepcopy(GU)
print("GG pairs= ", len(GG_copy), "  ||  GU pairs =", len(GU_copy))

while len(GG_copy) > 0:
    GG_dupl = copy.deepcopy(GG_copy)
    GU_dupl = copy.deepcopy(GU_copy)

    for pair in GG_copy: # for combination Group-Subgroup
        if not group_children(pair[1], GG_copy): #take Subgroup, take only those without any further subgroups
            new_users=group_children(pair[1], GU_copy) #for that Subgroup check all Users
            for nu in new_users: #for each user add it to the Group from initial FOR loop (materialize indirect relation in GU table)
                if nu not in GU_dupl:
                    GU_dupl.append([pair[0],nu])
            GG_dupl.remove(pair) # after assignment remove GG pair from further calculations

    GG_copy = copy.deepcopy(GG_dupl)
    GU_copy = copy.deepcopy(GU_dupl)
    print("GG pairs= ", len(GG_copy), "  ||  GU pairs =", len(GU_copy))
    #print("GU pairs =", len(GU_copy))


# Remove duplicates Group-User
GU_copy.sort()
GU_copy=list(GU_copy for GU_copy,_ in itertools.groupby(GU_copy))
print("Removing duplicates...")
print("GG pairs= ", len(GG_copy), "  ||  GU pairs =", len(GU_copy))

# Export to CSV
df = pd.DataFrame(GU_copy)
df.to_csv(env_id+'GU_final.csv', index = None,quoting=csv.QUOTE_ALL, header=["Group_ID", "User_ID"])

df = pd.DataFrame(GG)
df.to_csv(env_id+'GG_initial.csv', index = None,quoting=csv.QUOTE_ALL, header=["Parent Group", "Child_Group"])

df = pd.DataFrame(groupsAll)
df.replace(to_replace=[r"\\t|\\n|\\r", "\t|\n|\r"], value=["",""], regex=True, inplace=True)
df.to_csv(env_id+'LU_Groups.csv', index = None,quoting=csv.QUOTE_ALL)

# Get information about ALL users from Everyone user group + ENABLED flag
everyon=getGroupMembers(authToken, 'C82C6B1011D2894CC0009D9F29718E4F', cookies, False)
df = pd.DataFrame(everyon)
df.replace(to_replace=[r"\\t|\\n|\\r", "\t|\n|\r"], value=["",""], regex=True, inplace=True)
df.to_csv (env_id+'LU_Users.csv', index = None,quoting=csv.QUOTE_ALL)

# Log out and finish
logout(authToken, cookies)

Niciun comentariu:

Trimiteți un comentariu