Merge branch 'email-stub-in-verify-credentials' into 'develop'
authorfeld <feld@feld.me>
Tue, 2 Feb 2021 18:35:08 +0000 (18:35 +0000)
committerfeld <feld@feld.me>
Tue, 2 Feb 2021 18:35:08 +0000 (18:35 +0000)
Email-like field in /api/v1/accounts/verify_credentials (for PeerTube OAuth plugin and alike)

See merge request pleroma/pleroma!3286

CHANGELOG.md
docs/configuration/auth.md [new file with mode: 0644]
docs/configuration/cheatsheet.md
lib/pleroma/user.ex
lib/pleroma/web/mastodon_api/views/account_view.ex
lib/pleroma/web/router.ex
lib/pleroma/web/templates/embed/show.html.eex
lib/pleroma/web/views/embed_view.ex
test/pleroma/user_test.exs
test/pleroma/web/mastodon_api/views/account_view_test.exs

index 59091fb1b3209fe9ec82d100335ca6d707418a05..dab24f5ad1de32d45e06541d52e6252dfcfd4b6a 100644 (file)
@@ -21,6 +21,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
 - Admin API: Reports now ordered by newest
 - Deprecated `Pleroma.Uploaders.S3, :public_endpoint`. Now `Pleroma.Upload, :base_url` is the standard configuration key for all uploaders.
 - Improved Apache webserver support: updated sample configuration, MediaProxy cache invalidation verified with the included sample script
+- Improve OAuth 2.0 provider support. A missing `fqn` field was added to the response, but does not expose the user's email address.
 
 ### Added
 
