Cant update email via API - invalid_access error

Hi Guys,

Im getting an error when trying to use the API to update email.
I have looked at the logs and can see the following:

Started PUT “/discussion/users/davetest/preferences/email.json” for xx.xx.xx.xx at 2018-05-11 12:22:11 +0000

Processing by UsersEmailController#update as JSON

Parameters: {“api_key”=>;"[FILTERED]", “api_username”=>;“daveAdmin”, “email”=>;“[new.email@example.com](mailto:new.email@example.com)”, “username”=>;“davetest”}

Can’t verify CSRF token authenticity.

This is a PUT request, but looking at the scopes below, doesnt seem like PUT is supported for the WRITE scope? surely im misunderstanding, so could someone please assist?

I have re-generated the all-user api-key, also created specific user api-keys to use, but same result.

SCOPES = {
read: [:get],
write: [:get, :post, :patch],
message_bus: [[:post, ‘message_bus’]],
push: nil,
notifications: [[:post, ‘message_bus’], [:get, ‘notifications#index’], [:put, ‘notifications#mark_read’]],
session_info: [[:get, ‘session#current’], [:get, ‘users#topic_tracking_state’]]
}

Can you verify the content-type that you are making the API request as? It needs to be

"Content-Type: multipart/form-data;"

If it is not that content type you may see the CSRF token error.

Hi, thanks for the reply.
I actually had tried it both with ‘application/json’ and ‘application/x-www-form-urlencoded’ and neither worked. I have now tried it with what you suggested (via postman) and getting:

“You are not permitted to view the requested resource. The API username or key is invalid.”

I have regenerated the global api key that is used for “all users” and using it with my own username, which is an admin too…

shahid

Here is an example of my postman request maybe you can spot any differences with what you are doing? I’m also using the “all users” key with an admin username.

yes, its the same, im using the Postman API collection supplied by discourse. So using it as suggested. I will try again tonight and see if i get any different results. Will update when ive tried. Thanks for assisting, much appreciated. Do let me know if you have any other idea.

У меня тоже возникает эта проблема, и я wondering, не связано ли это с использованием OAuth-провайдера для входа, из-за чего именно эта страница блокируется?

Скорее всего, дело не в провайдере OAuth, так как API-ключи обходят его.

Можете ли вы поделиться кодом вашего запроса к API?

в Python:

import json
import requests
import time

my_token = ''

url_base = '<>'
update_email = url_base + "users/<my_username>/preferences/email.json"

headers = {
    "Content-Type": "multipart/form-data",
    'user-agent': 'my-app/0.0.1',
    'Api-Key': my_token,
    'Api-Username': '<my_username>'
}

data = {
  "email": "<new_email>"
}

response = requests.put(update_email, data=data, headers=headers)

print(response.text)

Редактирование: очень похожий код для настройки групп пользователей и т. д. работал, поэтому комбинация ключа и имени пользователя (которая представляет собой пользователя с правами администратора) работает.

Редактирование 2: Судя по другим обсуждениям на форуме, это нужно делать напрямую в базе данных (а точнее, через консоль), что для нас невозможно.

Есть ли ещё какие-то соображения по этому поводу? Мне кажется, что человек с правами администратора должен иметь возможность установить адрес электронной почты другого пользователя.

Как так? Я не думаю, что это возможно с помощью существующего веб-интерфейса, который определяет API. Следовательно, это нельзя сделать.

Вы имеете в виду, что UX/API должны позволять устанавливать адрес электронной почты пользователя на любой желаемый. (Не то, что вы считаете, что это сейчас возможно.)

Вы можете инициировать изменение (через UX и, полагаю, API), отредактировав профиль и введя новый адрес, но он не будет изменён, пока пользователь не нажмёт ссылку в полученном письме. Достаточно ли этого? Если нет, вам придётся сделать это через консоль или плагин.

Точно.

Всякий раз, когда я ввожу что-либо в UX для редактирования электронной почты (к чему у меня есть доступ только через прямой URL, т. е. https://<discourse>/u/<username>/preferences/email, так как ссылки в профиле пользователя нет), после нажатия кнопки «Изменить» появляется сообщение о том, что это невозможно:

Причём это происходит на моём собственном аккаунте администратора. Письмо мне не приходит.

Я тоже дошёл до этой точки…

@pfaffman: вы указали, что можно изменить адрес электронной почты в профиле, но для этого должно быть установлено значение email editable, верно?

Я узнал, что нет способа для администратора или вызова административного API инициировать изменение адреса электронной почты, если пользователи не имеют права менять свои адреса сами, так? Я вполне могу согласиться с тем, что будет отправлено письмо с подтверждением, и изменение должно быть авторизовано пользователем.

Мой случай использования таков: пользователи будут управляться в другом приложении через API. Поэтому я не хочу, чтобы они меняли свои адреса электронной почты самостоятельно, только в Discourse.

Могли бы вы реализовать Единый вход (SSO) и сделать ваше другое приложение источником данных для входа?

Существует специфическая настройка SSO sso overrides email, которая выполняет то, что вы пытаетесь реализовать. Если у вас настроен SSO, вы можете использовать endpoint sync_sso и передать туда новый адрес электронной почты.

Спасибо, @blake, это вызов, но забавный :wink:

Мне пришлось бы импортировать пароли из Discourse в центр идентификации… о боже.

Мой первоначальный сценарий был реализован в три шага: включить возможность редактирования email, инициировать изменение адреса email, отключить возможность редактирования email. Это кажется немного избыточным, но работает.

Подумаю над сценарием SSO.