Проблемы с SSO и символом '~'

Всем привет,

Недавно я обнаружил, что если включить ‘~’ в био пользователя, то Discourse выдаёт ошибку base64decode. Он отлично справляется со всеми kinds других проблемных символов (пробелы, =, %, &), но почему-то не может обработать ‘~’.

Кто-нибудь ещё сталкивался с этой проблемой?

Первая мысль — возможно, у меня неверное кодирование, но я пока не смог разобраться.

Вот моя реализация кодирования на Python:

return_payload = base64.urlsafe_b64encode(parse.urlencode(params).encode())

Затем этот результат напрямую передаётся в параметр ‘sso’ в запросах (вместе со всей необходимой информацией):

resp = requests.post(
       ".../admin/users/sync_sso",
        data={'sso': return_payload, ...}
        headers={...}
)

Я обновил Discourse до последней версии (3.5.0.beta1-dev), но проблема сохраняется.

Заранее спасибо за любую помощь!

Это, вероятно, должно быть исправлено, но этот вопрос выше моей квалификации и компетенции. Но из чистого практического любопытства: зачем кому-то использовать тильду в био?

Хм, думаю, это разумный вопрос.

Я веду многоязычный форум, и в других культурах символ ‘~’ используется часто. Например, в корейском языке его часто ставят в конце предложения, чтобы смягчить тон, как в фразе: «Если у вас есть вопросы, дайте знать~».

Итак, это отчёт об ошибке, а не запрос в службу поддержки?

Разве это баг? Баг — это что-то, что сделано, но не работает. Здесь же скорее вопрос «сделано или нет», а если нет, то это уже #фича или вопрос поддержки.

Да, я думаю, что «Ошибка» подходит. Я уверен, что правильно кодирую его в base64, поэтому Discourse должен корректно его декодировать.

Думаю, это баг (при условии, что мы сможем его воспроизвести)

При более тщательном расследовании я действительно ошибся в кодировании.

Вот что в итоге получилось, на будущее:

return_payload = base64.b64encode(parse.urlencode(kwargs).encode("utf-8"))
h = hmac.new(secret.encode("utf-8"), return_payload, digestmod=hashlib.sha256)
resp = requests.post(
       ".../admin/users/sync_sso",
        data={"sso": return_payload, "sig": h.hexdigest()}
        headers={...}
)

И если вы делаете редирект, обязательно выполните parse.urlencode для {“sso”…}.

Спасибо за помощь @sam и @david!