API создания пользователей: атрибут «active» установлен в True, но в ответе возвращается False

Всем привет,

Я использую Python для создания пользователей через API Discourse. Запрос на создание пользователя возвращает успешный ответ, но я сталкиваюсь с проблемой: атрибут active в ответе всегда равен false, хотя я явно устанавливаю его в true в полезной нагрузке. Атрибут confirmed установлен в true, и с ним всё работает корректно.

Вот код:

import csv
import requests
import json
from datetime import datetime

# Данные API Discourse
discourse_url = "https://forum.hobiguru.com/"  # Замените на ваш URL Discourse
api_key = "your-api-key"  # Замените на ваш ключ API Discourse
api_username = "system"  # Имя пользователя администратора

# Заголовки запроса
headers = {
    "Api-Key": api_key,
    "Api-Username": api_username,
    "Content-Type": "application/json"
}

# Функция для создания пользователя
def create_user(username, name, email, password, bio, location, confirmed, active, join_date):
    url = f"{discourse_url}/users.json"
    join_date_str = join_date.strftime('%Y-%m-%dT%H:%M:%SZ')

    payload = {
        "name": name,
        "email": email,
        "password": password,
        "username": username,
        "active": True,  # По умолчанию устанавливаем active в True
        "confirmed": True,  # По умолчанию устанавливаем confirmed в True
        "created_at": join_date_str
    }

    print(f"\nURL запроса: {url}")
    print(f"Заголовки запроса: {json.dumps(headers, indent=2)}")
    print(f"Полезная нагрузка запроса: {json.dumps(payload, indent=2)}")

    response = requests.post(url, json=payload, headers=headers)
    
    if response.status_code == 200:
        response_json = response.json()
        if response_json.get("success"):
            print(f"Успешное создание пользователя: {json.dumps(response_json, indent=2)}")
        else:
            print(f"Не удалось создать пользователя. Причина: {response_json.get('message')}")
            print(f"Ошибки: {json.dumps(response_json.get('errors'), indent=2)}")
    else:
        print(f"Запрос не выполнен: {response.status_code}, {response.text}")

# Чтение пользователей из CSV-файла
with open('input_users.csv', mode='r', encoding='utf-8') as file:
    reader = csv.DictReader(file)
    for row in reader:
        # Извлекаем данные пользователя из строки
        create_user(row['Username'], row['Name'], row['Email'], row['Password'], row['Bio'], row['Location'], row['Confirmed'] == 'TRUE', row['Active'] == 'TRUE', datetime.strptime(row['Join Date'], '%Y-%m-%dT%H:%M:%SZ'))

Вот что выводится:

 Запрос на создание пользователя

{'name': 'Goran', 'email': 'bla+blaaa@gmail.com', 'password': 'P@ssword!23', 'username': 'goran12', 'active': True, 'confirmed': True, 'created_at': '2024-11-04T10:20:34Z'}
URL запроса: https://forum.hobiguru.com/users.json
Заголовки запроса:
{
  "Api-Key": "d9---------------e564d65d9b5a3",
  "Api-Username": "system",
  "Content-Type": "application/json"
}
Полезная нагрузка запроса:
{
  "name": "Goran",
  "email": "'bla+blaaa@gmail.com",
  "password": "P@ssword!23",
  "username": "goran12",
  "active": true,
  "confirmed": true,
  "created_at": "2024-11-04T10:20:34Z"
}
Ответ:

Полный ответ: {
  "success": true,
  "active": false,
  "message": "Va\u0161 ra\u010dun je aktiviran i spreman za kori\u0161tenje."
}
Запрос выполнен успешно, пользователь создан:
{'success': True, 'active': False, 'message': 'Vaš račun je aktiviran i spreman za korištenje.'}

Проблема:

• Несмотря на передачу "active": True в полезной нагрузке, атрибут active в ответе всегда равен false. При просмотре пользователей в панели администратора Discourse я не могу найти их.

• API возвращает success: true, но пользователь, похоже, не полностью активирован.

Вопросы:

  1. Не упускаю ли я что-то в своём запросе, что может привести к неправильной установке атрибута active?

  2. Существуют ли в API Discourse какие-либо специфические условия, которые переопределяют атрибут active, даже если он явно установлен в true?

Буду очень признателен за любые разъяснения или советы!

Вы можете попробовать запустить этот скрипт один раз — возможно, это поможет. Вот он: Скрипт для создания тестовых пользователей вашего форума Discourse.

Кроме того, ваш скрипт, похоже, работает вполне хорошо, но проблема заключается в данных, которые вы используете в вашем CSV-файле.

Я протестировал ваш код, используя следующие примеры данных:

Username,Name,Email,Password,Bio,Location,Confirmed,Active,Join Date
Paul,Paul Paul,paul@example.com,tough001!@,This is Paul,Australia,TRUE,TRUE,2023-12-30T14:00:00Z
radhika01,Radhika Singh,singhradhika@example.com,tough001!@,This is Radhika Tomar,India,TRUE,TRUE,2023-12-30T14:00:00Z

У меня всё сработало без проблем. Несколько рекомендаций: используйте пароли длиной не менее 12 символов и убедитесь, что они надёжные.

Попробуйте и дайте знать, если это поможет вам :))

Привет, @MihirR

Большое спасибо за ваш ответ и помощь в решении этой проблемы! Я очень ценю это.

Я думаю, что нашел проблему. Дело было в адресах электронной почты, которые я использовал — конкретно, в адресах с плюсом (например, алиасы Gmail whatever+something@gmail.com, whatever+something2@gmail.com) для тестовых пользователей. Когда я использую email без плюса, всё работает отлично, и пользователь создается, как в вашем примере CSV. Однако при использовании email с плюсом API, похоже, не обрабатывает это корректно.

На скриншоте вы видите два вызова curl: один с плюсом в email, другой без…

Странно то, что при использовании плюса я не получаю ошибку. На самом деле я получаю успешный ответ, в котором говорится, что аккаунт создан и активирован, но это не так. Я проверил напрямую в консоли Rails и подключился к базе данных — пользователя там нет. Пользователь также не отображается в админ-панели Discourse.

Похоже, проблема в ответе API — он сообщает об успешном создании и активации (извините, текст на скриншоте на хорватском), но пользователь на самом деле никогда не создается в системе. Это указывает на то, что может быть проблема с тем, как API обрабатывает или сообщает о создании пользователя при использовании специальных символов (например, плюса) в адресе электронной почты.

Еще раз спасибо за вашу помощь, и я решил поделиться этим открытием с вами, на случай, если это поможет!

Как настроена параметр сайта normalize_emails на вашем экземпляре?

Кажется, на самом деле сообщается, что активация не удалась, если предположить, что это означает "active": false.

Ключ сообщения в ответе гласит: «Ваша учётная запись активирована и готова к использованию», что неверно.

Точно, это неверная часть всего этого. Параметр указывает active:false, а сообщение гласит: «Аккаунт активирован и готов к использованию»

Привет! В параметре ответа указано active:false, хотя в сообщении говорится: «Аккаунт активирован и готов к использованию».

Я пока не проверял, но проверю. Похоже, это было объявлено здесь: Enabling e-mail normalization by default


Да, похоже, что причиной сбоя был флаг normalize_email:true, который по умолчанию установлен в true. Как только я отключил его, пользователи начали создаваться… Однако API не учитывает флаг normalize_emails и возвращает статус успеха, даже если пользователь так и не был создан или активирован :confused: Стоит ли мне сообщить об этом в репозиторий Discourse на GitHub?

Или создать тему bug rest-api :slight_smile: