SQL User Import

From Hornbill
Jump to navigation Jump to search

About the Hornbill SQL User Import Utility

The utility provides a simple, safe and secure way to create user accounts on the Hornbill platform by synchronizing with accounts held in your Database. The tool is designed to run behind your corporate firewall, connect to your database, query the required account information, transform and load into the Hornbill instance. The tool connects to the Hornbill instance in the cloud over HTTPS/SSL so as long as you have standard internet access then you should be able to use tool without the need to make any firewall configuration changes. The tool supports both the initial bulk import as well as incremental adds and updates. You can schedule the tool to run periodically to perform the import/update tasks as required.

Open Source

The SQL User Import Utility is provided open source under the Hornbill Community Licence and can be found here on GitHub

Installation Overview

Windows Installation

  • Download the latest package from GitHub
  • Extract zip into a folder you would like the application to run from e.g. C:\Hornbill_Import\
  • Open conf.json and add in the necessary configration
  • Open Command Line Prompt as Administrator
  • Change Directory to the folder with goDb2HUserImport_x86.exe C:\Hornbill_Import\
  • Run the command goDb2HUserImport_x86.exe -dryrun=true

Change "x86" to "amd64" depending on your architecture

Configuration Overview

Prior to configuring the .json file, it is advisable to read the following wiki page regarding Hornbill User Accounts as it will provide some context to the content on this page.

