<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Create users and roles from a CSV file in ArcGIS API for Python Questions</title>
    <link>https://community.esri.com/t5/arcgis-api-for-python-questions/create-users-and-roles-from-a-csv-file/m-p/1386180#M9677</link>
    <description>&lt;P&gt;I hacked this to work with 3.7....&amp;nbsp;&lt;/P&gt;&lt;P&gt;Now I get the follwing error... &lt;span class="lia-unicode-emoji" title=":disappointed_face:"&gt;😞&lt;/span&gt;&lt;/P&gt;&lt;P&gt;fumbling thru an example... i am..&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;File "C:\SGT\ESRI\Python\ArcGIS Enterprise\AddUserToEntPortal-fumblethru.py", line 58, in generateToken&lt;BR /&gt;if responseJSON.has_key('error'):&lt;BR /&gt;AttributeError: 'dict' object has no attribute 'has_key'&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;# Requires Python 2.7+&lt;/P&gt;&lt;P&gt;# Demonstrates how to add users to the ArcGIS Enterprise portal in bulk&lt;/P&gt;&lt;P&gt;# For Http calls&lt;BR /&gt;import urllib3, urllib, json&lt;BR /&gt;import urllib.parse&lt;BR /&gt;import urllib.response&lt;BR /&gt;from urllib.request import urlopen&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;from notebook.notebookapp import raw_input&lt;/P&gt;&lt;P&gt;# This function connects to the portal and adds members to it from a collection&lt;BR /&gt;# def createUsers(username,password, portalUrl, provider,userParamsQ):&lt;BR /&gt;# ## these are the tinkerbell-az server credentials: DEVELOPMENT server&lt;BR /&gt;username = "sitdg5g45634min"&lt;BR /&gt;password = "fdghfdghfdghfdghfdghv"&lt;BR /&gt;portalUrl = "&lt;A href="https://tinkerbell-az.ci.janesville.wi.us/devportal" target="_blank"&gt;https://tinkerbell-az.ci.janesville.wi.us/devportal&lt;/A&gt;"&lt;BR /&gt;serverUrl = "&lt;A href="https://tinkerbell-az.ci.janesville.wi.us/devserver/admin" target="_blank"&gt;https://tinkerbell-az.ci.janesville.wi.us/devserver/admin&lt;/A&gt;"&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;# This function gets a token from the portal&lt;BR /&gt;#def generateToken(username, password, serverUrl, json_obj=None):&lt;BR /&gt;def generateToken(username, password, serverUrl):&lt;BR /&gt;parameters = urllib.parse.urlencode({'username' : username,&lt;BR /&gt;'password' : password,&lt;BR /&gt;'client' : 'referer',&lt;BR /&gt;'referer': portalUrl,&lt;BR /&gt;'expiration': 600,&lt;BR /&gt;'f' : 'json'})&lt;BR /&gt;pmans = parameters.encode('utf-8')&lt;BR /&gt;try:&lt;BR /&gt;#response = urllib3.urlopen(portalUrl + '/sharing/rest/generateToken?', parameters).read()&lt;BR /&gt;response = urllib.request.urlopen(serverUrl + '/generateToken?', pmans)&lt;BR /&gt;#response = urllib.request.urlopen(serverUrl + '/generateToken?', pmans).read()&lt;BR /&gt;responsestring = response.read().decode('utf-8')&lt;BR /&gt;json_obj = json.loads(responsestring)&lt;BR /&gt;#print('this is the response :' + json_obj)&lt;/P&gt;&lt;P&gt;except Exception as e:&lt;BR /&gt;#raise SystemExit( 'Unable to open the url %s/sharing/rest/generateToken' % (portalUrl))&lt;BR /&gt;raise SystemExit('Unable to open the url %s/' % (serverUrl))&lt;BR /&gt;# responseJSON = json.loads(response.strip(' \t\n\r'))&lt;/P&gt;&lt;P&gt;responseJSON = json.loads(responsestring)&lt;/P&gt;&lt;P&gt;#content = json.loads(r.decode('utf-8').replace('\n', ''))&lt;/P&gt;&lt;P&gt;# Log results&lt;BR /&gt;if responseJSON.has_key('error'):&lt;BR /&gt;errDict = responseJSON['error']&lt;BR /&gt;if int(errDict['code'])==498:&lt;BR /&gt;message = 'Token Expired. Getting new token... '&lt;BR /&gt;token = generateToken(username,password, serverUrl)&lt;BR /&gt;else:&lt;BR /&gt;message = 'Error Code: %s \n Message: %s' % (errDict['code'],&lt;BR /&gt;errDict['message'])&lt;BR /&gt;raise SystemExit(message)&lt;BR /&gt;token = responseJSON.get('token')&lt;BR /&gt;return token&lt;/P&gt;&lt;P&gt;print('...Connecting to ' + portalUrl)&lt;BR /&gt;token = generateToken(username,password, serverUrl)&lt;BR /&gt;print('...Adding users ')&lt;/P&gt;</description>
    <pubDate>Fri, 23 Feb 2024 18:11:43 GMT</pubDate>
    <dc:creator>SGTomlins</dc:creator>
    <dc:date>2024-02-23T18:11:43Z</dc:date>
    <item>
      <title>Create users and roles from a CSV file</title>
      <link>https://community.esri.com/t5/arcgis-api-for-python-questions/create-users-and-roles-from-a-csv-file/m-p/1337432#M9137</link>
      <description>&lt;P&gt;I am trying to work through the code example to bulk add users with csv on this page:&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;A href="https://enterprise.arcgis.com/en/server/10.8/administer/windows/example-create-users-and-roles-from-a-csv-file.htm" target="_blank"&gt;https://enterprise.arcgis.com/en/server/10.8/administer/windows/example-create-users-and-roles-from-a-csv-file.htm&lt;/A&gt;&lt;/P&gt;&lt;P&gt;The code has not been updated from python 2 to python 3 and I am getting stuck on this error message:&amp;nbsp;&lt;/P&gt;&lt;P&gt;gaierror: [Errno 11001] getaddrinfo failed&lt;/P&gt;&lt;P&gt;The code is below as well&lt;/P&gt;&lt;LI-CODE lang="python"&gt;# This script creates a bank of users and roles given a comma-separated text file
