Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
bwinf
medal
Commits
8944e398
Commit
8944e398
authored
Jul 18, 2019
by
Daniel Brüning
Committed by
Robert Czechowski
Aug 20, 2020
Browse files
Closes
#23
Added a signup-page: You can now create a new accounnt without a login-code.
parent
ae7ad8ae
Pipeline
#795
passed with stage
in 9 minutes and 11 seconds
Changes
11
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
src/core.rs
View file @
8944e398
...
...
@@ -14,7 +14,7 @@
use
time
;
use
db_conn
::
MedalConnection
;
use
db_conn
::
{
MedalConnection
,
SignupResult
}
;
use
db_objects
::
OptionSession
;
use
db_objects
::
SessionUser
;
use
db_objects
::{
Contest
,
Grade
,
Group
,
Participation
,
Submission
,
Taskgroup
};
...
...
@@ -533,6 +533,33 @@ pub fn logout<T: MedalConnection>(conn: &T, session_token: Option<String>) {
session_token
.map
(|
token
|
conn
.logout
(
&
token
));
}
pub
fn
signup
<
T
:
MedalConnection
>
(
conn
:
&
T
,
session_token
:
Option
<
String
>
,
signup_data
:
(
String
,
String
,
String
))
->
MedalResult
<
SignupResult
>
{
let
(
username
,
email
,
password
)
=
signup_data
;
if
username
==
""
||
email
==
""
||
password
==
""
{
return
Ok
(
SignupResult
::
EmptyFields
)
}
let
salt
=
helpers
::
make_salt
();
let
hash
=
helpers
::
hash_password
(
&
password
,
&
salt
)
?
;
let
result
=
conn
.signup
(
&
session_token
.unwrap
(),
&
username
,
&
email
,
hash
,
&
salt
);
Ok
(
result
)
}
pub
fn
signupdata
(
query_string
:
Option
<
String
>
)
->
json_val
::
Map
<
String
,
json_val
::
Value
>
{
let
mut
data
=
json_val
::
Map
::
new
();
if
let
Some
(
query
)
=
query_string
{
if
query
.starts_with
(
"status="
)
{
let
status
:
&
str
=
&
query
[
7
..
];
if
[
"EmailTaken"
,
"UsernameTaken"
,
"UserLoggedIn"
,
"EmptyFields"
]
.contains
(
&
status
)
{
data
.insert
((
status
)
.to_string
(),
to_json
(
&
true
));
}
}
}
data
}
pub
fn
load_submission
<
T
:
MedalConnection
>
(
conn
:
&
T
,
task_id
:
i32
,
session_token
:
&
str
,
subtask
:
Option
<
String
>
)
->
MedalResult
<
String
>
{
let
session
=
conn
.get_session
(
&
session_token
)
.ensure_alive
()
.ok_or
(
MedalError
::
NotLoggedIn
)
?
;
...
...
@@ -869,7 +896,7 @@ pub fn show_profile<T: MedalConnection>(conn: &T, session_token: &str, user_id:
if
let
Some
(
query
)
=
query_string
{
if
query
.starts_with
(
"status="
)
{
let
status
:
&
str
=
&
query
[
7
..
];
if
[
"NothingChanged"
,
"DataChanged"
,
"PasswordChanged"
,
"PasswordMissmatch"
,
"firstlogin"
]
.contains
(
&
status
)
{
if
[
"NothingChanged"
,
"DataChanged"
,
"PasswordChanged"
,
"PasswordMissmatch"
,
"firstlogin"
,
"SignedUp"
]
.contains
(
&
status
)
{
data
.insert
((
status
)
.to_string
(),
to_json
(
&
true
));
}
}
...
...
@@ -887,6 +914,7 @@ pub fn show_profile<T: MedalConnection>(conn: &T, session_token: &str, user_id:
})
.collect
();
data
.insert
(
"participations"
.into
(),
to_json
(
&
participations
));
}
// Case user_id: teacher modifing a students profile
Some
(
user_id
)
=>
{
// TODO: Add test to check if this access restriction works
let
(
user
,
opt_group
)
=
conn
.get_user_and_group_by_id
(
user_id
)
.ok_or
(
MedalError
::
AccessDenied
)
?
;
...
...
src/db_conn.base.rs
View file @
8944e398
...
...
@@ -270,8 +270,10 @@ impl MedalConnection for Connection {
sex = $11,
is_admin = $12,
is_teacher = $13,
permanent_login = $14
WHERE id = $15"
,
permanent_login = $14,
email = $15,
email_unconfirmed = $16
WHERE id = $17"
,
&
[
&
session
.username
,
&
session
.password
,
&
session
.salt
,
...
...
@@ -286,6 +288,8 @@ impl MedalConnection for Connection {
&
session
.is_admin
,
&
session
.is_teacher
,
&
session
.permanent_login
,
&
session
.email
,
&
session
.email_unconfirmed
,
&
session
.id
])
.unwrap
();
}
...
...
@@ -563,6 +567,35 @@ impl MedalConnection for Connection {
self
.execute
(
query
,
&
[
&
session
])
.unwrap
();
}
fn
signup
(
&
self
,
session_token
:
&
str
,
username
:
&
str
,
email
:
&
str
,
password_hash
:
String
,
salt
:
&
str
)
->
SignupResult
{
let
mut
session_user
=
self
.get_session_or_new
(
&
session_token
);
if
session_user
.is_logged_in
()
{
return
SignupResult
::
UserLoggedIn
}
if
let
Ok
(
None
)
=
self
.query_map_one
(
"SELECT username FROM session WHERE username = $1"
,
&
[
&
username
],
|
row
|
->
Option
<
String
>
{
row
.get
(
0
)
})
{}
else
{
//This username already exists!
return
SignupResult
::
UsernameTaken
}
if
let
Ok
(
None
)
=
self
.query_map_one
(
"SELECT email, email_unconfirmed FROM session WHERE email = $1 OR email_unconfirmed = $1"
,
&
[
&
email
],
|
row
|
->
(
Option
<
String
>
,
Option
<
String
>
)
{
(
row
.get
(
0
),
row
.get
(
1
))
})
{}
else
{
//This email already exists!
return
SignupResult
::
EmailTaken
}
session_user
.username
=
Some
(
username
.to_string
());
session_user
.email_unconfirmed
=
Some
(
email
.to_string
());
session_user
.password
=
Some
(
password_hash
);
session_user
.salt
=
Some
(
salt
.to_string
());
self
.save_session
(
session_user
);
SignupResult
::
SignedUp
}
fn
load_submission
(
&
self
,
session
:
&
SessionUser
,
task
:
i32
,
subtask
:
Option
<&
str
>
)
->
Option
<
Submission
>
{
match
subtask
{
None
=>
{
...
...
src/db_conn.rs
View file @
8944e398
...
...
@@ -14,6 +14,15 @@
use
db_objects
::
*
;
#[derive(Debug)]
pub
enum
SignupResult
{
SignedUp
,
EmailTaken
,
UsernameTaken
,
UserLoggedIn
,
EmptyFields
,
}
/// This trait abstracts the database connection and provides function for all actions to be performed on the database
/// in the medal platform.
pub
trait
MedalConnection
{
...
...
@@ -64,6 +73,8 @@ pub trait MedalConnection {
/// to `NULL`.
fn
logout
(
&
self
,
session
:
&
str
);
fn
signup
(
&
self
,
session_token
:
&
str
,
username
:
&
str
,
email
:
&
str
,
password_hash
:
String
,
salt
:
&
str
)
->
SignupResult
;
fn
load_submission
(
&
self
,
session
:
&
SessionUser
,
task
:
i32
,
subtask
:
Option
<&
str
>
)
->
Option
<
Submission
>
;
fn
get_all_submissions
(
&
self
,
session_id
:
i32
,
task
:
i32
,
subtask
:
Option
<&
str
>
)
->
Vec
<
Submission
>
;
fn
submit_submission
(
&
self
,
submission
:
Submission
);
...
...
src/db_conn_postgres.header.rs
View file @
8944e398
...
...
@@ -20,7 +20,7 @@ use postgres::Connection;
use
time
;
use
time
::
Duration
;
use
db_conn
::{
MedalConnection
,
MedalObject
};
use
db_conn
::{
MedalConnection
,
MedalObject
,
SignupResult
};
use
db_objects
::
*
;
use
helpers
;
...
...
src/db_conn_postgres.rs
View file @
8944e398
...
...
@@ -33,7 +33,7 @@ use postgres::Connection;
use
time
;
use
time
::
Duration
;
use
db_conn
::{
MedalConnection
,
MedalObject
};
use
db_conn
::{
MedalConnection
,
MedalObject
,
SignupResult
};
use
db_objects
::
*
;
use
helpers
;
...
...
@@ -382,8 +382,10 @@ impl MedalConnection for Connection {
sex = $11,
is_admin = $12,
is_teacher = $13,
permanent_login = $14
WHERE id = $15"
,
permanent_login = $14,
email = $15,
email_unconfirmed = $16
WHERE id = $17"
,
&
[
&
session
.username
,
&
session
.password
,
&
session
.salt
,
...
...
@@ -398,6 +400,8 @@ impl MedalConnection for Connection {
&
session
.is_admin
,
&
session
.is_teacher
,
&
session
.permanent_login
,
&
session
.email
,
&
session
.email_unconfirmed
,
&
session
.id
])
.unwrap
();
}
...
...
@@ -675,6 +679,35 @@ impl MedalConnection for Connection {
self
.execute
(
query
,
&
[
&
session
])
.unwrap
();
}
fn
signup
(
&
self
,
session_token
:
&
str
,
username
:
&
str
,
email
:
&
str
,
password_hash
:
String
,
salt
:
&
str
)
->
SignupResult
{
let
mut
session_user
=
self
.get_session_or_new
(
&
session_token
);
if
session_user
.is_logged_in
()
{
return
SignupResult
::
UserLoggedIn
}
if
let
Ok
(
None
)
=
self
.query_map_one
(
"SELECT username FROM session WHERE username = $1"
,
&
[
&
username
],
|
row
|
->
Option
<
String
>
{
row
.get
(
0
)
})
{}
else
{
//This username already exists!
return
SignupResult
::
UsernameTaken
}
if
let
Ok
(
None
)
=
self
.query_map_one
(
"SELECT email, email_unconfirmed FROM session WHERE email = $1 OR email_unconfirmed = $1"
,
&
[
&
email
],
|
row
|
->
(
Option
<
String
>
,
Option
<
String
>
)
{
(
row
.get
(
0
),
row
.get
(
1
))
})
{}
else
{
//This email already exists!
return
SignupResult
::
EmailTaken
}
session_user
.username
=
Some
(
username
.to_string
());
session_user
.email_unconfirmed
=
Some
(
email
.to_string
());
session_user
.password
=
Some
(
password_hash
);
session_user
.salt
=
Some
(
salt
.to_string
());
self
.save_session
(
session_user
);
SignupResult
::
SignedUp
}
fn
load_submission
(
&
self
,
session
:
&
SessionUser
,
task
:
i32
,
subtask
:
Option
<&
str
>
)
->
Option
<
Submission
>
{
match
subtask
{
None
=>
{
...
...
src/db_conn_sqlite_new.header.rs
View file @
8944e398
...
...
@@ -20,7 +20,7 @@ use rusqlite::Connection;
use
time
;
use
time
::
Duration
;
use
db_conn
::{
MedalConnection
,
MedalObject
};
use
db_conn
::{
MedalConnection
,
MedalObject
,
SignupResult
};
use
db_objects
::
*
;
use
helpers
;
...
...
src/db_conn_sqlite_new.rs
View file @
8944e398
...
...
@@ -33,7 +33,7 @@ use rusqlite::Connection;
use
time
;
use
time
::
Duration
;
use
db_conn
::{
MedalConnection
,
MedalObject
};
use
db_conn
::{
MedalConnection
,
MedalObject
,
SignupResult
};
use
db_objects
::
*
;
use
helpers
;
...
...
@@ -382,8 +382,10 @@ impl MedalConnection for Connection {
sex = ?11,
is_admin = ?12,
is_teacher = ?13,
permanent_login = ?14
WHERE id = ?15"
,
permanent_login = ?14,
email = ?15,
email_unconfirmed = ?16
WHERE id = ?17"
,
&
[
&
session
.username
,
&
session
.password
,
&
session
.salt
,
...
...
@@ -398,6 +400,8 @@ impl MedalConnection for Connection {
&
session
.is_admin
,
&
session
.is_teacher
,
&
session
.permanent_login
,
&
session
.email
,
&
session
.email_unconfirmed
,
&
session
.id
])
.unwrap
();
}
...
...
@@ -675,6 +679,35 @@ impl MedalConnection for Connection {
self
.execute
(
query
,
&
[
&
session
])
.unwrap
();
}
fn
signup
(
&
self
,
session_token
:
&
str
,
username
:
&
str
,
email
:
&
str
,
password_hash
:
String
,
salt
:
&
str
)
->
SignupResult
{
let
mut
session_user
=
self
.get_session_or_new
(
&
session_token
);
if
session_user
.is_logged_in
()
{
return
SignupResult
::
UserLoggedIn
}
if
let
Ok
(
None
)
=
self
.query_map_one
(
"SELECT username FROM session WHERE username = ?1"
,
&
[
&
username
],
|
row
|
->
Option
<
String
>
{
row
.get
(
0
)
})
{}
else
{
//This username already exists!
return
SignupResult
::
UsernameTaken
}
if
let
Ok
(
None
)
=
self
.query_map_one
(
"SELECT email, email_unconfirmed FROM session WHERE email = ?1 OR email_unconfirmed = ?1"
,
&
[
&
email
],
|
row
|
->
(
Option
<
String
>
,
Option
<
String
>
)
{
(
row
.get
(
0
),
row
.get
(
1
))
})
{}
else
{
//This email already exists!
return
SignupResult
::
EmailTaken
}
session_user
.username
=
Some
(
username
.to_string
());
session_user
.email_unconfirmed
=
Some
(
email
.to_string
());
session_user
.password
=
Some
(
password_hash
);
session_user
.salt
=
Some
(
salt
.to_string
());
self
.save_session
(
session_user
);
SignupResult
::
SignedUp
}
fn
load_submission
(
&
self
,
session
:
&
SessionUser
,
task
:
i32
,
subtask
:
Option
<&
str
>
)
->
Option
<
Submission
>
{
match
subtask
{
None
=>
{
...
...
src/webfw_iron.rs
View file @
8944e398
...
...
@@ -41,6 +41,8 @@ use db_conn::MedalConnection;
use
iron
::
typemap
::
Key
;
pub
use
serde_json
::
value
as
json_val
;
use
db_conn
::
SignupResult
;
static
TASK_DIR
:
&
str
=
"tasks"
;
macro_rules!
mime
{
...
...
@@ -592,9 +594,43 @@ fn logout<C>(req: &mut Request) -> IronResult<Response>
Ok
(
Response
::
with
((
status
::
Found
,
Redirect
(
url_for!
(
req
,
"greet"
)))))
}
fn
signup
<
C
>
(
req
:
&
mut
Request
)
->
IronResult
<
Response
>
where
C
:
MedalConnection
+
std
::
marker
::
Send
+
'static
{
let
query_string
=
req
.url
.query
()
.map
(|
s
|
s
.to_string
());
let
data
=
core
::
signupdata
(
query_string
);
let
mut
resp
=
Response
::
new
();
resp
.set_mut
(
Template
::
new
(
"signup"
,
data
))
.set_mut
(
status
::
Ok
);
Ok
(
resp
)
}
fn
signup_post
<
C
>
(
req
:
&
mut
Request
)
->
IronResult
<
Response
>
where
C
:
MedalConnection
+
std
::
marker
::
Send
+
'static
{
let
session_token
=
req
.get_session_token
();
let
signupdata
=
{
let
formdata
=
itry!
(
req
.get_ref
::
<
UrlEncodedBody
>
());
(
iexpect!
(
formdata
.get
(
"username"
))[
0
]
.to_owned
(),
iexpect!
(
formdata
.get
(
"email"
))[
0
]
.to_owned
(),
iexpect!
(
formdata
.get
(
"password"
))[
0
]
.to_owned
())
};
let
signupresult
=
with_conn!
[
core
::
signup
,
C
,
req
,
session_token
,
signupdata
]
.aug
(
req
)
?
;
match
signupresult
{
SignupResult
::
SignedUp
=>
Ok
(
Response
::
with
((
status
::
Found
,
Redirect
(
iron
::
Url
::
parse
(
&
format!
(
"{}?status={:?}"
,
&
url_for!
(
req
,
"profile"
),
signupresult
))
.unwrap
())))),
_
=>
Ok
(
Response
::
with
((
status
::
Found
,
Redirect
(
iron
::
Url
::
parse
(
&
format!
(
"{}?status={:?}"
,
&
url_for!
(
req
,
"signup"
),
signupresult
))
.unwrap
()))))
}
}
fn
submission
<
C
>
(
req
:
&
mut
Request
)
->
IronResult
<
Response
>
where
C
:
MedalConnection
+
std
::
marker
::
Send
+
'static
{
let
task_id
=
req
.expect_int
::
<
i32
>
(
"taskid"
)
?
;
let
session_token
=
req
.expect_session_token
()
?
;
let
subtask
:
Option
<
String
>
=
(||
->
Option
<
String
>
{
req
.get_ref
::
<
UrlEncodedQuery
>
()
.ok
()
?
.get
(
"subtask"
)
?
.get
(
0
)
.map
(|
x
|
x
.to_owned
())
...
...
@@ -1189,6 +1225,8 @@ pub fn start_server<C>(conn: C, config: Config) -> iron::error::HttpResult<iron:
login_post
:
post
"/login"
=>
login_post
::
<
C
>
,
login_code_post
:
post
"/clogin"
=>
login_code_post
::
<
C
>
,
logout
:
get
"/logout"
=>
logout
::
<
C
>
,
signup
:
get
"/signup"
=>
signup
::
<
C
>
,
signup_post
:
post
"/signup"
=>
signup_post
::
<
C
>
,
subm
:
get
"/submission/:taskid"
=>
submission
::
<
C
>
,
subm_post
:
post
"/submission/:taskid"
=>
submission_post
::
<
C
>
,
subm_load
:
get
"/load/:taskid"
=>
submission
::
<
C
>
,
...
...
templates/default/profile.hbs
View file @
8944e398
...
...
@@ -4,6 +4,11 @@
<h1>
Benutzerdaten bearbeiten:
{{
profile_firstname
}}
{{
profile_lastname
}}
</h1>
{{/if}}
{{#if
SignedUp
}}
<p
style=
"color:green; font-weight:bold;"
>
Du hast dir erfolgreich einen Account angelegt.
<br/>
Auf dieser Seite kannst du weitere Angaben zu dir eintragen und dein Passwort ändern.
</p>
{{/if}}
{{#if
profile_username
}}
<p>
Benutzername:
{{
profile_username
}}
</p>
{{/if}}
...
...
templates/default/signup.hbs
0 → 100644
View file @
8944e398
<h1>
Sign up
</h1>
<div
style=
"color:green; font-weight:bold"
>
{{#if
UsernameTaken
}}
<p>
Dieser Benutzername existiert bereits. Bitte wähle einen anderen.
</p>
{{/if}}
{{#if
EmailTaken
}}
<p>
Diese E-Mail Adresse wird bereits von einem anderen Account verwendet. Bitte wähle eine andere.
</p>
{{/if}}
{{#if
UserLoggedIn
}}
<p>
Du bist bereits angemeldet. Wenn du einen neuen Account erstellen möchtest, dann melde dich zunächst ab.
</p>
{{/if}}
{{#if
EmptyFields
}}
<p>
Bitte fülle alle Felder aus, um dir einen Account anzulegen.
</p>
{{/if}}
</div>
<p>
<form
action=
"signup"
method=
"post"
>
Beutzername:
<br>
<input
type=
"text"
name=
"username"
autofocus
>
<br>
E-Mail Adresse:
<br>
<input
type=
"text"
name=
"email"
>
<br>
Passwort:
<br>
<input
type=
"password"
name=
"password"
value=
""
>
<br><br>
<input
type=
"submit"
value=
"sign up"
>
</form>
templates/jwinf/signup.hbs
0 → 120000
View file @
8944e398
../default/signup.hbs
\ No newline at end of file
Write
Preview
Markdown
is supported
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