A default configuration file is provided conf.json, if a configuration file is not specified as a command line argument then conf.json must exist.

   {
   "APIKey": "", /* this is the API-key which is associated to a user in the Hornbill instance [1] */
   "InstanceId": "", /* your Hornbill instance name : not likely to change */
   "UpdateUserType": false, /* options : true/false ; whether the usertype (basic vs user) is updated on import */
   "UserRoleAction": "Create", /* options : Create/Update/Both ; on what action to assign roles to a user */
   "SQLConf": { /* db configuration : unlikely to change */
       "Driver": "mssql", /* options: mssql/mysql/swsql/mysql320/csv/excel ; what DB to connect to */
       "Server": "10.123.123.123", /* DB Server address */
       "Database": "HB", /* DB Name */
       "UserName": "Hornbill", /* DB Username */
       "Password": "password", /* DB Password */
       "Port": 1433, /* DB Server Port */
       "UserID": "winaccount", /* the FIELD name  */
       "Encrypt": false, /* options : true/false ; [2] */
       "Query": "SELECT department, division, emailaddress, ext, forenames, jobtitle, mgrstaffid, mgrfirstname, mgrlastname, portrait_url, staffid, subdivision, surname, winaccount FROM whatever_table" /* SQL Query to run [3] */
   },
   "UserMapping":{ /* mapping of fields in the format: "Field in Hornbill": "data to insert" [4] */
       "userId":"{{.winaccount}}",
       "UserType":"basic", /* usertype mentioned in comment on UpdateUserType */
       "Name":"{{.forenames}} {{.surname}}",
       "Password":"", /* if left blank a random 10-character password will be generated */
       "FirstName":"{{.forenames}}",
       "LastName":"{{.surname}}",
       "JobTitle":"{{.jobtitle}}",
       "Site":"", /* if set, see also comments below on SiteLookup */
       "Phone":"{{.ext}}",
       "Email":"{{.emailaddress}}",
       "Mobile":"",
       "AbsenceMessage":"",
       "TimeZone":"",
       "Language":"",
       "DateTimeFormat":"",
       "DateFormat":"",
       "TimeFormat":"",
       "CurrencySymbol":"",
       "CountryCode":""
   },
   "UserAccountStatus":{
       "Action":"Both", /* options : Create/Update/Both ; on what action to change the User Account Status */
       "Enabled": false, /* options : true/false ; turns on or off User Account Status  */
       "Status":"active" /* options : active/suspended/archived */
   },
   "UserProfileMapping":{ /* further fields [5]  */
       "MiddleName":"",
       "JobDescription":"",
       "Manager":"{{.mgrfirstname}} {{.mgrlastname}}", /* full name of manager. If set, see also comments below on UserManagerMapping */
       "WorkPhone":"",
       "Qualifications":"",
       "Interests":"",
       "Expertise":"",
       "Gender":"",
       "Dob":"",
       "Nationality":"",
       "Religion":"",
       "HomeTelephone":"",
       "SocialNetworkA":"",
       "SocialNetworkB":"",
       "SocialNetworkC":"",
       "SocialNetworkD":"",
       "SocialNetworkE":"",
       "SocialNetworkF":"",
       "SocialNetworkG":"",
       "SocialNetworkH":"",
       "PersonalInterests":"",
       "homeAddress":"",
       "PersonalBlog":"",
       "Attrib1":"",
           "Attrib2":"",
           "Attrib3":"",
           "Attrib4":"",
           "Attrib5":"",
           "Attrib6":"",
           "Attrib7":"",
           "Attrib8":"{{.staffid}}"
   },
   "UserManagerMapping":{
       "Action":"Both" /* options : Create/Update/Both ; on what action to change the User's Manager */
       , "Enabled":true /* options : true/false ; turn this on or off */
   },
   "Roles":[ /* list of Roles assigned to the users being imported */
       "Basic User Role"
   ],
   "SiteLookup":{
       "Action":"Both" /* options : Create/Update/Both ; on what action to change the User's Site */
       , "Enabled": true /* options : true/false ; turn this on or off */
   }
   , "ImageLink":{
       "Action":"Both" /* options : Create/Update/Both ; on what action to change the Image */
       , "Enabled": true /* options : true/false ; turn this on or off */
       , "UploadType": "URL"
       , "ImageType": "jpg" /* options : jpg/png */
       , "URI": "{{.portrait_url}}"
   }
   , "OrgLookup":{
       "Action":"Both" /* options : Create/Update/Both ; on what action to add to the organisational structure */
       , "Enabled":true /* options : true/false ; turn this on or off */
       , "OrgUnits":[ /* Organisational Units to associate the imported user with [6] */
           {
               "Attribute":"{{.department}}", /* name of organisational unit */
               "Type":2, /* options : 0,...,5 ; type of organisational unit, respectively: general/team/department/costcenter/division/company */
               "Membership":"member", /* options : member/teamLeader/manager */
               "TasksView":false, /* options : true/false ; If set true, then the user can view tasks assigned to this group */
               "TasksAction":false /* options : true/false ; If set true, then the user can action tasks assigned to this group */
           }, {
               "Attribute":"Great Company",
               "Type":5,
               "Membership":"member",
               "TasksView":false,
               "TasksAction":false
           }, {
               "Attribute":"{{.division}}",
               "Type":4,
               "Membership":"member",
               "TasksView":false,
               "TasksAction":false
           }
       ]
   }
   }


  1. An API key is set up against a user within Hornbill (accessed through: Administration > System > Organisationl Data > Users).
  2. specify whether the connection between the script and the database should be encrypted. NOTE: There is a bug in SQL Server 2008 and below that causes the connection to fail if the connection is encrypted. Only set this to true if your SQL Server has been patched accordingly
  3. please note that all field names are specificied as lowercase - this is to ensure smooth running for the mapped fields (as they are case-sensitive). Also, by specifying each field in use, one is following SQL best practice as it prevents unnecessary/unused data to be stored and processed (longvarchar and blob fields, for instance, take up a lot of memory). For CSV please use UPPERCASE for all field names and, also, do NOT use spaces in the headers (fieldnames).
  4. The fields are quite self-explanatory and part of the "Details"-section (as opposed to the "About"-section [5]), most can be left as-is. The mapping is done with some templating of the format {{fieldname}}. One can be a little adventurous, for instance "{{.mgrfirstname}} - {{.mgrlastname}}" puts a space, hyphen and space between the person's manager's first and last name. One can use this to prefix or suffix the values coming from the database or indeed to set a static value (as done for example with userType and Attribute under OrgLookup for the company (Type:5)).
  5. The same holds here as for [4], this is regarding the "About"-section of the user's details.
  6. this is a non-ordered list of the organisation structure - it allows one to associate the imported user to one or more levels within the organisation. The delivered configuration file will associate each imported user with EACH of the three discernable levels (company, department and division) - depending on your requirements regarding the availability of services and such, you will likely want to manipulate this section and perhaps only leave behind the "department" level (Type: 2) with the TasksView and TasksAction set accordingly. Please note that this import only adds and not REMOVES any association.

Command Line Parameters

  • file - Defaults to conf.json - Name of the Configuration file to load
  • dryrun - Defaults to false - Set to True and the XMLMC for Create and Update users will not be called and instead the XML will be dumped to the log file, this is to aid in debugging the initial connection information.
  • zone - Defaults to eur - Allows you to change the ZONE used for creating the XMLMC EndPoint URL https://{ZONE}api.hornbill.com/{INSTANCE}/
  • workers - Defaults to `3` - Allows you to change the number of worker threads used to process the import, this can improve performance on slow import but using too many workers have a detriment to performance of your Hornbill instance.