#  They should be listed in the following format and saved in a file with a .txt extension:
#
#  User,Role,RoleType,Password,EMail,FullName,Description
#  John,Admins,ADMINISTER,changeme,johndoe@esri.com,John Doe,Server admin
#  Jane,Publishers,PUBLISH,changeme,janedoe@esri.com,Jane Doe,Server publisher
#  Etc.

import json, urllib,httplib

# For system tools
import sys

# For reading passwords without echoing
import getpass


def main(argv=None):
    # Ask for admin/publisher user name and password
    username = raw_input("Enter user name: ")
    password = getpass.getpass("Enter password: ")

    # Ask for server name &amp;amp; port
    serverName = raw_input("Enter server name: ")
    serverPort = 6080

    # Input File with the Role and user information
    inFile = raw_input("Path to comma-delimited text file containing users and roles: ")

    # InFile = r"C:\testing\agsUsersRoles.txt"
    opnFile = open(inFile,'r')

    # Dictionaries to store user and role information
    roles = {}
    users = {}   
    addUserRole = {}

    # Read the next line 
    ln = opnFile.readline()

    # Counter to get through the column header of the input file
    num = 0
    while ln:
        if num == 0:
            pass # File header
        else:
            # Split the current line into list
            lnSplt = ln.split(",")
            
            # Build the Dictionary to add the roles
            roles[lnSplt[1]] = {lnSplt[2]:lnSplt[len(lnSplt) -1].rstrip()}
           
            # Add the user information to a dictionary
            users["user" + str(num)] = {"username":lnSplt[0],"password":lnSplt[3],"fullname":lnSplt[5],"email":lnSplt[4],"description":lnSplt[-1].rstrip()}

            # Store the user and role type in a dictionary
            if addUserRole.has_key(lnSplt[1]):
                addUserRole[lnSplt[1]] =  addUserRole[lnSplt[1]] + "," + lnSplt[0]
            else:
                addUserRole[lnSplt[1]] = lnSplt[0]

        # Prepare to move to the next line        
        ln = opnFile.readline()
        num +=1

    # Get a token and connect
    token = getToken(username, password,serverName,serverPort)
    if token == "":
            sys.exit(1)

    # Call helper functions to add users and roles
    addRoles(roles, token,serverName,serverPort)
    addUsers(users,token,serverName,serverPort)
    addUserToRoles(addUserRole,token,serverName,serverPort)


