Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
birger
users
Commits
b96e5d24
Commit
b96e5d24
authored
Jul 27, 2018
by
o@immerda.ch
Browse files
improve error messages
parent
d2beb328
Changes
15
Hide whitespace changes
Inline
Side-by-side
app/controllers/app_passwords_controller.rb
View file @
b96e5d24
class
AppPasswordsController
<
ApplicationController
def
show
res
=
ApiBackend
::
app_passwords
(
current_user
)
if
res
&&
res
[
'result'
]
==
'success'
begin
res
=
ApiBackend
::
app_passwords
(
current_user
)
@passwords
=
res
[
'names'
]
if
session
[
:app_pw
]
@app_pw
=
session
[
:app_pw
]
session
[
:app_pw
]
=
nil
end
else
rescue
flash
[
:notice
]
=
:failed
redirect_to
'/'
end
end
def
edit
if
params
[
:app_name
]
res
=
ApiBackend
::
app_password_create
(
current_user
,
params
[
:password
],
params
[
:app_name
])
if
res
&&
res
[
'result'
]
==
'success'
begin
res
=
ApiBackend
::
app_password_create
(
current_user
,
params
[
:password
],
params
[
:app_name
])
session
[
:app_pw
]
=
res
[
'app_pw'
]
else
flash
[
:notice
]
=
:failed
rescue
=>
e
puts
e
.
inspect
if
e
.
api_msg
flash
[
:notice
]
=
e
.
api_msg
else
flash
[
:notice
]
=
:failed
end
end
elsif
params
[
:delete
]
ApiBackend
::
app_password_delete
(
current_user
,
params
[
:delete
])
begin
ApiBackend
::
app_password_delete
(
current_user
,
params
[
:delete
])
rescue
flash
[
:notice
]
=
:failed
end
else
flash
[
:notice
]
=
:failed
redirect_to
'/'
...
...
app/controllers/concerns/api_backend.rb
View file @
b96e5d24
require
'uri'
module
ApiBackend
class
ApiError
<
RuntimeError
attr_reader
:msg
,
:api_msg
def
initialize
(
msg
,
api_msg
=
nil
)
@msg
=
msg
@api_msg
=
api_msg
end
end
def
self
.
sanitize
(
parts
)
parts
.
map
{
|
v
|
URI
.
encode
(
v
)}.
join
(
"/"
)
end
...
...
@@ -13,9 +21,16 @@ module ApiBackend
:verify_ssl
=>
OpenSSL
::
SSL
::
VERIFY_PEER
)
begin
response
=
res
.
post
(
data
.
to_json
)
JSON
.
parse
(
response
)
rescue
false
res
=
JSON
.
parse
(
response
)
if
!
res
||
res
[
'result'
]
!=
"success"
puts
"Expected success from iapi, but got
#{
res
}
"
raise
ApiError
.
new
(
"blocked
#{
res
}
"
)
end
res
rescue
RestClient
::
BadRequest
=>
e
raise
ApiError
.
new
(
"400"
,
JSON
.
parse
(
e
.
response
)[
'errors'
])
rescue
=>
e
raise
ApiError
.
new
(
"
#{
e
}
"
)
end
end
...
...
@@ -27,21 +42,21 @@ module ApiBackend
:verify_ssl
=>
OpenSSL
::
SSL
::
VERIFY_PEER
)
begin
response
=
res
.
get
(
:params
=>
data
)
JSON
.
parse
(
response
)
rescue
false
res
=
JSON
.
parse
(
response
)
if
!
res
[
'result'
]
==
"success"
puts
"Expected success from iapi, but got
#{
res
}
"
raise
ApiError
.
new
(
"blocked
#{
res
}
"
)
end
res
rescue
RestClient
::
BadRequest
=>
e
raise
ApiError
.
new
(
"400"
,
JSON
.
parse
(
e
.
response
)[
'errors'
])
rescue
=>
e
raise
ApiError
.
new
(
"
#{
e
}
"
)
end
end
def
self
.
auth
(
user
,
pw
,
options
=
{})
email_regex
=
%r{^
[a-z0-9
\-\.
_]+
@
[0-9a-z]
[0-9a-z.
\-
]+
[0-9a-z]
$}xi
if
user
=~
email_regex
if
EmailValidation
::
immerda_email_conform
(
user
)
return
post
([
"authenticate"
],
options
.
merge
({
"email"
=>
user
,
"password"
=>
pw
}))
end
...
...
@@ -67,8 +82,8 @@ module ApiBackend
get
([
"info"
],
{
'id'
=>
id
})
end
def
self
.
new_email_token
_valid?
(
token
)
get
([
"check_
new_email_token
"
],
{
'token'
=>
token
})
def
self
.
invite
_valid?
(
token
)
get
([
"check_
invite
"
],
{
'token'
=>
token
})
end
def
self
.
valid_new_email?
(
email
)
...
...
@@ -80,7 +95,7 @@ module ApiBackend
end
def
self
.
list_domains
@domains
||=
get
([
"list_domains"
],
{})
@domains
||=
get
([
"list_domains"
],
{})
[
'domains'
]
end
def
self
.
change_password
(
user
,
old
,
pw
)
...
...
@@ -99,15 +114,15 @@ module ApiBackend
post
([
"set_recovery_email"
],
{
"email"
=>
email
,
"recovery_email"
=>
recovery
})
end
def
self
.
generate_
new_email_token
s
(
num
)
post
([
"generate_
new_email_token
s"
],
{
"number"
=>
num
})
def
self
.
generate_
invite
s
(
num
)
post
([
"generate_
invite
s"
],
{
"number"
=>
num
})
end
def
self
.
create_new_mailbox
(
email
,
pw
,
trees_enabled
,
new_email_token
,
recovery_email
,
keep_recovery_token
)
def
self
.
create_new_mailbox
(
email
,
pw
,
trees_enabled
,
invite
,
recovery_email
,
keep_recovery_token
)
post
([
"create_new_mailbox"
],
{
"email"
=>
email
,
"password"
=>
pw
,
"trees_enabled"
=>
trees_enabled
,
"
new_email_token"
=>
new_email_token
,
"
invite"
=>
invite
,
"recovery_email"
=>
recovery_email
,
"keep_recovery_token"
=>
keep_recovery_token
,
})
...
...
app/controllers/concerns/email_validation.rb
0 → 100644
View file @
b96e5d24
require
'resolv'
require
'uri'
module
EmailValidation
def
self
.
valid_email_host?
(
hostname
)
valid
=
true
begin
Resolv
::
DNS
.
new
.
getresource
(
hostname
,
Resolv
::
DNS
::
Resource
::
IN
::
MX
)
rescue
Resolv
::
ResolvError
begin
Resolv
::
DNS
.
new
.
getresource
(
hostname
,
Resolv
::
DNS
::
Resource
::
IN
::
A
)
rescue
Resolv
::
ResolvError
valid
=
false
end
end
return
valid
end
def
self
.
check_external_email
(
string
)
if
string
.
match
(
URI
::
MailTo
::
EMAIL_REGEXP
)
string
=~
/(.*)@([^@]+)$/
local
=
$1
domain
=
$2
if
valid_email_host?
(
domain
)
return
[
local
,
domain
]
end
end
false
end
def
self
.
immerda_email_conform
(
string
)
email_regex
=
%r{^
([a-z0-9
\-\.
_]+)
@
([0-9a-z]
[0-9a-z.
\-
]+
[0-9a-z])
$}xi
if
string
=~
email_regex
local
=
$1
domain
=
$2
[
local
,
domain
]
else
false
end
end
end
app/controllers/invites_controller.rb
View file @
b96e5d24
class
InvitesController
<
AdminController
def
show
if
params
[
'num_tokens'
]
res
=
ApiBackend
::
generate_new_email_tokens
(
params
[
'num_tokens'
])
if
res
&&
res
[
'result'
]
==
'success'
begin
res
=
ApiBackend
::
generate_invites
(
params
[
'num_tokens'
])
@tokens
=
res
[
'tokens'
]
rescue
flash
[
:notice
]
=
:failed
end
end
end
...
...
app/controllers/password_controller.rb
View file @
b96e5d24
...
...
@@ -9,9 +9,14 @@ class PasswordController < ApplicationController
redirect_to
'/password'
return
end
res
=
ApiBackend
::
change_password
(
current_user
,
params
[
'old'
],
params
[
'new'
])
if
!
res
||
res
[
'result'
]
!=
'success'
flash
[
:notice
]
=
:password_change_failed
begin
ApiBackend
::
change_password
(
current_user
,
params
[
'old'
],
params
[
'new'
])
rescue
=>
e
if
e
.
api_msg
==
'auth_fail'
flash
[
:notice
]
=
:auth_fail
else
flash
[
:notice
]
=
:password_change_failed
end
redirect_to
'/password'
return
end
...
...
app/controllers/recovery_email_controller.rb
View file @
b96e5d24
class
RecoveryEmailController
<
ApplicationController
def
show
if
params
[
:recovery_email
]
res
=
ApiBackend
::
set_recovery_email
(
current_user
,
params
[
:recovery_email
])
if
res
&&
res
[
'result'
]
==
"success"
if
!
EmailValidation
::
check_external_email
(
params
[
:recovery_email
])
flash
[
:notice
]
=
:invalid_recovery_email
return
end
begin
ApiBackend
::
set_recovery_email
(
current_user
,
params
[
:recovery_email
])
flash
[
:notice
]
=
:success
redirect_to
'/'
els
e
rescu
e
flash
[
:notice
]
=
:failed
end
end
...
...
app/controllers/sessions_controller.rb
View file @
b96e5d24
...
...
@@ -25,14 +25,9 @@ class SessionsController < ApplicationController
if
h
&&
allowed_handoff
.
include?
(
h
)
@handoff
=
h
end
if
@handoff
res
=
ApiBackend
::
auth
(
params
[
:user_id
],
params
[
:password
],
master_pw:
true
,
generate_temp_pw:
true
)
else
res
=
ApiBackend
::
auth
(
params
[
:user_id
],
params
[
:password
],
master_pw:
true
)
end
if
res
&&
res
[
'state'
]
==
'success'
query
=
{
master_pw:
true
,
generate_temp_pw:
@handoff
}
begin
res
=
ApiBackend
::
auth
(
params
[
:user_id
],
params
[
:password
],
query
)
session
[
:user_id
]
=
params
[
:user_id
]
session
[
:trees_enabled
]
=
res
[
'trees_enabled'
]
session
[
:pow_factor
]
=
1
...
...
@@ -47,7 +42,10 @@ class SessionsController < ApplicationController
end
redirect_to
'/'
end
# successful login
return
rescue
# Fallthrough, error handling below
end
end
if
session
[
:pow_factor
]
<
4
...
...
app/controllers/signup_controller.rb
View file @
b96e5d24
...
...
@@ -3,9 +3,10 @@ class SignupController < ApplicationController
@token
=
nil
token
=
params
[
:token
]
if
token
check_token
=
ApiBackend
::
new_email_token_valid?
(
token
)
if
check_token
&&
check_token
[
'result'
]
==
'success'
begin
ApiBackend
::
invite_valid?
(
token
)
@token
=
token
rescue
end
end
end
...
...
@@ -26,18 +27,11 @@ class SignupController < ApplicationController
if
request
.
post?
&&
@domain
&&
@email
&&
@email
!=
""
full_email
=
"
#{
@email
}
@
#{
@domain
}
"
check
=
ApiBackend
::
valid_new_email?
(
full_email
)
if
!
check
||
check
[
'result'
]
!=
'success'
if
check
&&
check
[
'msg'
]
==
'invalid_domain'
flash
[
:notice
]
=
:invalid_domain
else
flash
[
:notice
]
=
:invalid_email
end
return
end
if
check
[
'exists'
]
flash
[
:notice
]
=
:account_exists_already
begin
ApiBackend
::
valid_new_email?
(
full_email
)
rescue
=>
e
sleep
5
flash
[
:notice
]
=
e
.
api_msg
return
end
...
...
@@ -49,21 +43,28 @@ class SignupController < ApplicationController
return
end
if
!
@keep_recovery_token
if
@recovery_email
&&
@recovery_email
!=
''
&&
!
EmailValidation
::
check_external_email
(
@recovery_email
)
flash
[
:notice
]
=
:invalid_recovery_email
return
end
if
@enable_trees
&&
!
@keep_recovery_token
flash
[
:notice
]
=
:decide_recovery_token
return
end
res
=
ApiBackend
::
create_new_mailbox
(
full_email
,
@new_pw
,
@enable_trees
,
@token
,
@recovery_email
,
@keep_recovery_token
==
'yes'
)
if
res
&&
res
[
'result'
]
==
'succes
s'
begin
res
=
ApiBackend
::
create_new_mailbox
(
full_email
,
@new_pw
,
@enable_trees
,
@token
,
@recovery_email
,
@keep_recovery_token
==
'ye
s'
)
flash
.
delete
(
:notice
)
if
@keep_recovery_token
==
'no'
puts
res
if
@keep_recovery_token
!=
'yes'
@trees_recovery_token
=
res
[
'trees_recovery_token'
]
end
@account_successfully_created
=
true
els
e
rescu
e
flash
[
:notice
]
=
:signup_failed
end
end
...
...
app/controllers/trees_controller.rb
View file @
b96e5d24
class
TreesController
<
ApplicationController
def
show
if
params
[
:pass
]
res
=
ApiBackend
::
trees_enable
(
current_user
,
params
[
'pass'
])
if
res
&&
res
[
'result'
]
==
'succe
ss'
begin
ApiBackend
::
trees_enable
(
current_user
,
params
[
'pa
ss'
])
session
[
:trees_enabled
]
=
true
flash
[
:notice
]
=
:trees_enabled
redirect_to
'/trees_token'
else
flash
[
:notice
]
=
:trees_enable_failed
rescue
=>
e
if
e
.
api_msg
==
'auth_fail'
flash
[
:notice
]
=
:auth_fail
else
flash
[
:notice
]
=
:trees_enable_failed
end
end
end
end
...
...
app/controllers/trees_token_controller.rb
View file @
b96e5d24
class
TreesTokenController
<
ApplicationController
def
show
if
params
[
:pass
]
res
=
ApiBackend
::
trees_token
(
current_user
,
params
[
:pass
])
if
res
&&
res
[
'result'
]
==
"success"
begin
res
=
ApiBackend
::
trees_token
(
current_user
,
params
[
:pass
])
session
[
:trees_recovery_token
]
=
res
[
'trees_recovery_token'
]
flash
.
delete
(
:notice
)
else
flash
[
:notice
]
=
:get_token_failed
rescue
=>
e
if
e
.
api_msg
==
'auth_fail'
flash
[
:notice
]
=
:auth_fail
else
flash
[
:notice
]
=
:get_token_failed
end
end
end
end
...
...
app/views/app_passwords/show.html.erb
View file @
b96e5d24
...
...
@@ -3,9 +3,14 @@
<p>
<%=
@app_pw
%>
</p>
<%
end
%>
<%
if
@passwords
&&
!
@passwords
.
empty?
%>
<h3>
<%=
t
:app_passwords
%>
</h3>
<p>
<%=
t
:app_passwords_help
%>
</p>
<%
if
@passwords
&&
!
@passwords
.
empty?
%>
<ul>
<%
@passwords
.
each
do
|
pw
|
%>
<li>
...
...
@@ -17,11 +22,11 @@
</li>
<%
end
%>
</ul>
<%
end
%>
<hr/ >
<%
end
%>
<br
/>
<h3>
<%=
t
:new_app_passwords
%>
</h3>
<%=
form_tag
(
"/app_passwords"
,
method:
"post"
)
do
%>
<table>
<tr><td>
...
...
@@ -35,7 +40,7 @@
</td></tr>
</table>
<p>
<%=
submit_tag
(
t
:
submit
)
%>
<%=
link_to
"Cancel"
,
:back
%>
<%=
submit_tag
(
t
:
generate
)
%>
<%=
link_to
t
(
:back
),
'/'
%>
</p>
<%
end
%>
app/views/recovery_email/show.html.erb
View file @
b96e5d24
...
...
@@ -9,4 +9,5 @@
<%=
text_field_tag
(
:recovery_email
)
%>
<br
/>
<%=
submit_tag
(
t
:submit
)
%>
<%=
link_to
t
(
:back
),
'/'
%>
<%
end
%>
app/views/signup/new.html.erb
View file @
b96e5d24
...
...
@@ -3,7 +3,7 @@
<%
if
!
@token
||
@token
==
""
%>
<%=
form_tag
(
"/signup"
,
method:
"post"
)
do
%>
<%=
label_tag
(
:token
,
(
t
:token
))
%>
<%=
label_tag
(
:token
,
(
t
:
invite_
token
))
%>
<%=
text_field_tag
(
:token
)
%>
<%=
submit_tag
(
t
:submit
)
%>
<%
end
%>
...
...
config/locales/de.yml
View file @
b96e5d24
...
...
@@ -36,6 +36,8 @@ de:
create
:
"
erstellen"
app_passwords
:
"
App
Passwörter"
app_passwords_short_help
:
"
Um
via
Mail
Programm
einzuloggen,
musst
du
ein
App
Passwort
erstellen."
app_passwords_help
:
"
Um
mit
externen
Programmen
einzuloggen,
brauchst
du
ein
App
Passwort.
Das
Haupt
Passwort
funktioniert
nur
auf
unseren
Webseiten.
Für
alle
anderen
Zugänge,
zum
Beispiel
für
Thunderbird,
oder
Exchange
Sync
via
Phone,
kannst
du
hier
ein
Spezifisches
Passwort
generieren.
Gib
dazu
den
Verwendungszweck
ein
und
klicke
auf
generieren.
Das
Passwort
wird
dir
danach
angezeigt
und
du
kannst
es
kopieren.
Ebenfalls
kannst
du
hier
bestehende
App
Passwörter
löschen."
generate
:
"
generieren"
change_password_short_help
:
"
Das
Hauptpasswort
ändern"
trees_token_short_help
:
"
Wenn
du
dein
Passwort
vergisst
können
deine
Mails
nur
mit
diesem
Token
wiederhergestellt
werden"
enable_trees_short_help
:
"
Verschlüsselt
Mails
in
deiner
Mailbox
mit
deinem
Passwort"
...
...
@@ -56,3 +58,11 @@ de:
keep_recovery_token_help
:
"
Beim
Passwortverlust
brauchst
du
ein
Token,
um
deine
Mailbox
wiederherzustellen."
init_keep_token
:
"
Ich
kann
jetzt
gerade
das
Token
nicht
sicher
aufbewahren
und
werde
es
später
abholen."
init_delete_token
:
"
Ich
bewahre
das
Token
selber
auf."
invite_token
:
"
Einladungscode"
new_account
:
"
Neues
Konto"
invalid_recovery_email
:
"
Backup
Email
ist
keine
gültige
Adresse"
decide_recovery_token
:
"
Bitte
wähle
aus,
ob
du
dein
Wiederherstellungs
Token
aufbewahren
kannst"
auth_fail
:
"
Falsches
Passwort"
app_password_duplicate
:
"
App
Passwort
mit
diesem
Namen
besteht
bereits"
back
:
"
zurück"
account_exists_already
:
"
Diese
Email
besteht
bereits"
config/locales/en.yml
View file @
b96e5d24
...
...
@@ -15,7 +15,6 @@ en:
encrypt_mailbox_help
:
"
WARNING:
This
feature
is
not
stable
yet
and
it
might
happen
that
mails
become
unreadable.
Activate
this
option
to
encrypt
all
new
incomming
mails
in
your
mailbox."
encrypt_mailbox_help_existing
:
"
(Currently
only
applies
to
new
incoming
mails)"
trees_enabled
:
"
Encryption
activated"
token_cleared
:
"
Token
copy
erased"
password_changed
:
"
Password
changed"
login_failed
:
"
Login
failed"
login
:
"
Login"
...
...
@@ -40,6 +39,8 @@ en:
enable_trees_short_help
:
"
Encrypt
your
mailbox
with
your
password"
your_pw
:
"
Your
password"
new_app_passwords
:
"
Request
new
app
password"
app_passwords_help
:
"
To
connect
with
external
programs
you
need
an
app
specific
password.
Your
main
password
only
works
on
our
own
websites.
For
other
access,
like
Thunderbird,
or
Exchange
sync
by
phone,
you
need
to
create
a
special
password
here.
To
do
so
enter
the
intended
usage
and
click
generate.
The
app
password
will
be
shown
and
you
can
copy/paste
it.
Additionally
you
can
delete
existing
app
passwords
here."
generate
:
"
generate"
password_for_reveal
:
"
Enter
password
to
show
token"
password_for_clear
:
"
Enter
password
to
clear
our
copy"
password_for_enable
:
"
Enter
password
to
enable
encryption"
...
...
@@ -55,3 +56,9 @@ en:
keep_recovery_token_help
:
"
You
need
this
token
to
recover
your
data,
when
you
forget
your
password."
init_keep_token
:
"
Ich
can't
safely
store
the
token
right
now.
I
will
pick
it
up
later."
init_delete_token
:
"
Ich
will
safely
store
my
token."
invite_token
:
"
Invite
Code"
new_account
:
"
New
Account"
invalid_recovery_email
:
"
Recovery
email
is
not
valid"
decide_recovery_token
:
"
Please
decide
if
your
store
your
recovery
token"
auth_fail
:
"
password
wrong"
app_password_duplicate
:
"
App
password
with
this
name
already
exists"
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a 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