Não é possível atualizar o e-mail via API – erro 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.

Estou enfrentando esse problema também e estou me perguntando se isso tem a ver com o uso de um provedor OAuth para fazer login e, portanto, se essa página específica está sendo bloqueada?

Muito provavelmente não é o provedor OAuth, pois as chaves de API o contornam.

Você poderia compartilhar o código da sua solicitação de API?

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

Edição: código muito semelhante para definir grupos em usuários, etc., funcionou, então a combinação de chave/nome de usuário (que é um usuário com privilégios de administrador) funciona.

Edição 2: Estou supondo, com base em outras navegações no fórum, que isso precise ser feito diretamente no banco de dados (ou melhor, via console), o que é impossível para nós.

Mais alguma opinião sobre isso? Minha impressão é que alguém com direitos de acesso de administrador deve poder definir o e-mail de uma pessoa.

Como assim? Não acho que isso seja possível com a interface web existente, que define a API. Portanto, não pode ser feito.

Você quer dizer que a UX/API deveria permitir definir o endereço de e-mail de um usuário para o que você quiser. (Não que você acredite que isso seja atualmente possível.)

Você pode iniciar uma alteração (via UX e, presumo, via API) editando o perfil do usuário e inserindo o novo endereço, mas a alteração só será efetivada quando ele clicar no link enviado por e-mail. Isso é suficiente? Se não for, você precisará fazer isso pelo console ou por meio de um plugin.

Exatamente.

Sempre que insiro algo na UX para editar o e-mail (ao qual só consigo acessar através da URL direta, ou seja, https://<discourse>/u/<username>/preferences/email, já que não há nenhum link no perfil do usuário), aparece uma mensagem informando que não posso fazer isso após clicar em “Alterar”:

E isso ocorre na minha própria conta, mesmo sendo administrador. Não recebo nenhum e-mail.

Cheguei a esse ponto também…

@pfaffman: você mencionou que é possível alterar o endereço de e-mail no perfil, mas isso exige que a opção email editable esteja ativada, não é?

Entendi que não há como um administrador ou uma chamada de API administrativa iniciar uma alteração no endereço de e-mail, a menos que os usuários também tenham permissão para alterar seus próprios e-mails, certo? Posso perfeitamente aceitar que um e-mail de confirmação seja enviado e que a alteração precise ser autorizada pelo usuário.

Meu caso de uso é que os usuários serão gerenciados em outro aplicativo via API. Portanto, não quero que eles alterem seus endereços de e-mail por conta própria apenas no Discourse.

Você poderia implementar Single Sign On e fazer com que seu outro aplicativo seja a fonte de logins?

Existe uma configuração específica de SSO chamada sso overrides email que faz exatamente o que você está tentando realizar. Se você tiver o SSO configurado, poderá usar o endpoint sync_sso e passar o novo endereço de e-mail.

Obrigado @blake, isso é desafiador, mas divertido :wink:

Eu teria que importar as senhas do Discourse para o hub de identidade… meu Deus.

Ajudei meu cenário original com um processo de três etapas: habilitar edição de e-mail, iniciar a alteração do endereço de e-mail, desabilitar edição de e-mail. O que parece um pouco exagerado, mas funciona.

Vou pensar no cenário de SSO.