@@ -20,17 +20,28 @@ impl Paste {
2020 ) -> Result < Paste > {
2121 let query = format ! (
2222 "
23- UPDATE
23+ WITH _ AS (
24+ UPDATE
25+ pastes
26+ SET
27+ views = views + 1
28+ WHERE
29+ id = $1 AND {}
30+ )
31+ SELECT
32+ created_at,
33+ expires_at,
34+ views + 1 AS views, -- account for in-progress update above
35+ max_views,
36+ CASE WHEN password IS NULL THEN true ELSE
37+ CASE WHEN $2 IS NULL THEN false ELSE password = CRYPT($2, password) END
38+ END AS authenticated
39+ FROM
2440 pastes
25- SET
26- views = views + 1
2741 WHERE
2842 id = $1 AND
2943 CASE WHEN max_views IS NULL THEN true ELSE views <= max_views END AND
30- CASE WHEN expires_at IS NULL THEN true ELSE expires_at > CURRENT_TIMESTAMP END AND
31- {}
32- RETURNING
33- created_at, expires_at, views, max_views
44+ CASE WHEN expires_at IS NULL THEN true ELSE expires_at > CURRENT_TIMESTAMP END
3445 " ,
3546 match password {
3647 None => "password IS NULL" ,
@@ -46,10 +57,21 @@ impl Paste {
4657
4758 match result {
4859 Ok ( row) => {
49- let files = File :: fetch ( conn, & id) . await ?;
50- Ok ( Paste :: from_row ( row, id, files, None ) )
60+ let authenticated = row. get ( "authenticated" ) ;
61+
62+ if authenticated {
63+ let files = File :: fetch ( conn, & id) . await ?;
64+ Ok ( Paste :: from_row ( row, id, files, None ) )
65+ } else {
66+ Err ( HTTPError :: new ( 401 , "Provided password is not valid." ) )
67+ }
68+ }
69+ Err ( _) => {
70+ return Err ( HTTPError :: new (
71+ 404 ,
72+ "Requested paste does not exist, has too many views, or has expired." ,
73+ ) )
5174 }
52- Err ( _) => return Err ( HTTPError :: new ( 404 , "Unknown paste or invalid password." ) ) ,
5375 }
5476 }
5577
0 commit comments