Skip to main content

Batch Operations

Batch API - Server Administration

Written by Petr Pech

For partner solutions that need to manage ABRA Flexi instances in the cloud, we have prepared an API that makes this possible. It is currently in beta status and this document describes the planned state. Please verify everything thoroughly before use.

Authentication of Requests to ABRA Flexi

ABRA Flexi supports several methods of so-called server authorization:

  • server username and password – when a special username and password are provided, server authorization is accepted. This solution cannot be used in the cloud.

  • client certificate – allows us to have a certificate for each partner or instance that enables administration. This solution is not yet usable outside the cloud.

Server Username and Password

For this type of authorization, it is necessary to edit /etc/flexibee/server-auth.xml and add:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"><properties>  <comment>WinStrom server configuration</comment>  <entry key="username">winstrom-server-admin</entry>  <entry key="password">velmi-tajne-a-hodne-dlouhe-heslo</entry></properties>

After restarting the server, the username and password will be accepted.

Note: the password must be at least 15 characters long. This password will grant access to all data on the given installation. Store it securely!

Client Certificate

A more secure method is to use a certificate. It can be used to authorize and obtain administrator access. Communication must use the HTTPS protocol and connect on port 7000. Only the certificate fingerprint (SHA1 fingerprint) is stored on the server.

The certificate fingerprint can be obtained as follows:

openssl x509 -noout -in cert.pem -fingerprint

This fingerprint must be sent to support and will be configured for the given instance or tree of instances (their grouping).

User Impersonation

In some cases, it is necessary for the server to log in and then act on behalf of one of the users.

This can be done by adding the header:

X-FlexiBee-Authorization: jmeno.

From that point on, all changes, including permissions, will be performed under that user.

API Usage Scenarios

The entire ABRA Flexi REST API always operates on a single company data database. The exception is user and company management. This is extracted from the company and stored differently. In a standard installation, user information is stored in the centralServer database. Companies are stored in individual databases. In the case of cloud operation, the information is stored in a highly replicated CouchDB database.

If processing were done across multiple requests, it is possible that when assigning user permissions to a company, the handling server would not know that the company or user has already been created. This is why this batch API was developed — a list of operations is submitted and executed by a single server, ensuring consistency.

Because a request may fail (for example, due to the temporary unavailability of one of the components), the request can be retried. Everything will then be executed again as specified. If a change has already been made, the operation will be skipped (operations are idempotent).

Creating an ABRA Flexi Instance Administrator Account and Default Accounting Company

When an ADMIN account is created in ABRA Flexi, a default accounting company will be created based on the order details (we will have the company name and registration number).

It is not possible to create a company without an administrator user.

<flexibee-batch id="abc-1"> 
<user action="create-update">
<username>admin</username>
<password hash="sha256" salt=”123”>f86vs6vds66</password>
<email>admin@firma.cz</email>
<givenName>Roman</givenName>
<familyName>Skamene</familyName>
<ssoIdentifier>admin@firma.cz</ssoIdentifier>
<defaultRole>ADMIN</defaultRole>
<permissions>
<manageAll>true</manageAll>
<createCompany>false</createCompany>
<deleteCompany>false</deleteCompany>
<createUser>false</createUser>
<changePassword>false</changePassword>
<grantPermission>false</grantPermission>
<licenseManagement>false</licenseManagement>
</permissions>
</user>
<company action="create-update">
<id>digitalni_media_s_r_o_</id>
<name>Digitalní media s.r.o.</name>
<country>CZ</country>
<regNo>966664322</regNo><!-- IČ -->
<type>PODNIKATELE</type>
<adminUser role="ADMIN">admin</adminUser>
</company>
</flexibee-batch>

Standard User Roles in ABRA Flexi

  • ADMIN

  • SUPERUZIVATEL

  • MZDOVYUCETNI

  • UCETNI

  • OBCHODNIK

  • SKLADNIK

  • SKLADNIKSPOKLADNOU

  • UZIVATEL

  • JENCIST

  • ZABLOKOVAN

Organization Type + Accounting Method