Testing Overview

If you run the application with the argument dryrun=true then no users will be created or updated, the XML used to create or update will be saved in the log file so you can ensure the LDAP mappings are correct before running the import.

goDb2HUserImport.exe -dryrun=true

Logging Overview

All Logging output is saved in the "log" directory which can be found in the same location as the executable. The file name contains the date and time the import was run SQL_User_Import_2015-11-06T14-26-13Z.log

Trouble Shooting

Common Error Messages

Below are some common errors that you may encounter in the log file and what they mean:

  • [ERROR] Error Decoding Configuration File:..... - this will be typically due to a missing quote (") or comma (,) somewhere in the configuration file. This is where an online JSON viewer/validator can come in handy rather than trawling the conf file looking for that proverbial needle in a haystack.
  • [ERROR] Get https://api.github.com/repos/hornbill/goSQL2HUserImport/tags: dial tcp xx.xx.xx.xx:xxx: ........ - this most likely indicates that you have a HTTP proxy server on your network between the host running the executable and your Hornbill API endpoint. Ensure the http_proxy environment variable is set (See the section on "HTTP Proxies" for more information) and that the proxy is configured to allow this communication.
  • [ERROR] Unable to Create User: Invalid value for parameter '[parameter name]': The text size provided (31 characters) is greater than the maximum allowable size of 20 characters for column [column name] - the contents of your directory attribute exceed the maximum number of characters that can be placed in the Hornbill database column.
  • [ERROR] Unable to Create User: The value in element <userId> did not meet the required input pattern constraints. at location '/methodCall/params/userId' - the user id contains characters that are not allowed. The User Id should be made up of alphanumeric characters. Full stops (.) and underscores (_) are also supported.
  • [ERROR] Unable to Update User: Invalid value for parameter '[parameter name]': Error setting value for column '[column name]'. bad lexical cast: source type value could not be interpreted as target - this error is indicating that the contents of your directory attribute are in a format that is not compatible with the type of the Hornbill database column. For example, you will get this when trying to place text into a database field that is of type "INT" (accepts integer values only).
  • [ERROR] Unable to Load LDAP Attribute: '[LDAP attribute name]' For Input Param: '[Hornbill Parameter name]' - When the import utility is unable to load a particular LDAP attribute, this means that the attribute field in your directory does not contain a value. This error will not prevent the user account being created or updated in Hornbill and can be considered more as a warning rather than an outright failure or problem.

Error Codes

  • 100 - Unable to create log File
  • 101 - Unable to create log folder
  • 102 - Unable to Load Configuration File

HTTP Proxies

If you use a proxy for all of your internet traffic, the HTTP_PROXY Environment variable needs to be set. The https_proxy environment variable holds the hostname or IP address of your proxy server. It is a standard environment variable and like any such variable, the specific steps you use to set it depends on your operating system.

For windows machines, it can be set from the command line using the following:
set HTTP_PROXY=HOST:PORT
Where "HOST" is the IP address or host name of your Proxy Server and "PORT" is the specific port number.

Scheduling Overview

Windows

You can schedule .exe to run with any optional command line argument from Windows Task Scheduler.

  • Ensure the user account running the task has rights to ldap_import.exe and the containing folder.
  • Make sure the Start In parameter contains the folder where the executable resides in, otherwise it will not be able to pick up the correct path. eg:

Ldap import schedule.png


Required Permissions

Default Role

As of Server Release 2494 a default role User Import is delivered which has all the necessary rights to import / update users. The exception to this is any roles you try and assign to users being imported must be assigned to the user account logging in and running the import, this is due to a security measure that prevents you inflating your own rights or giving a user more rights than you have yourself.


The following rights are required by any user account being used to run the User Import tool.

System Rights

Group A (Accounts)

  • Manage Users
  • Create Users
  • Update Users

Screen Shot 2016-02-26 at 07.59.50.png

Table Rights

h_sys_accounts

  • Browse
  • Add
  • Update

Screen Shot 2016-02-26 at 08.00.02.png

h_sys_sites

  • Browse

Screen Shot 2016-02-26 at 08.00.24.png

h_sys_roles

  • Browse

Screen Shot 2016-03-01 at 14.48.42.png

h_sys_accounts_roles

  • Browse
  • Add

Screen Shot 2016-03-02 at 10.00.30.png