No se puede actualizar el correo electrónico mediante API: error invalid_access

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.

Yo también estoy experimentando este problema y me pregunto si tiene algo que ver con el uso de un proveedor de OAuth para iniciar sesión, por lo que esta página específica está siendo bloqueada.

Lo más probable es que no sea el proveedor de OAuth, ya que las claves de API lo eludirán.

¿Podrías compartir el código de tu solicitud de API?

en 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)

Edición: un código muy similar para establecer grupos en usuarios, etc., funcionó, por lo que la combinación de clave/usuario (que es un usuario con privilegios de administrador) funciona.

Edición 2: Por lo que he visto navegando por el foro, supongo que esto debe hacerse directamente en la base de datos (o más bien, a través de la consola), lo cual es imposible para nosotros.

¿Alguna otra opinión al respecto? Mi impresión es que alguien con derechos de acceso de administrador debería poder establecer el correo electrónico de una persona.

¿En qué sentido? No creo que sea posible con la interfaz de usuario web existente, que define la API. Por lo tanto, no se puede hacer.

¿Te refieres a que la UX/API debería permitir establecer la dirección de correo electrónico de un usuario a lo que tú quieras. (No que creas que actualmente sea posible.)

Puedes iniciar un cambio (mediante la UX y, presumiblemente, la API) editando su perfil e ingresando la nueva dirección, pero no se cambiará hasta que hagan clic en el enlace de su correo electrónico. ¿Es eso suficiente? Si no lo es, tendrás que hacerlo desde la consola o mediante un plugin.

Exactamente.

Cada vez que ingreso algo en la interfaz de usuario para editar el correo electrónico (al que solo puedo acceder mediante la URL directa, es decir, https://<discourse>/u/<username>/preferences/email, ya que no hay ningún enlace en el perfil del usuario), aparece un mensaje indicando que no puedo hacer esto después de hacer clic en “Cambiar”:

Y esto ocurre en mi propia cuenta como administrador. No recibo ningún correo electrónico.

También he llegado a este punto…

@pfaffman: mencionaste que es posible cambiar la dirección de correo electrónico en el perfil, pero eso requiere que email editable esté activado, ¿verdad?

He aprendido que no hay forma de que un administrador o una llamada a la API administrativa inicie un cambio de dirección de correo electrónico a menos que también se permita a los usuarios cambiar sus propias direcciones, ¿es así? Puedo perfectamente aceptar que se envíe un correo de confirmación y que el cambio deba ser autorizado por el usuario.

Mi caso de uso es que los usuarios se gestionarán desde otra aplicación a través de la API. Por lo tanto, no quiero que puedan cambiar sus direcciones de correo electrónico por sí mismos solo en Discourse.

¿Podrías implementar Inicio de sesión único y convertir tu otra aplicación en la fuente de inicios de sesión?

Existe una configuración específica de SSO llamada sso overrides email que hace exactamente lo que intentas lograr. Si tienes SSO configurado, puedes usar el endpoint sync_sso y pasar la nueva dirección de correo electrónico.

¡Gracias @blake, eso es un desafío pero divertido :wink:

Tendría que importar las contraseñas de Discourse al centro de identidad… oh, Dios mío.

Ayudé a mi escenario original con un proceso de tres pasos: habilitar la edición del correo electrónico, iniciar el cambio de dirección de correo electrónico y deshabilitar la edición del correo electrónico. Lo cual parece un poco excesivo, pero funciona.

Pensaré en el escenario de SSO.