def addRoles(roleDict, token, serverName, serverPort):
    
    for item in roleDict.keys():
        # Build the dictionary with the role name and description
        roleToAdd = {"rolename":item}

        # Load the response
        jsRole = json.dumps(roleToAdd)
        
        # URL for adding a role
        addroleURL = "/arcgis/admin/security/roles/add"
        params = urllib.urlencode({'token':token,'f':'json','Role':jsRole})
        headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}

        # Build the connection to add the roles to the server
        httpRoleConn = httplib.HTTPConnection(serverName, serverPort)
        httpRoleConn.request("POST",addroleURL,params,headers)

        response = httpRoleConn.getresponse()
        if (response.status != 200):
            httpRoleConn.close()
            print "Could not add role."
            return
        else:
            data = response.read()
            
            # Check that data returned is not an error object
            if not assertJsonSuccess(data):          
                print "Error when adding role. " + str(data)
                return
            else:
                print "Added role successfully"

        httpRoleConn.close()

        # Assign a privilege to the recently added role 
        assignAdminUrl = "/arcgis/admin/security/roles/assignPrivilege"
        params = urllib.urlencode({'token':token,'f':'json',"rolename":item, "privilege":roleDict[item].keys()[0]})
            
        headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}

        # Build the connection to assign the privilege
        httpRoleAdminConn = httplib.HTTPConnection(serverName, serverPort)
        httpRoleAdminConn.request("POST",assignAdminUrl,params,headers)

        response = httpRoleAdminConn.getresponse()
        if (response.status != 200):
            httpRoleAdminConn.close()
            print "Could not assign privilege to role."
            return
        else:
            data = response.read()
            
            # Check that data returned is not an error object
            if not assertJsonSuccess(data):          
                print "Error when assigning privileges to role. " + str(data)
                return
            else:
                print "Assigned privileges to role successfully"

        httpRoleAdminConn.close()


def addUsers(userDict,token, serverName, serverPort):

    for userAdd in userDict:
        jsUser = json.dumps(userDict[userAdd])
        
        # URL for adding a user
        addUserURL = "/arcgis/admin/security/users/add"
        params = urllib.urlencode({'token':token,'f':'json','user':jsUser})
        headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}

        # Build the connection to add the users
        httpRoleConn = httplib.HTTPConnection(serverName, serverPort)
        httpRoleConn.request("POST",addUserURL,params,headers)


        httpRoleConn.close()
       

def addUserToRoles(userRoleDict,token, serverName, serverPort):
    for userRole in userRoleDict.keys():

        # Using the current role build the URL to assign the right users to the role
        addUserURL = "/arcgis/admin/security/roles/addUsersToRole"
        params = urllib.urlencode({'token':token,'f':'json',"rolename":userRole,"users":userRoleDict[userRole]})
        headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
    
        # Build the connection
        httpRoleConn = httplib.HTTPConnection(serverName, serverPort)
        httpRoleConn.request("POST",addUserURL,params,headers)

        response = httpRoleConn.getresponse()
        if (response.status != 200):
            httpRoleConn.close()
            print "Could not add user to role."
            return
        else:
            data = response.read()
            
            # Check that data returned is not an error object
            if not assertJsonSuccess(data):          
                print "Error when adding user to role. " + str(data)
                return
            else:
                print "Added user to role successfully"
                    
        httpRoleConn.close()
        