Double-entry bookkeeping is the default for all organization types.

  • PODNIKATELE

  • PODNIKATELE+PU (double-entry bookkeeping)

  • PODNIKATELE+DE (tax records)

  • ROZPOCTOVE

  • NEZISKOVE

  • PODNIKATELIA (Slovakia only)

Supported Hash Functions for Password Storage

  • sha256 (default for storing passwords sent in plain text)

  • sha512

  • sha1

  • md5

  • pbkdf2 (the most secure but also the slowest method – without using sessions with the REST API it becomes unusable – it is intentionally too slow).

A sample program for calculating the password fingerprint for ABRA Flexi.

import org.apache.commons.codec.binary.Hex; public static final String SHA256 = "sha256"; public static final String SEPARATOR = ":"; protected static String encryptPasswordSHA256(String plain, String salt) { String toDigest = salt + SEPARATOR + plain; try { MessageDigest md = MessageDigest.getInstance("SHA-256"); byte[] result = md.digest(toDigest.getBytes("utf-8")); return SHA256 + SEPARATOR + salt + SEPARATOR + new String(Hex.encodeHex(result)); } catch (UnsupportedEncodingException e) { throw new RuntimeException(e); } catch (GeneralSecurityException e) { throw new RuntimeException(e); } } public static String getRandomSalt() { byte[] b = new byte[10]; new Random().nextBytes(b); return new String(Hex.encodeHex(b)).substring(10); } String plain = "moje heslo"; String result = encryptPasswordSHA256(plain, getRandomSalt());

Creating Additional "Standard" Users

These users will be created from the Admin Portal as new users by the tenant administrator. It will also be called in bulk for multiple users when changing a profile in the Admin Portal.

<?xml version="1.0"?><flexibee-batch id="abc-12">  <user action="create-update">    <username>anna.mlada</username>    <password hash="sha256" salt="123">f86vs6vds66</password>    <email>anna.mlada@firma.cz</email>    <givenName>Anna</givenName>    <familyName>Mlad&#xE1;</familyName>    <defaultRole>UZIVATEL</defaultRole>    <permissions>      <manageAll>true</manageAll>    </permissions>  </user></flexibee-batch>

It is also possible to store a password without a salt, but we strongly advise against it!

Changing an Existing User's Password

<?xml version="1.0"?><flexibee-batch id="abc-123">  <user action="create-update">    <username>anna.mlada</username>    <password hash="sha256" salt="123">f86vs6vds66</password>  </user></flexibee-batch>

Deleting an Existing User

Deleting a user from the Admin Portal = releasing a license. It will also be called in bulk for multiple users when changing a profile.

<?xml version="1.0"?><flexibee-batch id="abc-12345">  <user action="delete">    <username>anna.mlada</username>  </user></flexibee-batch>

Note: if a user was deleted and later a create-update is set, the user should be restored.

Restoring a User

<?xml version="1.0"?><flexibee-batch id="abc-123456">  <user action="create-update">    <username>anna.mlada</username>  </user></flexibee-batch>

Note: during a user create-update, records marked as "deleted" are first attempted to be recycled. All access settings and roles will be retained.

Blocking an Existing User

Blocking a user from the Admin Portal = the user cannot log in.

<?xml version="1.0"?><flexibee-batch id="abc-123456">  <user action="create-update">    <username>anna.mlada</username>    <blocked message="Blocked from external system">true</blocked>  </user></flexibee-batch>

Unblocking a User

<?xml version="1.0"?><flexibee-batch id="abc-123456">  <user action="create-update">    <username>anna.mlada</username>    <blocked>false</blocked>  </user></flexibee-batch>

Adding the ADMIN Role to an Existing User

Adding the atomic role "ERP administrator" in the Admin Portal. Can also be called in bulk for multiple users when changing a profile in the Admin Portal.

<?xml version="1.0"?><flexibee-batch id="abc-1234567">  <user action="create-update">    <username>anna.mlada</username>    <defaultRole>ADMIN</defaultRole>  </user>  <access role="ADMIN"/></flexibee-batch>