diff --git a/docs/configuration/auth.md b/docs/configuration/auth.md
new file mode 100644 (file)
index 0000000..c80f094
--- /dev/null
@@ -0,0 +1 @@
+See `Authentication` section of [the configuration cheatsheet](../configuration/cheatsheet.md#authentication).
index 9d4b07bf4061b9deda13e50501693e0c5bce36d4..ad57684656f3f1422bc0a7017f49249d3d2c32e7 100644 (file)
@@ -893,6 +893,22 @@ Pleroma account will be created with the same name as the LDAP user name.
 Note, if your LDAP server is an Active Directory server the correct value is commonly `uid: "cn"`, but if you use an
 OpenLDAP server the value may be `uid: "uid"`.
 
+### :oauth2 (Pleroma as OAuth 2.0 provider settings)
+
+OAuth 2.0 provider settings:
+
+* `token_expires_in` - The lifetime in seconds of the access token.
+* `issue_new_refresh_token` - Keeps old refresh token or generate new refresh token when to obtain an access token.
+* `clean_expired_tokens` - Enable a background job to clean expired oauth tokens. Defaults to `false`.
+
+OAuth 2.0 provider and related endpoints:
+
+* `POST /api/v1/apps` creates client app basing on provided params.
+* `GET/POST /oauth/authorize` renders/submits authorization form.
+* `POST /oauth/token` creates/renews OAuth token.
+* `POST /oauth/revoke` revokes provided OAuth token.
+* `GET /api/v1/accounts/verify_credentials` (with proper `Authorization` header or `access_token` URI param) returns user info on requester (with `acct` field containing local nickname and `fqn` field containing fully-qualified nickname which could generally be used as email stub for OAuth software that demands email field in identity endpoint response, like Peertube).
+
 ### OAuth consumer mode
 
 OAuth consumer mode allows sign in / sign up via external OAuth providers (e.g. Twitter, Facebook, Google, Microsoft, etc.).
@@ -965,14 +981,6 @@ config :ueberauth, Ueberauth,
   ]
 ```
 
-### OAuth 2.0 provider - :oauth2
-
-Configure OAuth 2 provider capabilities:
-
-* `token_expires_in` - The lifetime in seconds of the access token.
-* `issue_new_refresh_token` - Keeps old refresh token or generate new refresh token when to obtain an access token.
-* `clean_expired_tokens` - Enable a background job to clean expired oauth tokens. Defaults to `false`.
-
 ## Link parsing
 
 ### :uri_schemes
index 06cdb42af3becb1e645cb6a0038c16b4bf1ebf82..b69709db40e53304942dd34a318df0c92a8addd2 100644 (file)
@@ -2031,6 +2031,15 @@ defmodule Pleroma.User do
     |> hd()
   end
 
+  def full_nickname(%User{} = user) do
+    if String.contains?(user.nickname, "@") do
+      user.nickname
+    else
+      %{host: host} = URI.parse(user.ap_id)
+      user.nickname <> "@" <> host
+    end
+  end
+
   def full_nickname(nickname_or_mention),
     do: String.trim_leading(nickname_or_mention, "@")
 
index 63417142f79d6c256e907d7deb47dff8509e1c07..ac25aefdd6653850c4843e585aada9898d2b87e5 100644 (file)
@@ -262,7 +262,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do
         }
       },
 
-      # Pleroma extension
+      # Pleroma extensions
+      # Note: it's insecure to output :email but fully-qualified nickname may serve as safe stub
+      fqn: User.full_nickname(user),
       pleroma: %{
         ap_id: user.ap_id,
         also_known_as: user.also_known_as,
index 7521f5dc34fce8eeab5731a777e850f17188886f..2105d7e9ed2bbf842a97032d4a81e693c0ae2921 100644 (file)
@@ -320,6 +320,8 @@ defmodule Pleroma.Web.Router do
   end
 
   scope "/oauth", Pleroma.Web.OAuth do
+    # Note: use /api/v1/accounts/verify_credentials for userinfo of signed-in user
+
     get("/registration_details", OAuthController, :registration_details)
 
     post("/mfa/verify", MFAController, :verify, as: :mfa_verify)
index 05a3f0ee305acf26c0cc469ace6d0f8b7b82fee4..092b52b705350807f86089402a85ff772698c4d4 100644 (file)
@@ -6,7 +6,7 @@
       </div>
       <span class="display-name" style="padding-left: 0.5em;">
         <bdi><%= raw (@author.name |> Formatter.emojify(@author.emoji)) %></bdi>
-        <span class="nickname"><%= full_nickname(@author) %></span>
+        <span class="nickname">@<%= full_nickname(@author) %></span>
       </span>
     </a>
   </div>
index cb7600adbaf3f1952f05ed3ba01d22286dfe16a7..81e19673038d46e052378512ffcc71895dd5dd77 100644 (file)
@@ -17,6 +17,8 @@ defmodule Pleroma.Web.EmbedView do
 
   use Phoenix.HTML
 
+  defdelegate full_nickname(user), to: User
+
   @media_types ["image", "audio", "video"]
 
   defp fetch_media_type(%{"mediaType" => mediaType}) do
@@ -30,11 +32,6 @@ defmodule Pleroma.Web.EmbedView do
     )
   end
 
-  defp full_nickname(user) do
-    %{host: host} = URI.parse(user.ap_id)
-    "@" <> user.nickname <> "@" <> host
-  end
-
   defp status_title(%Activity{object: %Object{data: %{"name" => name}}}) when is_binary(name),
     do: name
 
index ae6fc4c0db5432384d0824ff2e06a6f8557e8f73..be39339f34724d798c4c37b851875408635907b3 100644 (file)
@@ -2232,6 +2232,36 @@ defmodule Pleroma.UserTest do
     end
   end
 
+  describe "local_nickname/1" do
+    test "returns nickname without host" do
+      assert User.local_nickname("@mentioned") == "mentioned"
+      assert User.local_nickname("a_local_nickname") == "a_local_nickname"
+      assert User.local_nickname("nickname@host.com") == "nickname"
+    end
+  end
+
+  describe "full_nickname/1" do
+    test "returns fully qualified nickname for local and remote users" do
+      local_user =
+        insert(:user, nickname: "local_user", ap_id: "https://somehost.com/users/local_user")
+
+      remote_user = insert(:user, nickname: "remote@host.com", local: false)
+
+      assert User.full_nickname(local_user) == "local_user@somehost.com"
+      assert User.full_nickname(remote_user) == "remote@host.com"
+    end
+
+    test "strips leading @ from mentions" do
+      assert User.full_nickname("@mentioned") == "mentioned"
+      assert User.full_nickname("@nickname@host.com") == "nickname@host.com"
+    end
+
+    test "does not modify nicknames" do
+      assert User.full_nickname("nickname") == "nickname"
+      assert User.full_nickname("nickname@host.com") == "nickname@host.com"
+    end
+  end
+
   test "avatar fallback" do
     user = insert(:user)
     assert User.avatar_url(user) =~ "/images/avi.png"
index 999bde474fd82df177cadc99632e58fde2e9f3a1..5373a17c38f84a0db34a20ef213e0812daadd7b3 100644 (file)
@@ -73,6 +73,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
         },
         fields: []
       },
+      fqn: "shp@shitposter.club",
       pleroma: %{
         ap_id: user.ap_id,
         also_known_as: ["https://shitposter.zone/users/shp"],
@@ -172,6 +173,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountViewTest do
         },
         fields: []
       },
+      fqn: "shp@shitposter.club",
       pleroma: %{
         ap_id: user.ap_id,
         also_known_as: [],