For partner solutions that need to manage ABRA Flexi instances in the cloud, there is a batch API. It is given a list of operations on users and companies, and a single server executes them all at once, ensuring consistency.
⚠️ The status of this API is currently beta, and the document also describes the planned state. Please thoroughly verify everything on a test environment before use.
Authenticating requests to ABRA Flexi
ABRA Flexi supports several methods of so-called server authorization:
Method | Where it can be used |
Server username and password | Only for self-hosted installations — not usable in the cloud. |
Client certificate | Currently only in the cloud — not usable outside the cloud. |
Logged-in administrator | Anywhere, but only on versioned paths and limited to their own license groups. |
Server username and password
For this type of authorization, you need to modify /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>
The username and password will be accepted after the server restarts.
🚨 The password must be at least 15 characters long and will grant access to all data on the given installation. Store it securely.
Client certificate
A more secure approach is to use a certificate — it can be used to authorize for administrator access. You must use the HTTPS protocol for communication and connect on port 7000. Only the certificate fingerprint (SHA1 fingerprint) is stored on the server.
You can obtain the certificate fingerprint as follows:
openssl x509 -noout -in cert.pem -fingerprint
This fingerprint needs to be sent to support and will be set on the given instance, or on the instance tree (their grouping), respectively.
Logged-in administrator
On the versioned paths /v2/admin/batch and /v3/admin/batch, the batch API can also be used by a regularly logged-in user who has the rights manageAll and licenseMgmt.
ℹ️ Unlike server authorization, such a user is limited to the license groups they have access to — an item targeting a foreign license group will end with the status FAILED. The non-versioned path /admin/batch remains reserved for server authorization.
User impersonation
In some cases, it is necessary for the server to log in and then act as one of the users. This can be done by adding the header:
X-FlexiBee-Authorization: jmeno
From that moment on, all changes, including permissions, will be made under this user.
API usage scenarios
The entire ABRA Flexi REST API always operates on a single database containing a company's data. The exception is user and company management — this is separated from the company and stored differently. In a standard installation, user information is in the centralServer database, while companies are in individual databases. In cloud operation, the information is stored in a highly replicated CouchDB database.
If processing were done across multiple requests, it could happen that when assigning user rights within a company, the serving server would not know that the company or user had already been created. That is why this batch API was created.
💡 Because a request may fail — for example, due to temporary unavailability of one of the components — it can be retried. In that case, everything is executed again; changes that have already been made are skipped, as operations are idempotent.
Creating an administrator account and default accounting company
When an ADMIN account is created, a default accounting company is also created based on the order details. A company cannot be created without an administrator user.
<?xml version="1.0"?>
<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ČO -->
<type>PODNIKATELE</type>
<adminUser role="ADMIN">admin</adminUser>
</company>
</flexibee-batch>
Standard user roles
ADMINSUPERUZIVATELMZDOVYUCETNIUCETNIOBCHODNIKSKLADNIKSKLADNIKSPOKLADNOUUZIVATELJENCISTZABLOKOVAN
Organization type and accounting method
Double-entry bookkeeping is the default for all organization types.
Value | Meaning |
| Businesses. |
| Businesses using double-entry bookkeeping. |
| Businesses using tax records (single-entry bookkeeping). |
| Budgetary organizations. |
| Non-profit organizations. |
| Slovakia only. |
Supported hash functions for storing passwords
Function | Note |
| Default for storing passwords sent in plain form. |
| — |
| — |
| — |
| The most secure but also the slowest method — it is intentionally slow, making it impractical for the REST API without using a session. |
The password hash is calculated from the string salt + ":" + heslo and written as a lowercase hexadecimal string. Calculation example:
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 "regular" users
These users are created by the tenant administrator from the Admin Portal. This can also be called in bulk for multiple users when a profile changes.
<?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á</familyName>
<defaultRole>UZIVATEL</defaultRole>
<permissions>
<manageAll>true</manageAll>
</permissions>
</user>
</flexibee-batch>
🚨 A password can be stored without salt as well, but this is strongly discouraged.
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 releases the license. This can also be called in bulk for multiple users when a profile changes.
<?xml version="1.0"?>
<flexibee-batch id="abc-12345">
<user action="delete">
<username>anna.mlada</username>
</user>
</flexibee-batch>
If a user was deleted and you later recreate them using the create-update action, they 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>
ℹ️ When create-update a user, the system first tries to recycle records marked as "deleted". All access and role settings will be preserved.
Blocking an existing user
A blocked 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
This corresponds to adding the atomic role "ERP Administrator" in the Admin Portal. This can also be called in bulk for multiple users.
<?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
<?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 an existing user's first and last name
<?xml version="1.0"?>
<flexibee-batch id="abc-123456789">
<user action="create-update">
<username>anna.mlada</username>
<givenName>Anička</givenName>
<familyName>Starší</familyName>
</user>
</flexibee-batch>
Hiding and showing a company (disconnecting)
<?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>
The same can also be done outside the batch API — see disconnecting and reconnecting a company.
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
The following description applies to the first published test version with functional user creation in the central database.
Calling
The batch is sent using the PUT method to the address https://server:7000/admin/batch, and the request must be authorized using one of the methods described above. The request body is the batch XML:
PUT https://server:7000/admin/batch
Content-Type: application/xml
<obsah souboru batch.xml>
When using client certificate authorization, the certificate is attached to the TLS connection; with server authorization, the server username and password are sent in the Authorization header.
Sample request
Contents of the file 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á</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"><!-- 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>
</flexibee-batch>
Response
On success (200), XML is returned in the following format — each item in the batch has its own entry with a status:
<?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>
⚠️ A 200 status for the entire batch does not mean that all items succeeded. Always read the result from the individual entry entries — they may also carry SKIPPED or FAILED.
