Merge branch 'develop' into oembed_provider

This commit is contained in:
raeno 2018-12-19 22:39:44 +04:00
commit 7fb3780431
30 changed files with 169 additions and 42 deletions

View file

@ -13,6 +13,7 @@ cache:
key: ${CI_COMMIT_REF_SLUG} key: ${CI_COMMIT_REF_SLUG}
paths: paths:
- deps - deps
- _build
stages: stages:
- lint - lint
- test - test
@ -21,6 +22,7 @@ before_script:
- mix local.hex --force - mix local.hex --force
- mix local.rebar --force - mix local.rebar --force
- mix deps.get - mix deps.get
- mix compile --force
- MIX_ENV=test mix ecto.create - MIX_ENV=test mix ecto.create
- MIX_ENV=test mix ecto.migrate - MIX_ENV=test mix ecto.migrate

View file

@ -0,0 +1,6 @@
<component name="libraryTable">
<library name="gen_smtp" type="mix">
<CLASSES />
<SOURCES />
</library>
</component>

View file

@ -0,0 +1,6 @@
<component name="libraryTable">
<library name="html_entities" type="mix">
<CLASSES />
<SOURCES />
</library>
</component>

View file

@ -0,0 +1,8 @@
<component name="libraryTable">
<library name="plug_cowboy" type="mix">
<CLASSES />
<SOURCES>
<root url="file://$PROJECT_DIR$/deps/plug_cowboy/lib" />
</SOURCES>
</library>
</component>

View file

@ -0,0 +1,8 @@
<component name="libraryTable">
<library name="plug_crypto" type="mix">
<CLASSES />
<SOURCES>
<root url="file://$PROJECT_DIR$/deps/plug_crypto/lib" />
</SOURCES>
</library>
</component>

View file

@ -0,0 +1,6 @@
<component name="libraryTable">
<library name="swoosh" type="mix">
<CLASSES />
<SOURCES />
</library>
</component>

View file

@ -137,8 +137,8 @@
logo_mask: true, logo_mask: true,
logo_margin: "0.1em", logo_margin: "0.1em",
background: "/static/aurora_borealis.jpg", background: "/static/aurora_borealis.jpg",
redirect_root_no_login: "/main/all", redirect_root_no_login: "/~/main/all",
redirect_root_login: "/main/friends", redirect_root_login: "/~/main/friends",
show_instance_panel: true, show_instance_panel: true,
scope_options_enabled: false, scope_options_enabled: false,
formatting_options_enabled: false, formatting_options_enabled: false,

View file

@ -175,3 +175,16 @@ the source code is here: https://github.com/koto-bank/kocaptcha. The default end
`https://captcha.kotobank.ch` is hosted by the developer. `https://captcha.kotobank.ch` is hosted by the developer.
* `endpoint`: the kocaptcha endpoint to use * `endpoint`: the kocaptcha endpoint to use
## :admin_token
Allows to set a token that can be used to authenticate with the admin api without using an actual user by giving it as the 'admin_token' parameter. Example:
```
config :pleroma, :admin_token, "somerandomtoken"
```
You can then do
```
curl "http://localhost:4000/api/pleroma/admin/invite_token?admin_token=somerandomtoken"
```

View file

