> For the complete documentation index, see [llms.txt](https://apidocs.akinon.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://apidocs.akinon.com/omnitron/integration/migration/user-migration.md).

# User Migration

* If user passwords in the old system are encrypted using MD5, SHA1, or SHA256, you can migrate users using these algorithms.
* Otherwise, after users are migrated, they must create a new password using the **Forgot Password** option during their first login. In this case, get in touch with the Akinon team to receive assistance regarding the password\_algorithm value to be used in the upcoming steps.
* Migrated users can be checked in the omnitron panel under **Sales Channel > Users** section.
* Unencrypted credentials of the test user undergoing migration will be needed for future checks.
* The user being imported must not have a record in Omnitron. The email field must be unique.

## <mark style="color:red;">Commerce ENV Settings</mark>

If the encryption algorithm is "md5," then the PASSWORD\_HASHERS list in the ENV should be updated as follows:

```

PASSWORD_HASHERS='django.contrib.auth.hashers.PBKDF2PasswordHasher','django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher','django.contrib.auth.hashers.Argon2PasswordHasher','django.contrib.auth.hashers.BCryptSHA256PasswordHasher','django.contrib.auth.hashers.BCryptPasswordHasher','django.contrib.auth.hashers.MD5PasswordHasher','django.contrib.auth.hashers.UnsaltedMD5PasswordHasher'

```

If the encryption algorithm is "sha1," then the PASSWORD\_HASHERS list in the ENV should be updated as follows:

```

PASSWORD_HASHERS='django.contrib.auth.hashers.PBKDF2PasswordHasher','django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher','django.contrib.auth.hashers.Argon2PasswordHasher','django.contrib.auth.hashers.BCryptSHA256PasswordHasher','django.contrib.auth.hashers.BCryptPasswordHasher','omnishop.users.helpers.SHA1MD5PasswordHasher','django.contrib.auth.hashers.SHA1PasswordHasher', ‘django.contrib.auth.hashers.UnsaltedSHA1PasswordHasher'

```

If the encryption algorithm is "sha256," then the PASSWORD\_HASHERS list in the ENV should be updated as follows:

```

PASSWORD_HASHERS='django.contrib.auth.hashers.PBKDF2PasswordHasher','django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher','django.contrib.auth.hashers.Argon2PasswordHasher','django.contrib.auth.hashers.BCryptSHA256PasswordHasher','django.contrib.auth.hashers.BCryptPasswordHasher','omnishop.users.helpers.SHA256PasswordHasher', ‘omnishop.users.helpers.SHA256UnsaltedPasswordHasher'

```

### Example Request

```
curl --location --request POST 'https://{{omnitron_url}}/api/v1/remote/{{channel_id}}/migrations/start/user/' \
--header 'Authorization: Token {{token}}' \
--form 'file=@"/path/to/test_user.json"'

```

#### **Test User File Format (test\_user.json)**

```json
[
    {
        "first_name": "Lorem",
        "last_name": "Ipsum",
        "email": "lorem.ipsum@mail.com",
        "gender": "male",
        "sms_allowed": false,
        "email_allowed": false,
        "phone": "999999999",
        "date_of_birth": "1990-01-13",
        "date_joined": "2022-01-13 09:26:00",
        "password": "sha1$salt$7c4a8d09ca3762af61e59520943ddc26494f8941b",
        "password_algorithm": "sha1",
        "customer_code": "1",
        "verified": true,
        "facebook_uuid": null,
        "attributes": {},
        "call_allowed": false,
        "user_type": "registered"
    }
]
```

**Description:**

The data format requirements for each field are as follows:

* **"first\_name"**: Should be in String format and is mandatory.
* **"last\_name"**: Should be in String format and is mandatory.
* **"email"**: Should be in Email format and is mandatory.
* **"gender"**: Should be in String format, can be null or an empty string. Acceptable values are 'male' or 'female'.
* **"sms\_allowed"**: Should be in Boolean format and is mandatory.
* **"email\_allowed"**: Should be in Boolean format and is mandatory.
* **"phone"**: Should be in the format "5XXXXXXXXX" as a string. Can be null. For foreign numbers, please seek assistance from the Akinon team.
* **"date\_of\_birth"**: Format is detailed in the date\_format section. Can be null.
* **"date\_joined"**: Format is detailed in the datetime\_format section and is mandatory.
* **"password"**: Format is detailed in the password section and is mandatory.
* **"password\_algorithm"**: Should be in String format. Acceptable values are 'sha1', 'md5', or 'sha256'. Mandatory.
* **"customer\_code"**: Should be in String format and is mandatory. After migration, this information will be stored in user.attributes.migration\_customer\_code.
* **"verified"**: Should be in Boolean format and is mandatory.
* **"facebook\_uuid"**: Should be in String format, can be null or an empty string.
* **"attributes"**: Should be in Dictionary format and is mandatory. If empty, it should be provided as {}.
* **"call\_allowed"**: Should be in Boolean format.
* **"user\_type"**: Should be in String format and is mandatory. Acceptable values are 'guest' or 'registered'.

**Date Format:**

The following formats are accepted as date\_format:

* '%Y-%m-%d'
* '%Y/%m/%d'
* '%d.%m.%Y'
* '%d-%m-%Y'
* '%d/%m/%Y'

**Password Format:**

It should be provided in the following format:\
`{algorithm}${salt}${hash_value}`

* **algorithm:** Can be `sha1`, `md5`, or `sha256`.
  * If **no salt** is used, the algorithm value must be set as `unsalted_sha256` instead of `sha256`.
  * Example:

    ```json
    "password": "unsalted_sha256$$02368e229cacd51bdd9c0284744dc049e7f1de06f0fd42529a98c931b5cd59a0",
    "password_algorithm": "sha256"
    ```
* **salt:** If unsalted, should be left empty.
* **hash\_value:** The hash value.

### Example Response

When a request is made using cURL, the response received will be as follows:

```
{"migration_id": "2740e84efe2e4bea91615f46f567aa3c"}
```

#### **Control**

For verification, the following request is sent:

```
curl --location --request GET 'https://{{omnitron_url}}/api/v1/remote/{{channel_id}}/migrations/{{migration_id}}/progress/' \  
--header 'Authorization: Token {{token}}'
```

If the response received is as follows:

```
{
    "total_count": 1,
    "error_count": 0,
    "processed_count": 1
}
```

The response means that the user has been successfully migrated.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://apidocs.akinon.com/omnitron/integration/migration/user-migration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