def getToken(username, password, serverName, serverPort):
    # Token URL is typically http://server[:port]/arcgis/admin/generateToken
    tokenURL = "/arcgis/admin/generateToken"
    
    params = urllib.urlencode({'username': username, 'password': password,'client': 'requestip', 'f': 'json'})
    
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
    
    # Connect to URL and post parameters
    httpConn = httplib.HTTPConnection(serverName, serverPort)
    httpConn.request("POST", tokenURL, params, headers)
    
    # Read response
    response = httpConn.getresponse()
    if (response.status != 200):
        httpConn.close()
        print "Error while fetching tokens from admin URL. Please check the URL and try again."
        return
    else:
        data = response.read()
        httpConn.close()
        
        # Check that data returned is not an error object
        if not assertJsonSuccess(data):            
            return
        
        # Extract the token from it
        token = json.loads(data)        
        return token['token']            
        

# A function that checks that the input JSON object 
#  is not an error object.   
def assertJsonSuccess(data):
    obj = json.loads(data)
    if 'status' in obj and obj['status'] == "error":
        print "Error: JSON object returns an error. " + str(obj)
        return False
    else:
        return True

# Script start 
if __name__ == "__main__":
    sys.exit(main(sys.argv[1:]))&lt;/LI-CODE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 12 Oct 2023 18:39:09 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-api-for-python-questions/create-users-and-roles-from-a-csv-file/m-p/1337432#M9137</guid>
      <dc:creator>chill_gis_dude</dc:creator>
      <dc:date>2023-10-12T18:39:09Z</dc:date>
    </item>
    <item>
      <title>Re: Create users and roles from a CSV file</title>
      <link>https://community.esri.com/t5/arcgis-api-for-python-questions/create-users-and-roles-from-a-csv-file/m-p/1340107#M9174</link>
      <description>&lt;P&gt;Hey George,&lt;/P&gt;&lt;P&gt;For what version of Enterprise is this for? The documentation is for version 10.8.1 so this might be where we are hitting the error.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The following&lt;A href="https://developers.arcgis.com/python/guide/accessing-and-managing-users/" target="_self"&gt; sample&lt;/A&gt; might be more useful if you are using a version later than 10.8.1.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Hope that helps,&lt;/P&gt;&lt;P&gt;David&lt;/P&gt;</description>
      <pubDate>Fri, 20 Oct 2023 16:34:42 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-api-for-python-questions/create-users-and-roles-from-a-csv-file/m-p/1340107#M9174</guid>
      <dc:creator>David_McRitchie</dc:creator>
      <dc:date>2023-10-20T16:34:42Z</dc:date>
    </item>
    <item>
      <title>Re: Create users and roles from a CSV file</title>
      <link>https://community.esri.com/t5/arcgis-api-for-python-questions/create-users-and-roles-from-a-csv-file/m-p/1386180#M9677</link>
      <description>&lt;P&gt;I hacked this to work with 3.7....&amp;nbsp;&lt;/P&gt;&lt;P&gt;Now I get the follwing error... &lt;span class="lia-unicode-emoji" title=":disappointed_face:"&gt;😞&lt;/span&gt;&lt;/P&gt;&lt;P&gt;fumbling thru an example... i am..&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;File "C:\SGT\ESRI\Python\ArcGIS Enterprise\AddUserToEntPortal-fumblethru.py", line 58, in generateToken&lt;BR /&gt;if responseJSON.has_key('error'):&lt;BR /&gt;AttributeError: 'dict' object has no attribute 'has_key'&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;# Requires Python 2.7+&lt;/P&gt;&lt;P&gt;# Demonstrates how to add users to the ArcGIS Enterprise portal in bulk&lt;/P&gt;&lt;P&gt;# For Http calls&lt;BR /&gt;import urllib3, urllib, json&lt;BR /&gt;import urllib.parse&lt;BR /&gt;import urllib.response&lt;BR /&gt;from urllib.request import urlopen&lt;/P&gt;&lt;P&gt;&lt;BR /&gt;from notebook.notebookapp import raw_input&lt;/P&gt;&lt;P&gt;# This function connects to the portal and adds members to it from a collection&lt;BR /&gt;# def createUsers(username,password, portalUrl, provider,userParamsQ):&lt;BR /&gt;# ## these are the tinkerbell-az server credentials: DEVELOPMENT server&lt;BR /&gt;username = "sitdg5g45634min"&lt;BR /&gt;password = "fdghfdghfdghfdghfdghv"&lt;BR /&gt;portalUrl = "&lt;A href="https://tinkerbell-az.ci.janesville.wi.us/devportal" target="_blank"&gt;https://tinkerbell-az.ci.janesville.wi.us/devportal&lt;/A&gt;"&lt;BR /&gt;serverUrl = "&lt;A href="https://tinkerbell-az.ci.janesville.wi.us/devserver/admin" target="_blank"&gt;https://tinkerbell-az.ci.janesville.wi.us/devserver/admin&lt;/A&gt;"&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;# This function gets a token from the portal&lt;BR /&gt;#def generateToken(username, password, serverUrl, json_obj=None):&lt;BR /&gt;def generateToken(username, password, serverUrl):&lt;BR /&gt;parameters = urllib.parse.urlencode({'username' : username,&lt;BR /&gt;'password' : password,&lt;BR /&gt;'client' : 'referer',&lt;BR /&gt;'referer': portalUrl,&lt;BR /&gt;'expiration': 600,&lt;BR /&gt;'f' : 'json'})&lt;BR /&gt;pmans = parameters.encode('utf-8')&lt;BR /&gt;try:&lt;BR /&gt;#response = urllib3.urlopen(portalUrl + '/sharing/rest/generateToken?', parameters).read()&lt;BR /&gt;response = urllib.request.urlopen(serverUrl + '/generateToken?', pmans)&lt;BR /&gt;#response = urllib.request.urlopen(serverUrl + '/generateToken?', pmans).read()&lt;BR /&gt;responsestring = response.read().decode('utf-8')&lt;BR /&gt;json_obj = json.loads(responsestring)&lt;BR /&gt;#print('this is the response :' + json_obj)&lt;/P&gt;&lt;P&gt;except Exception as e:&lt;BR /&gt;#raise SystemExit( 'Unable to open the url %s/sharing/rest/generateToken' % (portalUrl))&lt;BR /&gt;raise SystemExit('Unable to open the url %s/' % (serverUrl))&lt;BR /&gt;# responseJSON = json.loads(response.strip(' \t\n\r'))&lt;/P&gt;&lt;P&gt;responseJSON = json.loads(responsestring)&lt;/P&gt;&lt;P&gt;#content = json.loads(r.decode('utf-8').replace('\n', ''))&lt;/P&gt;&lt;P&gt;# Log results&lt;BR /&gt;if responseJSON.has_key('error'):&lt;BR /&gt;errDict = responseJSON['error']&lt;BR /&gt;if int(errDict['code'])==498:&lt;BR /&gt;message = 'Token Expired. Getting new token... '&lt;BR /&gt;token = generateToken(username,password, serverUrl)&lt;BR /&gt;else:&lt;BR /&gt;message = 'Error Code: %s \n Message: %s' % (errDict['code'],&lt;BR /&gt;errDict['message'])&lt;BR /&gt;raise SystemExit(message)&lt;BR /&gt;token = responseJSON.get('token')&lt;BR /&gt;return token&lt;/P&gt;&lt;P&gt;print('...Connecting to ' + portalUrl)&lt;BR /&gt;token = generateToken(username,password, serverUrl)&lt;BR /&gt;print('...Adding users ')&lt;/P&gt;</description>
      <pubDate>Fri, 23 Feb 2024 18:11:43 GMT</pubDate>
      <guid>https://community.esri.com/t5/arcgis-api-for-python-questions/create-users-and-roles-from-a-csv-file/m-p/1386180#M9677</guid>
      <dc:creator>SGTomlins</dc:creator>
      <dc:date>2024-02-23T18:11:43Z</dc:date>
    </item>
  </channel>
</rss>