@ -4,12 +4,12 @@ defmodule Pleroma.Formatter do
alias Pleroma.HTML alias Pleroma.HTML
alias Pleroma.Emoji alias Pleroma.Emoji
@tag_regex ~r/\#\w+/u @tag_regex ~r/((?<=[^&])|\A)(\#)(\w+)/u
@markdown_characters_regex ~r/(`|\*|_|{|}|[|]|\(|\)|#|\+|-|\.|!)/ @markdown_characters_regex ~r/(`|\*|_|{|}|[|]|\(|\)|#|\+|-|\.|!)/
def parse_tags(text, data \\ %{}) do def parse_tags(text, data \\ %{}) do
Regex.scan(@tag_regex, text) Regex.scan(@tag_regex, text)
|> Enum.map(fn ["#" <> tag = full_tag] -> {full_tag, String.downcase(tag)} end) |> Enum.map(fn ["#" <> tag = full_tag | _] -> {full_tag, String.downcase(tag)} end)
|> (fn map -> |> (fn map ->
if data["sensitive"] in [true, "True", "true", "1"], if data["sensitive"] in [true, "True", "true", "1"],
do: [{"#nsfw", "nsfw"}] ++ map, do: [{"#nsfw", "nsfw"}] ++ map,
@ -155,7 +155,7 @@ def add_hashtag_links({subs, text}, tags) do
uuid_text = uuid_text =
tags tags
|> Enum.reduce(text, fn {match, _short, uuid}, text -> |> Enum.reduce(text, fn {match, _short, uuid}, text ->
String.replace(text, match, uuid) String.replace(text, ~r/((?<=[^&])|(\A))#{match}/, uuid)
end) end)
subs = subs =

View file

@ -0,0 +1,25 @@
defmodule Pleroma.Plugs.AdminSecretAuthenticationPlug do
import Plug.Conn
alias Pleroma.User
def init(options) do
options
end
def secret_token do
Pleroma.Config.get(:admin_token)
end
def call(%{assigns: %{user: %User{}}} = conn, _), do: conn
def call(%{params: %{"admin_token" => admin_token}} = conn, _) do
if secret_token() && admin_token == secret_token() do
conn
|> assign(:user, %User{info: %{is_admin: true}})
else
conn
end
end
def call(conn, _), do: conn
end

View file

@ -38,6 +38,7 @@ defmodule Pleroma.Web.Router do
plug(Pleroma.Plugs.SessionAuthenticationPlug) plug(Pleroma.Plugs.SessionAuthenticationPlug)
plug(Pleroma.Plugs.LegacyAuthenticationPlug) plug(Pleroma.Plugs.LegacyAuthenticationPlug)
plug(Pleroma.Plugs.AuthenticationPlug) plug(Pleroma.Plugs.AuthenticationPlug)
plug(Pleroma.Plugs.AdminSecretAuthenticationPlug)
plug(Pleroma.Plugs.UserEnabledPlug) plug(Pleroma.Plugs.UserEnabledPlug)
plug(Pleroma.Plugs.SetUserSessionIdPlug) plug(Pleroma.Plugs.SetUserSessionIdPlug)
plug(Pleroma.Plugs.EnsureAuthenticatedPlug) plug(Pleroma.Plugs.EnsureAuthenticatedPlug)

View file

@ -1 +1 @@
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link rel=stylesheet href=/static/font/css/fontello.css><link rel=stylesheet href=/static/font/css/animation.css><link href=/static/css/app.ea00efb3229c8591fcc5249f0241b986.css rel=stylesheet></head><body style="display: none"><div id=app></div><script type=text/javascript src=/static/js/manifest.e076977b8e6c6844fb00.js></script><script type=text/javascript src=/static/js/vendor.cc4190750f6ed4d697bd.js></script><script type=text/javascript src=/static/js/app.67f548ecb9e9fd6b25b0.js></script></body></html> <!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link rel=stylesheet href=/static/font/css/fontello.css><link rel=stylesheet href=/static/font/css/animation.css><link href=/static/css/app.285fa56c62b811bbd37880f7e2656b13.css rel=stylesheet></head><body style="display: none"><div id=app></div><script type=text/javascript src=/static/js/manifest.60e190da7cc4cc4711dc.js></script><script type=text/javascript src=/static/js/vendor.48d4753220bd83360796.js></script><script type=text/javascript src=/static/js/app.6cb7378f44092df9536a.js></script></body></html>

View file

@ -4,8 +4,8 @@
"logo": "/static/logo.png", "logo": "/static/logo.png",
"logoMask": true, "logoMask": true,
"logoMargin": ".1em", "logoMargin": ".1em",
"redirectRootNoLogin": "/main/all", "redirectRootNoLogin": "/~/main/all",
"redirectRootLogin": "/main/friends", "redirectRootLogin": "/~/main/friends",
"chatDisabled": false, "chatDisabled": false,
"showInstanceSpecificPanel": false, "showInstanceSpecificPanel": false,
"scopeOptionsEnabled": false, "scopeOptionsEnabled": false,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,2 +1,2 @@
!function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var r=window.webpackJsonp;window.webpackJsonp=function(o,p){for(var c,l,s=0,i=[];s<o.length;s++)l=o[s],a[l]&&i.push.apply(i,a[l]),a[l]=0;for(c in p)Object.prototype.hasOwnProperty.call(p,c)&&(e[c]=p[c]);for(r&&r(o,p);i.length;)i.shift().call(null,t);if(p[0])return n[0]=0,t(0)};var n={},a={0:0};t.e=function(e,r){if(0===a[e])return r.call(null,t);if(void 0!==a[e])a[e].push(r);else{a[e]=[r];var n=document.getElementsByTagName("head")[0],o=document.createElement("script");o.type="text/javascript",o.charset="utf-8",o.async=!0,o.src=t.p+"static/js/"+e+"."+{1:"b578d16088622c18d886",2:"0220742f52d6912415d5"}[e]+".js",n.appendChild(o)}},t.m=e,t.c=n,t.p="/"}([]); !function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={exports:{},id:r,loaded:!1};return e[r].call(a.exports,a,a.exports,t),a.loaded=!0,a.exports}var r=window.webpackJsonp;window.webpackJsonp=function(o,p){for(var c,l,s=0,i=[];s<o.length;s++)l=o[s],a[l]&&i.push.apply(i,a[l]),a[l]=0;for(c in p)Object.prototype.hasOwnProperty.call(p,c)&&(e[c]=p[c]);for(r&&r(o,p);i.length;)i.shift().call(null,t);if(p[0])return n[0]=0,t(0)};var n={},a={0:0};t.e=function(e,r){if(0===a[e])return r.call(null,t);if(void 0!==a[e])a[e].push(r);else{a[e]=[r];var n=document.getElementsByTagName("head")[0],o=document.createElement("script");o.type="text/javascript",o.charset="utf-8",o.async=!0,o.src=t.p+"static/js/"+e+"."+{1:"48d4753220bd83360796",2:"6cb7378f44092df9536a"}[e]+".js",n.appendChild(o)}},t.m=e,t.c=n,t.p="/"}([]);
//# sourceMappingURL=manifest.f0b8300215e3fdbb725f.js.map //# sourceMappingURL=manifest.60e190da7cc4cc4711dc.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,4 +1,4 @@
var serviceWorkerOption = {"assets":["/static/img/nsfw.50fd83c.png","/static/js/manifest.f0b8300215e3fdbb725f.js","/static/js/vendor.b578d16088622c18d886.js","/static/js/app.0220742f52d6912415d5.js","/static/css/app.a37e07355ec1b0b45e84807615297c27.css"]}; var serviceWorkerOption = {"assets":["/static/img/nsfw.50fd83c.png","/static/js/manifest.60e190da7cc4cc4711dc.js","/static/js/vendor.48d4753220bd83360796.js","/static/js/app.6cb7378f44092df9536a.js","/static/css/app.285fa56c62b811bbd37880f7e2656b13.css"]};
!function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="/",t(0)}([function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(){return u.default.getItem("vuex-lz").then(function(e){return e.config.webPushNotifications})}function i(){return clients.matchAll({includeUncontrolled:!0}).then(function(e){return e.filter(function(e){var t=e.type;return"window"===t})})}var a=n(1),u=r(a);self.addEventListener("push",function(e){e.data&&e.waitUntil(o().then(function(t){return t&&i().then(function(t){var n=e.data.json();if(0===t.length)return self.registration.showNotification(n.title,n)})}))}),self.addEventListener("notificationclick",function(e){e.notification.close(),e.waitUntil(i().then(function(e){for(var t=0;t<e.length;t++){var n=e[t];if("/"===n.url&&"focus"in n)return n.focus()}if(clients.openWindow)return clients.openWindow("/")}))})},function(e,t){/*! !function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="/",t(0)}([function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function o(){return u.default.getItem("vuex-lz").then(function(e){return e.config.webPushNotifications})}function i(){return clients.matchAll({includeUncontrolled:!0}).then(function(e){return e.filter(function(e){var t=e.type;return"window"===t})})}var a=n(1),u=r(a);self.addEventListener("push",function(e){e.data&&e.waitUntil(o().then(function(t){return t&&i().then(function(t){var n=e.data.json();if(0===t.length)return self.registration.showNotification(n.title,n)})}))}),self.addEventListener("notificationclick",function(e){e.notification.close(),e.waitUntil(i().then(function(e){for(var t=0;t<e.length;t++){var n=e[t];if("/"===n.url&&"focus"in n)return n.focus()}if(clients.openWindow)return clients.openWindow("/")}))})},function(e,t){/*!
localForage -- Offline Storage, Improved localForage -- Offline Storage, Improved

View file

@ -22,6 +22,18 @@ test "turns hashtags into links" do
assert expected_text == assert expected_text ==
Formatter.add_hashtag_links({[], text}, tags) |> Formatter.finalize() Formatter.add_hashtag_links({[], text}, tags) |> Formatter.finalize()
end end
test "does not turn html characters to tags" do
text = "Fact #3: pleroma does what mastodon't"
expected_text =
"Fact <a data-tag='3' href='http://localhost:4001/tag/3' rel='tag'>#3</a>: pleroma does what mastodon't"
tags = Formatter.parse_tags(text)
assert expected_text ==
Formatter.add_hashtag_links({[], text}, tags) |> Formatter.finalize()
end
end end
describe ".add_links" do describe ".add_links" do

View file

@ -0,0 +1,38 @@
defmodule Pleroma.Plugs.AdminSecretAuthenticationPlugTest do
use Pleroma.Web.ConnCase, async: true
import Pleroma.Factory
alias Pleroma.Plugs.AdminSecretAuthenticationPlug
test "does nothing if a user is assigned", %{conn: conn} do
user = insert(:user)
conn =
conn
|> assign(:user, user)
ret_conn =
conn
|> AdminSecretAuthenticationPlug.call(%{})
assert conn == ret_conn
end
test "with secret set and given in the 'admin_token' parameter, it assigns an admin user", %{
conn: conn
} do
Pleroma.Config.put(:admin_token, "password123")
conn =
%{conn | params: %{"admin_token" => "wrong_password"}}
|> AdminSecretAuthenticationPlug.call(%{})
refute conn.assigns[:user]
conn =
%{conn | params: %{"admin_token" => "password123"}}
|> AdminSecretAuthenticationPlug.call(%{})
assert conn.assigns[:user].info.is_admin
end
end

View file

@ -1,6 +1,8 @@
defmodule Pleroma.Plugs.SetUserSessionIdPlugTest do defmodule Pleroma.Plugs.SetUserSessionIdPlugTest do
use Pleroma.Web.ConnCase, async: true use Pleroma.Web.ConnCase, async: true
Code.ensure_compiled(Pleroma.User)
alias Pleroma.Plugs.SetUserSessionIdPlug alias Pleroma.Plugs.SetUserSessionIdPlug
alias Pleroma.User alias Pleroma.User