ソースを参照

Merge branch 'issue/699' into 'develop'

[#699] add worker to clean expired oauth tokens

See merge request pleroma/pleroma!1184
tags/v1.1.4
lambda 5年前
コミット
83ca12f45e
8個のファイルの変更132行の追加21行の削除
  1. +1
    -0
      CHANGELOG.md
  2. +3
    -1
      config/config.exs
  3. +2
    -0
      docs/config.md
  4. +1
    -0
      lib/pleroma/application.ex
  5. +16
    -20
      lib/pleroma/web/oauth/token.ex
  6. +41
    -0
      lib/pleroma/web/oauth/token/clean_worker.ex
  7. +55
    -0
      lib/pleroma/web/oauth/token/query.ex
  8. +13
    -0
      test/web/oauth/token_test.exs

+ 1
- 0
CHANGELOG.md ファイルの表示

@@ -41,6 +41,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- OAuth: added support for refresh tokens
- Emoji packs and emoji pack manager
- Object pruning (`mix pleroma.database prune_objects`)
- OAuth: added job to clean expired access tokens

### Changed
- **Breaking:** Configuration: move from Pleroma.Mailer to Pleroma.Emails.Mailer


+ 3
- 1
config/config.exs ファイルの表示

@@ -481,7 +481,9 @@ config :pleroma, Pleroma.ScheduledActivity,

config :pleroma, :oauth2,
token_expires_in: 600,
issue_new_refresh_token: true
issue_new_refresh_token: true,
clean_expired_tokens: false,
clean_expired_tokens_interval: 86_400_000

config :pleroma, :database, rum_enabled: false



+ 2
- 0
docs/config.md ファイルの表示

@@ -550,6 +550,8 @@ 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`.
* `clean_expired_tokens_interval` - Interval to run the job to clean expired tokens. Defaults to `86_400_000` (24 hours).

## :emoji
* `shortcode_globs`: Location of custom emoji files. `*` can be used as a wildcard. Example `["/emoji/custom/**/*.png"]`


+ 1
- 0
lib/pleroma/application.ex ファイルの表示

@@ -110,6 +110,7 @@ defmodule Pleroma.Application do
hackney_pool_children() ++
[
worker(Pleroma.Web.Federator.RetryQueue, []),
worker(Pleroma.Web.OAuth.Token.CleanWorker, []),
worker(Pleroma.Stats, []),
worker(Task, [&Pleroma.Web.Push.init/0], restart: :temporary, id: :web_push_init),
worker(Task, [&Pleroma.Web.Federator.init/0], restart: :temporary, id: :federator_init)


+ 16
- 20
lib/pleroma/web/oauth/token.ex ファイルの表示

@@ -5,7 +5,6 @@
defmodule Pleroma.Web.OAuth.Token do
use Ecto.Schema

import Ecto.Query
import Ecto.Changeset

alias Pleroma.Repo
@@ -13,6 +12,7 @@ defmodule Pleroma.Web.OAuth.Token do
alias Pleroma.Web.OAuth.App
alias Pleroma.Web.OAuth.Authorization
alias Pleroma.Web.OAuth.Token
alias Pleroma.Web.OAuth.Token.Query

@expires_in Pleroma.Config.get([:oauth2, :token_expires_in], 600)
@type t :: %__MODULE__{}
@@ -31,17 +31,17 @@ defmodule Pleroma.Web.OAuth.Token do
@doc "Gets token for app by access token"
@spec get_by_token(App.t(), String.t()) :: {:ok, t()} | {:error, :not_found}
def get_by_token(%App{id: app_id} = _app, token) do
from(t in __MODULE__, where: t.app_id == ^app_id and t.token == ^token)
Query.get_by_app(app_id)
|> Query.get_by_token(token)
|> Repo.find_resource()
end

@doc "Gets token for app by refresh token"
@spec get_by_refresh_token(App.t(), String.t()) :: {:ok, t()} | {:error, :not_found}
def get_by_refresh_token(%App{id: app_id} = _app, token) do
from(t in __MODULE__,
where: t.app_id == ^app_id and t.refresh_token == ^token,
preload: [:user]
)
Query.get_by_app(app_id)
|> Query.get_by_refresh_token(token)
|> Query.preload([:user])
|> Repo.find_resource()
end

@@ -97,29 +97,25 @@ defmodule Pleroma.Web.OAuth.Token do
end

def delete_user_tokens(%User{id: user_id}) do
from(
t in Token,
where: t.user_id == ^user_id
)
Query.get_by_user(user_id)
|> Repo.delete_all()
end

def delete_user_token(%User{id: user_id}, token_id) do
from(
t in Token,
where: t.user_id == ^user_id,
where: t.id == ^token_id
)
Query.get_by_user(user_id)
|> Query.get_by_id(token_id)
|> Repo.delete_all()
end

def delete_expired_tokens do
Query.get_expired_tokens()
|> Repo.delete_all()
end

def get_user_tokens(%User{id: user_id}) do
from(
t in Token,
where: t.user_id == ^user_id
)
Query.get_by_user(user_id)
|> Query.preload([:app])
|> Repo.all()
|> Repo.preload(:app)
end

def is_expired?(%__MODULE__{valid_until: valid_until}) do


+ 41
- 0
lib/pleroma/web/oauth/token/clean_worker.ex ファイルの表示

@@ -0,0 +1,41 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.Web.OAuth.Token.CleanWorker do
@moduledoc """
The module represents functions to clean an expired oauth tokens.
"""

# 10 seconds
@start_interval 10_000
@interval Pleroma.Config.get(
# 24 hours
[:oauth2, :clean_expired_tokens_interval],
86_400_000
)
@queue :background

alias Pleroma.Web.OAuth.Token

def start_link, do: GenServer.start_link(__MODULE__, nil)

def init(_) do
if Pleroma.Config.get([:oauth2, :clean_expired_tokens], false) do
Process.send_after(self(), :perform, @start_interval)
{:ok, nil}
else
:ignore
end
end

@doc false
def handle_info(:perform, state) do
Process.send_after(self(), :perform, @interval)
PleromaJobQueue.enqueue(@queue, __MODULE__, [:clean])
{:noreply, state}
end

# Job Worker Callbacks
def perform(:clean), do: Token.delete_expired_tokens()
end

+ 55
- 0
lib/pleroma/web/oauth/token/query.ex ファイルの表示

@@ -0,0 +1,55 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2018 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only

defmodule Pleroma.Web.OAuth.Token.Query do
@moduledoc """
Contains queries for OAuth Token.
"""

import Ecto.Query, only: [from: 2]

@type query :: Ecto.Queryable.t() | Token.t()

alias Pleroma.Web.OAuth.Token

@spec get_by_refresh_token(query, String.t()) :: query
def get_by_refresh_token(query \\ Token, refresh_token) do
from(q in query, where: q.refresh_token == ^refresh_token)
end

@spec get_by_token(query, String.t()) :: query
def get_by_token(query \\ Token, token) do
from(q in query, where: q.token == ^token)
end

@spec get_by_app(query, String.t()) :: query
def get_by_app(query \\ Token, app_id) do
from(q in query, where: q.app_id == ^app_id)
end

@spec get_by_id(query, String.t()) :: query
def get_by_id(query \\ Token, id) do
from(q in query, where: q.id == ^id)
end

@spec get_expired_tokens(query, DateTime.t() | nil) :: query
def get_expired_tokens(query \\ Token, date \\ nil) do
expired_date = date || Timex.now()
from(q in query, where: fragment("?", q.valid_until) < ^expired_date)
end

@spec get_by_user(query, String.t()) :: query
def get_by_user(query \\ Token, user_id) do
from(q in query, where: q.user_id == ^user_id)
end

@spec preload(query, any) :: query
def preload(query \\ Token, assoc_preload \\ [])

def preload(query, assoc_preload) when is_list(assoc_preload) do
from(q in query, preload: ^assoc_preload)
end

def preload(query, _assoc_preload), do: query
end

+ 13
- 0
test/web/oauth/token_test.exs ファイルの表示

@@ -69,4 +69,17 @@ defmodule Pleroma.Web.OAuth.TokenTest do

assert tokens == 2
end

test "deletes expired tokens" do
insert(:oauth_token, valid_until: Timex.shift(Timex.now(), days: -3))
insert(:oauth_token, valid_until: Timex.shift(Timex.now(), days: -3))
t3 = insert(:oauth_token)
t4 = insert(:oauth_token, valid_until: Timex.shift(Timex.now(), minutes: 10))
{tokens, _} = Token.delete_expired_tokens()
assert tokens == 2
available_tokens = Pleroma.Repo.all(Token)

token_ids = available_tokens |> Enum.map(& &1.id)
assert token_ids == [t3.id, t4.id]
end
end

読み込み中…
キャンセル
保存