Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Pleroma
pleroma
Commits
a2399c1c
Commit
a2399c1c
authored
Dec 15, 2018
by
vaartis
Browse files
Add base CAPTCHA support (currently only kocaptcha)
parent
e74f384b
Changes
6
Hide whitespace changes
Inline
Side-by-side
config/config.exs
View file @
a2399c1c
...
...
@@ -10,6 +10,13 @@
config
:pleroma
,
Pleroma
.
Repo
,
types:
Pleroma
.
PostgresTypes
config
:pleroma
,
Pleroma
.
Captcha
,
method:
Pleroma
.
Captcha
.
Kocaptcha
# Kocaptcha is a very simple captcha service, the source code is here: https://github.com/koto-bank/kocaptcha
config
:pleroma
,
Pleroma
.
Captcha
.
Kocaptcha
,
endpoint:
"http://localhost:9093"
# Upload configuration
config
:pleroma
,
Pleroma
.
Upload
,
uploader:
Pleroma
.
Uploaders
.
Local
,
...
...
lib/pleroma/application.ex
View file @
a2399c1c
...
...
@@ -24,6 +24,7 @@ def start(_type, _args) do
# Start the Ecto repository
supervisor
(
Pleroma
.
Repo
,
[]),
worker
(
Pleroma
.
Emoji
,
[]),
worker
(
Pleroma
.
Captcha
,
[]),
worker
(
Cachex
,
[
...
...
lib/pleroma/captcha.ex
0 → 100644
View file @
a2399c1c
defmodule
Pleroma
.
Captcha
do
use
GenServer
@ets
__MODULE__
.
Ets
@ets_options
[
:ordered_set
,
:private
,
:named_table
,
{
:read_concurrency
,
true
}]
@doc
false
def
start_link
()
do
GenServer
.
start_link
(
__MODULE__
,
[],
name:
__MODULE__
)
end
@doc
false
def
init
(
_
)
do
@ets
=
:ets
.
new
(
@ets
,
@ets_options
)
{
:ok
,
nil
}
end
def
new
()
do
GenServer
.
call
(
__MODULE__
,
:new
)
end
def
validate
(
token
,
captcha
)
do
GenServer
.
call
(
__MODULE__
,
{
:validate
,
token
,
captcha
})
end
@doc
false
def
handle_call
(
:new
,
_from
,
state
)
do
method
=
Pleroma
.
Config
.
get!
([
__MODULE__
,
:method
])
case
method
do
__MODULE__
.
Kocaptcha
->
endpoint
=
Pleroma
.
Config
.
get!
([
method
,
:endpoint
])
case
HTTPoison
.
get
(
endpoint
<>
"/new"
)
do
{
:error
,
_
}
->
%{
error:
"Kocaptcha service unavailable"
}
{
:ok
,
res
}
->
json_resp
=
Poison
.
decode!
(
res
.
body
)
token
=
json_resp
[
"token"
]
true
=
:ets
.
insert
(
@ets
,
{
token
,
json_resp
[
"md5"
]})
{
:reply
,
%{
type:
:kocaptcha
,
token:
token
,
url:
endpoint
<>
json_resp
[
"url"
]},
state
}
end
end
end
@doc
false
def
handle_call
({
:validate
,
token
,
captcha
},
_from
,
state
)
do
with
false
<-
is_nil
(
captcha
),
[{
^
token
,
saved_md5
}]
<-
:ets
.
lookup
(
@ets
,
token
),
true
<-
(
:crypto
.
hash
(
:md5
,
captcha
)
|>
Base
.
encode16
)
==
String
.
upcase
(
saved_md5
)
do
# Clear the saved value
:ets
.
delete
(
@ets
,
token
)
{
:reply
,
true
,
state
}
else
e
->
IO
.
inspect
(
e
);
{
:reply
,
false
,
state
}
end
end
end
lib/pleroma/web/router.ex
View file @
a2399c1c
...
...
@@ -99,6 +99,7 @@ defmodule Pleroma.Web.Router do
get
(
"/password_reset/:token"
,
UtilController
,
:show_password_reset
)
post
(
"/password_reset"
,
UtilController
,
:password_reset
)
get
(
"/emoji"
,
UtilController
,
:emoji
)
get
(
"/captcha"
,
UtilController
,
:captcha
)
end
scope
"/api/pleroma/admin"
,
Pleroma
.
Web
.
AdminAPI
do
...
...
lib/pleroma/web/twitter_api/controllers/util_controller.ex
View file @
a2399c1c
...
...
@@ -284,4 +284,8 @@ def delete_account(%{assigns: %{user: user}} = conn, params) do
json
(
conn
,
%{
error:
msg
})
end
end
def
captcha
(
conn
,
_params
)
do
json
(
conn
,
Pleroma
.
Captcha
.
new
())
end
end
lib/pleroma/web/twitter_api/twitter_api.ex
View file @
a2399c1c
...
...
@@ -132,38 +132,47 @@ def register_user(params) do
bio:
User
.
parse_bio
(
params
[
"bio"
]),
email:
params
[
"email"
],
password:
params
[
"password"
],
password_confirmation:
params
[
"confirm"
]
password_confirmation:
params
[
"confirm"
],
captcha_solution:
params
[
"captcha_solution"
],
captcha_token:
params
[
"captcha_token"
]
}
registrations_open
=
Pleroma
.
Config
.
get
([
:instance
,
:registrations_open
])
# Captcha invalid
if
not
Pleroma
.
Captcha
.
validate
(
params
[
:captcha_token
],
params
[
:captcha_solution
])
do
# I have no idea how this error handling works
{
:error
,
%{
error:
Jason
.
encode!
(%{
captcha:
[
"Invalid CAPTCHA"
]})}}
else
registrations_open
=
Pleroma
.
Config
.
get
([
:instance
,
:registrations_open
])
# no need to query DB if registration is open
token
=
unless
registrations_open
||
is_nil
(
tokenString
)
do
# no need to query DB if registration is open
token
=
unless
registrations_open
||
is_nil
(
tokenString
)
do
Repo
.
get_by
(
UserInviteToken
,
%{
token:
tokenString
})
end
cond
do
registrations_open
||
(
!is_nil
(
token
)
&&
!token
.
used
)
->
changeset
=
User
.
register_changeset
(%
User
{
info:
%{}},
params
)
cond
do
registrations_open
||
(
!is_nil
(
token
)
&&
!token
.
used
)
->
changeset
=
User
.
register_changeset
(%
User
{
info:
%{}},
params
)
with
{
:ok
,
user
}
<-
Repo
.
insert
(
changeset
)
do
!registrations_open
&&
UserInviteToken
.
mark_as_used
(
token
.
token
)
{
:ok
,
user
}
else
{
:error
,
changeset
}
->
errors
=
with
{
:ok
,
user
}
<-
Repo
.
insert
(
changeset
)
do
!registrations_open
&&
UserInviteToken
.
mark_as_used
(
token
.
token
)
{
:ok
,
user
}
else
{
:error
,
changeset
}
->
errors
=
Ecto
.
Changeset
.
traverse_errors
(
changeset
,
fn
{
msg
,
_opts
}
->
msg
end
)
|>
Jason
.
encode!
()
{
:error
,
%{
error:
errors
}}
end
end
!registrations_open
&&
is_nil
(
token
)
->
{
:error
,
"Invalid token"
}
!registrations_open
&&
is_nil
(
token
)
->
{
:error
,
"Invalid token"
}
!registrations_open
&&
token
.
used
->
{
:error
,
"Expired token"
}
!registrations_open
&&
token
.
used
->
{
:error
,
"Expired token"
}
end
end
end
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment