Allways give "next" argument for login link.

This commit is contained in:
Rasmus Kaj 2017-08-03 19:59:21 +02:00
parent f78966682a
commit a0df34644b
15 changed files with 65 additions and 51 deletions

View File

@ -132,16 +132,17 @@ fn login<'mw>(req: &mut Request,
mut res: Response<'mw>) mut res: Response<'mw>)
-> MiddlewareResult<'mw> { -> MiddlewareResult<'mw> {
res.clear_jwt(); res.clear_jwt();
let next = sanitize_next(req.query().get("next")); let next = sanitize_next(req.query().get("next")).map(String::from);
res.ok(|o| templates::login(o, next)) res.ok(|o| templates::login(o, req, next))
} }
fn do_login<'mw>(req: &mut Request, fn do_login<'mw>(req: &mut Request,
mut res: Response<'mw>) mut res: Response<'mw>)
-> MiddlewareResult<'mw> { -> MiddlewareResult<'mw> {
let next = {
let c: &PgConnection = &req.db_conn(); let c: &PgConnection = &req.db_conn();
let form_data = try_with!(res, req.form_body()); let form_data = try_with!(res, req.form_body());
let next = sanitize_next(form_data.get("next")); let next = sanitize_next(form_data.get("next")).map(String::from);
if let (Some(user), Some(pw)) = (form_data.get("user"), if let (Some(user), Some(pw)) = (form_data.get("user"),
form_data.get("password")) { form_data.get("password")) {
use rphotos::schema::users::dsl::*; use rphotos::schema::users::dsl::*;
@ -152,14 +153,16 @@ fn do_login<'mw>(req: &mut Request,
if djangohashers::check_password_tolerant(pw, &hash) { if djangohashers::check_password_tolerant(pw, &hash) {
info!("User {} logged in", user); info!("User {} logged in", user);
res.set_jwt_user(user); res.set_jwt_user(user);
return res.redirect(next.unwrap_or("/")); return res.redirect(next.unwrap_or("/".to_string()));
} }
debug!("Password verification failed"); debug!("Password verification failed");
} else { } else {
debug!("No hash found for {}", user); debug!("No hash found for {}", user);
} }
} }
res.ok(|o| templates::login(o, next)) next
};
res.ok(|o| templates::login(o, req, next))
} }
fn sanitize_next(next: Option<&str>) -> Option<&str> { fn sanitize_next(next: Option<&str>) -> Option<&str> {
@ -291,7 +294,7 @@ fn tag_all<'mw>(req: &mut Request,
}; };
res.ok(|o| { res.ok(|o| {
templates::tags(o, templates::tags(o,
req.authorized_user(), req,
&query.order(tag_name).load(c).expect("List tags")) &query.order(tag_name).load(c).expect("List tags"))
}) })
} }
@ -307,7 +310,7 @@ fn tag_one<'mw>(req: &mut Request,
use rphotos::schema::photo_tags::dsl::{photo_id, photo_tags, tag_id}; use rphotos::schema::photo_tags::dsl::{photo_id, photo_tags, tag_id};
return res.ok(|o| { return res.ok(|o| {
templates::tag(o, templates::tag(o,
req.authorized_user(), req,
&Photo::query(req.authorized_user().is_some()) &Photo::query(req.authorized_user().is_some())
.filter(id.eq_any(photo_tags.select(photo_id) .filter(id.eq_any(photo_tags.select(photo_id)
.filter(tag_id.eq(tag.id)))) .filter(tag_id.eq(tag.id))))
@ -340,7 +343,7 @@ fn place_all<'mw>(req: &mut Request,
let c: &PgConnection = &req.db_conn(); let c: &PgConnection = &req.db_conn();
res.ok(|o| templates::places( res.ok(|o| templates::places(
o, o,
req.authorized_user(), req,
&query.order(place_name).load(c).expect("List places"))) &query.order(place_name).load(c).expect("List places")))
} }
@ -369,7 +372,7 @@ fn place_one<'mw>(req: &mut Request,
place_id}; place_id};
return res.ok(|o| templates::place( return res.ok(|o| templates::place(
o, o,
req.authorized_user(), req,
&Photo::query(req.authorized_user().is_some()) &Photo::query(req.authorized_user().is_some())
.filter(id.eq_any(photo_places.select(photo_id) .filter(id.eq_any(photo_places.select(photo_id)
.filter(place_id.eq(place.id)))) .filter(place_id.eq(place.id))))
@ -400,7 +403,7 @@ fn person_all<'mw>(req: &mut Request,
let c: &PgConnection = &req.db_conn(); let c: &PgConnection = &req.db_conn();
res.ok(|o| templates::people( res.ok(|o| templates::people(
o, o,
req.authorized_user(), req,
&query.order(person_name).load(c).expect("list people"))) &query.order(person_name).load(c).expect("list people")))
} }
@ -416,7 +419,7 @@ fn person_one<'mw>(req: &mut Request,
photo_people}; photo_people};
return res.ok(|o| templates::person( return res.ok(|o| templates::person(
o, o,
req.authorized_user(), req,
&Photo::query(req.authorized_user().is_some()) &Photo::query(req.authorized_user().is_some())
.filter(id.eq_any(photo_people.select(photo_id) .filter(id.eq_any(photo_people.select(photo_id)
.filter(person_id.eq(person.id)))) .filter(person_id.eq(person.id))))
@ -437,12 +440,12 @@ fn photo_details<'mw>(req: &mut Request,
if req.authorized_user().is_some() || tphoto.is_public() { if req.authorized_user().is_some() || tphoto.is_public() {
return res.ok(|o| templates::details( return res.ok(|o| templates::details(
o, o,
req,
&tphoto.date &tphoto.date
.map(|d| vec![Link::year(d.year()), .map(|d| vec![Link::year(d.year()),
Link::month(d.year(), d.month()), Link::month(d.year(), d.month()),
Link::day(d.year(), d.month(), d.day())]) Link::day(d.year(), d.month(), d.day())])
.unwrap_or_else(|| vec![]), .unwrap_or_else(|| vec![]),
req.authorized_user(),
&{ &{
use rphotos::schema::people::dsl::{people, id}; use rphotos::schema::people::dsl::{people, id};
use rphotos::schema::photo_people::dsl::{photo_people, photo_id, person_id}; use rphotos::schema::photo_people::dsl::{photo_people, photo_id, person_id};

View File

@ -20,7 +20,6 @@ pub fn all_years<'mw>(req: &mut Request,
use rphotos::schema::photos::dsl::{date, grade}; use rphotos::schema::photos::dsl::{date, grade};
let c: &PgConnection = &req.db_conn(); let c: &PgConnection = &req.db_conn();
let user: Option<String> = req.authorized_user();
let groups: Vec<Group> = let groups: Vec<Group> =
SqlLiteral::new(format!( SqlLiteral::new(format!(
"select cast(extract(year from date) as int) y, count(*) c \ "select cast(extract(year from date) as int) y, count(*) c \
@ -53,7 +52,7 @@ pub fn all_years<'mw>(req: &mut Request,
} }
}).collect(); }).collect();
res.ok(|o| templates::groups(o, "All photos", &[], user, &groups)) res.ok(|o| templates::groups(o, req, "All photos", &[], &groups))
} }
pub fn months_in_year<'mw>(req: &mut Request, pub fn months_in_year<'mw>(req: &mut Request,
@ -63,7 +62,6 @@ pub fn months_in_year<'mw>(req: &mut Request,
use rphotos::schema::photos::dsl::{date, grade}; use rphotos::schema::photos::dsl::{date, grade};
let c: &PgConnection = &req.db_conn(); let c: &PgConnection = &req.db_conn();
let user: Option<String> = req.authorized_user();
let title: String = format!("Photos from {}", year); let title: String = format!("Photos from {}", year);
let groups: Vec<Group> = let groups: Vec<Group> =
SqlLiteral::new(format!( SqlLiteral::new(format!(
@ -102,7 +100,7 @@ pub fn months_in_year<'mw>(req: &mut Request,
if groups.is_empty() { if groups.is_empty() {
res.not_found("No such image") res.not_found("No such image")
} else { } else {
res.ok(|o| templates::groups(o, &title, &[], user, &groups)) res.ok(|o| templates::groups(o, req, &title, &[], &groups))
} }
} }
@ -114,7 +112,6 @@ pub fn days_in_month<'mw>(req: &mut Request,
use rphotos::schema::photos::dsl::{date, grade}; use rphotos::schema::photos::dsl::{date, grade};
let c: &PgConnection = &req.db_conn(); let c: &PgConnection = &req.db_conn();
let user: Option<String> = req.authorized_user();
let lpath: Vec<Link> = vec![Link::year(year)]; let lpath: Vec<Link> = vec![Link::year(year)];
let title: String = format!("Photos from {} {}", monthname(month), year); let title: String = format!("Photos from {} {}", monthname(month), year);
let groups: Vec<Group> = let groups: Vec<Group> =
@ -151,7 +148,7 @@ pub fn days_in_month<'mw>(req: &mut Request,
if groups.is_empty() { if groups.is_empty() {
res.not_found("No such image") res.not_found("No such image")
} else { } else {
res.ok(|o| templates::groups(o, &title, &lpath, user, &groups)) res.ok(|o| templates::groups(o, req, &title, &lpath, &groups))
} }
} }
@ -163,9 +160,9 @@ pub fn all_null_date<'mw>(req: &mut Request,
let c: &PgConnection = &req.db_conn(); let c: &PgConnection = &req.db_conn();
res.ok(|o| templates::index( res.ok(|o| templates::index(
o, o,
req,
&"Photos without a date", &"Photos without a date",
&[], &[],
req.authorized_user(),
&Photo::query(req.authorized_user().is_some()) &Photo::query(req.authorized_user().is_some())
.filter(date.is_null()) .filter(date.is_null())
.order(path.asc()) .order(path.asc())
@ -198,9 +195,9 @@ pub fn all_for_day<'mw>(req: &mut Request,
warn!("Got {} photos, way to many", n); warn!("Got {} photos, way to many", n);
res.ok(|o| templates::groups( res.ok(|o| templates::groups(
o, o,
req,
&format!("Photos from {} {}", day, monthname(month)), &format!("Photos from {} {}", day, monthname(month)),
&[Link::year(year), Link::month(year, month)], &[Link::year(year), Link::month(year, month)],
req.authorized_user(),
&(photos.chunks((n as f64).sqrt() as usize) &(photos.chunks((n as f64).sqrt() as usize)
.enumerate() .enumerate()
.map(|(i, chunk)| { .map(|(i, chunk)| {
@ -232,9 +229,9 @@ pub fn all_for_day<'mw>(req: &mut Request,
} else { } else {
res.ok(|o| templates::index( res.ok(|o| templates::index(
o, o,
req,
&format!("Photos from {} {} {}", day, monthname(month), year), &format!("Photos from {} {} {}", day, monthname(month), year),
&[Link::year(year), Link::month(year, month)], &[Link::year(year), Link::month(year, month)],
req.authorized_user(),
&photos, &photos,
)) ))
} }
@ -267,6 +264,7 @@ pub fn part_for_day<'mw>(
if let Some(photos) = chunks.nth(part) { if let Some(photos) = chunks.nth(part) {
res.ok(|o| templates::index( res.ok(|o| templates::index(
o, o,
req,
&format!( &format!(
"Photos from {} {} {}, {} - {}", "Photos from {} {} {}, {} - {}",
day, monthname(month), year, day, monthname(month), year,
@ -284,7 +282,6 @@ pub fn part_for_day<'mw>(
Link::month(year, month), Link::month(year, month),
Link::day(year, month, day), Link::day(year, month, day),
], ],
req.authorized_user(),
&photos, &photos,
)) ))
} else { } else {
@ -305,9 +302,9 @@ pub fn on_this_day<'mw>(req: &mut Request,
}; };
res.ok(|o| templates::groups( res.ok(|o| templates::groups(
o, o,
req,
&format!("Photos from {} {}", day, monthname(month)), &format!("Photos from {} {}", day, monthname(month)),
&[], &[],
req.authorized_user(),
&SqlLiteral::new(format!( &SqlLiteral::new(format!(
"select extract(year from date) y, count(*) c \ "select extract(year from date) y, count(*) c \
from photos where extract(month from date)={} \ from photos where extract(month from date)={} \

View File

@ -1,13 +1,15 @@
@use ::{Coord, Link}; @use ::{Coord, Link};
@use nickel::Request;
@use nickel_jwt_session::SessionRequestExtensions;
@use rphotos::models::{Photo, Person, Place, Tag, Camera}; @use rphotos::models::{Photo, Person, Place, Tag, Camera};
@use templates::page_base; @use templates::page_base;
@(lpath: &[Link], user: Option<String>, people: &[Person], places: &[Place], tags: &[Tag], position: Option<Coord>, attribution: Option<String>, camera: Option<Camera>, photo: Photo) @(req: &Request, lpath: &[Link], people: &[Person], places: &[Place], tags: &[Tag], position: Option<Coord>, attribution: Option<String>, camera: Option<Camera>, photo: Photo)
@:page_base("Photo details", lpath, &user, { @:page_base(req, "Photo details", lpath, {
<div class="details"> <div class="details">
<div class="item"><img src="/img/@photo.id-m.jpg"></div> <div class="item"><img src="/img/@photo.id-m.jpg"></div>
<div class="meta"> <div class="meta">
@if user.is_some() { @if req.authorized_user().is_some() {
<p><a href="/img/@photo.id-l.jpg">@photo.path</a></p> <p><a href="/img/@photo.id-l.jpg">@photo.path</a></p>
@if photo.is_public() {<p>This photo is public.</p>} @if photo.is_public() {<p>This photo is public.</p>}
else {<p>This photo is not public.</p>} else {<p>This photo is not public.</p>}

View File

@ -1,9 +1,10 @@
@use ::{Group, Link}; @use ::{Group, Link};
@use nickel::Request;
@use templates::page_base; @use templates::page_base;
@(title: &str, lpath: &[Link], user: Option<String>, groups: &[Group]) @(req: &Request, title: &str, lpath: &[Link], groups: &[Group])
@:page_base(title, lpath, &user, { @:page_base(req, title, lpath, {
<div class="group"> <div class="group">
@if groups.is_empty() { @if groups.is_empty() {
<p>Inga bilder.</p> <p>Inga bilder.</p>

View File

@ -1,6 +1,8 @@
@use ::Link; @use ::Link;
@use nickel::Request;
@use nickel_jwt_session::SessionRequestExtensions;
@(lpath: &[Link], user: &Option<String>) @(req: &Request, lpath: &[Link])
<header> <header>
<span><a href="/">Images</a> <span><a href="/">Images</a>
@ -10,6 +12,6 @@
<span>· <a href="/person/">People</a></span> <span>· <a href="/person/">People</a></span>
<span>· <a href="/place/">Places</a></span> <span>· <a href="/place/">Places</a></span>
<span>· <a href="/thisday">On this day</a></span> <span>· <a href="/thisday">On this day</a></span>
@if let &Some(ref u) = user {<span class="user">@u (<a href="/logout">log out</a>)</span>} @if let Some(ref u) = req.authorized_user() {<span class="user">@u (<a href="/logout">log out</a>)</span>}
else {<span class="user">(<a href="/login">log in</a>)</span>} else {<span class="user">(<a href="/login@if let Some(p) = req.path_without_query() {?next=@p}">log in</a>)</span>}
</header> </header>

View File

@ -1,10 +1,11 @@
@use ::Link; @use ::Link;
@use nickel::Request;
@use rphotos::models::Photo; @use rphotos::models::Photo;
@use templates::{page_base, img_link}; @use templates::{page_base, img_link};
@(title: &str, lpath: &[Link], user: Option<String>, photos: &[Photo]) @(req: &Request, title: &str, lpath: &[Link], photos: &[Photo])
@:page_base(title, lpath, &user, { @:page_base(req, title, lpath, {
<div class="group"> <div class="group">
@for p in photos {@:img_link(p)} @for p in photos {@:img_link(p)}
</div> </div>

View File

@ -1,14 +1,15 @@
@use nickel::Request;
@use templates::page_base; @use templates::page_base;
@(next: Option<&str>) @(req: &Request, next: Option<String>)
@:page_base("login", &[], &None, { @:page_base(req, "login", &[], {
<form action="/login" method="post"> <form action="/login" method="post">
<p><label for="user">User:</label> <p><label for="user">User:</label>
<input id="user" name="user"></p> <input id="user" name="user"></p>
<p><label for="password">Password:</label> <p><label for="password">Password:</label>
<input id="password" name="password" type="password"></p> <input id="password" name="password" type="password"></p>
<p><span>@if let Some(next) = next { <p><span>@if let Some(ref next) = next {
<input type="hidden" name="next" value="@next"> <input type="hidden" name="next" value="@next">
}</span> }</span>
<input type="submit" value="Log in"> <input type="submit" value="Log in">

View File

@ -4,7 +4,7 @@
@(req: &Request) @(req: &Request)
@:page_base("Not found", &[], &req.authorized_user(), { @:page_base(req, "Not found", &[], {
<p>No page or photo match that url.</p> <p>No page or photo match that url.</p>
@if req.authorized_user().is_none() { @if req.authorized_user().is_none() {
<p>At least nothing publicly visible, you might try <p>At least nothing publicly visible, you might try

View File

@ -1,8 +1,9 @@
@use ::Link; @use ::Link;
@use nickel::Request;
@use templates::head; @use templates::head;
@use templates::statics::photos_css; @use templates::statics::photos_css;
@(title: &str, lpath: &[Link], user: &Option<String>, content: Content) @(req: &Request, title: &str, lpath: &[Link], content: Content)
<!doctype html> <!doctype html>
<html> <html>
@ -13,7 +14,7 @@
<link rel="stylesheet" href="/static/@photos_css.name" type="text/css"/> <link rel="stylesheet" href="/static/@photos_css.name" type="text/css"/>
</head> </head>
<body> <body>
@:head(lpath, user) @:head(req, lpath)
<main> <main>
<h1>@title</h1> <h1>@title</h1>
@:content() @:content()

View File

@ -1,8 +1,9 @@
@use nickel::Request;
@use rphotos::models::Person; @use rphotos::models::Person;
@use templates::page_base; @use templates::page_base;
@(user: Option<String>, people: &[Person]) @(req: &Request, people: &[Person])
@:page_base("Photo people", &[], &user, { @:page_base(req, "Photo people", &[], {
<ul class="allpeople"> <ul class="allpeople">
@for p in people { @for p in people {
<li><a href="/person/@p.slug">@p.person_name</a> <li><a href="/person/@p.slug">@p.person_name</a>

View File

@ -1,8 +1,9 @@
@use nickel::Request;
@use rphotos::models::{Photo, Person}; @use rphotos::models::{Photo, Person};
@use templates::{page_base, img_link}; @use templates::{page_base, img_link};
@(user: Option<String>, photos: &[Photo], person: Person) @(req: &Request, photos: &[Photo], person: Person)
@:page_base(&format!("Photos with {}", person.person_name), &[], &user, { @:page_base(req, &format!("Photos with {}", person.person_name), &[], {
<div class="group"> <div class="group">
@for p in photos {@:img_link(p)} @for p in photos {@:img_link(p)}
</div> </div>

View File

@ -1,8 +1,9 @@
@use nickel::Request;
@use rphotos::models::{Photo, Place}; @use rphotos::models::{Photo, Place};
@use templates::{page_base, img_link}; @use templates::{page_base, img_link};
@(user: Option<String>, photos: &[Photo], place: Place) @(req: &Request, photos: &[Photo], place: Place)
@:page_base(&format!("Photos from {}", place.place_name), &[], &user, { @:page_base(req, &format!("Photos from {}", place.place_name), &[], {
<div class="group"> <div class="group">
@for p in photos {@:img_link(p)} @for p in photos {@:img_link(p)}
</div> </div>

View File

@ -1,9 +1,10 @@
@use nickel::Request;
@use rphotos::models::Place; @use rphotos::models::Place;
@use templates::page_base; @use templates::page_base;
@(user: Option<String>, places: &[Place]) @(req: &Request, places: &[Place])
@:page_base("Photo places", &[], &user, { @:page_base(req, "Photo places", &[], {
<ul class="allplaces"> <ul class="allplaces">
@for p in places { @for p in places {
<li><a href="/place/@p.slug">@p.place_name</a> <li><a href="/place/@p.slug">@p.place_name</a>

View File

@ -1,9 +1,10 @@
@use nickel::Request;
@use rphotos::models::{Photo, Tag}; @use rphotos::models::{Photo, Tag};
@use templates::{page_base, img_link}; @use templates::{page_base, img_link};
@(user: Option<String>, photos: &[Photo], tag: Tag) @(req: &Request, photos: &[Photo], tag: Tag)
@:page_base(&format!("Photos tagged {}", tag.tag_name), &[], &user, { @:page_base(req, &format!("Photos tagged {}", tag.tag_name), &[], {
<div class="group"> <div class="group">
@for p in photos {@:img_link(p)} @for p in photos {@:img_link(p)}
</div> </div>

View File

@ -1,8 +1,9 @@
@use nickel::Request;
@use rphotos::models::Tag; @use rphotos::models::Tag;
@use templates::page_base; @use templates::page_base;
@(user: Option<String>, tags: &[Tag]) @(req: &Request, tags: &[Tag])
@:page_base("Photo tags", &[], &user, { @:page_base(req, "Photo tags", &[], {
<ul class="alltags"> <ul class="alltags">
@for tag in tags { @for tag in tags {
<li><a href="/tag/@tag.slug">@tag.tag_name</a> <li><a href="/tag/@tag.slug">@tag.tag_name</a>