Removing the ADMIN Role from an Existing User

Removing the atomic role "ERP administrator" in the Admin Portal. Can also be called in bulk for multiple users when changing a profile in the Admin Portal.

<?xml version="1.0"?><flexibee-batch id="abc-12345678">  <user action="create-update">    <username>anna.mlada</username>    <defaultRole>UZIVATEL</defaultRole>  </user>  <access role="UZIVATEL"/></flexibee-batch>

Changing the First Name and Last Name of an Existing User

<?xml version="1.0"?><flexibee-batch id="abc-123456789">  <user action="create-update">    <username>anna.mlada</username>    <givenName>Ani&#x10D;ka</givenName>    <familyName>Star&#x161;&#xED;</familyName>  </user></flexibee-batch>

Hiding / Showing a Company (Disconnection)

<?xml version="1.0"?><flexibee-batch id="abc-123">  <company action="create-update">    <id>digitalni_media_s_r_o_</id>    <show>false</show>    <!-- true pro zobrazení -->  </company></flexibee-batch>

Deleting a Company

<?xml version="1.0"?><flexibee-batch id="abc-123">  <company action="delete">    <id>digitalni_media_s_r_o_</id>  </company></flexibee-batch>

Using the API

Applicable to the first published test version with functional user creation in the central database.

Calling

The request must be authorized.

The XML request can be sent using curl as follows:

curl -3 'https://server:7000/admin/batch' -T batch.xml -E cert.pem

Sample Request

batch.xml

<?xml version="1.0"?><flexibee-batch id="abc-123">  <!-- ID by mělo unikátně označovat dávku -->  <user>    <username>anna.mlada</username>    <password hash="sha256" salt="xyz987">af123bd35</password>    <email>anna.mlada@firma.cz</email>    <givenName>Anna</givenName>    <familyName>Mlad&#xE1;</familyName>    <permissions>      <manageAll>true</manageAll>      <createCompany>true</createCompany>      <deleteCompany>true</deleteCompany>      <createUser>false</createUser>      <changePassword>false</changePassword>      <grantPermission>true</grantPermission>      <licenseManagement>false</licenseManagement>    </permissions>    <defaultRole>UZIVATEL</defaultRole>  </user>  <company action="create-update">    <!-- action="create-update" je výchozí akce -->    <id>moje_firma_s_r_o_</id>    <name>Moje Firma s.r.o.</name>    <country>CZ</country>    <!-- aktuálně podporované jsou CZ a SK -->    <regNo>123</regNo>    <!-- IČO -->    <vatId>CZ123</vatId>    <!-- DIČ -->    <type>PODNIKATELE</type>    <adminUser>anna.mlada</adminUser>  </company>  <company action="delete">    <id>demo_a_s_</id>  </company>  <access role="ADMIN">anna_mlada_s_r_o_</access>  <access role="UZIVATEL">moje_firma_s_r_o_</access>  <access>demo_a_s_</access>  <access role="ADMIN"/>  <access>demo_a_s_</access></flexibee-batch>

Response

On success (HTTP 200), XML is returned in the following format:

<?xml version="1.0" encoding="UTF-8"?><flexibee-batch-result id="abc-12345678">  <entry>    <id>moje_firma_s_r_o_</id>    <entity>COMPANY</entity>    <action>DELETE</action>    <result>      <status>SKIPPED</status>      <message>Not implemented yet.</message>    </result>  </entry>  <entry>    <id>anna.mlada@firma.cz</id>    <entity>USER</entity>    <action>CREATE_UPDATE</action>    <result>      <status>CREATED</status>    </result>  </entry></flexibee-batch-result>

Entity type enumeration

  • USER

  • COMPANY

  • ACCESS_LIST

Action type enumeration

  • CREATE_UPDATE

  • DELETE

Status code enumeration

  • CREATED

  • UPDATED

  • DELETED

  • FAILED (the reason for the error will be in the <message> element)

  • SKIPPED (may be supplemented with a <message> element)

Did this answer your question?