diff --git a/design/api.md b/design/api.md index 9d73329..eab7d08 100644 --- a/design/api.md +++ b/design/api.md @@ -104,8 +104,9 @@ The `application/json` response will have a dict as follows: time zone. It is usually 24 hours after the start time. It might be 23 hours or 25 hours during spring forward or fall back, respectively. -* `signals`: a map of all signals known to the server. Keys are ids. Values are - dictionaries with the following properties: +* `signals`: a list of all signals known to the server. Each is a dictionary + with the following properties: + * `id`: an integer identifier. * `shortName`: a unique, human-readable description of the signal * `cameras`: a map of associated cameras' UUIDs to the type of association: `direct` or `indirect`. See `db/schema.sql` for more description. @@ -163,8 +164,9 @@ Example response: }, ... ], - "signals": { - 1: { + "signals": [ + { + "id": 1, "shortName": "driveway motion", "cameras": { "fd20f7a2-9d69-4cb3-94ed-d51a20c3edfe": "direct" diff --git a/src/json.rs b/src/json.rs index 7021fa3..d0975aa 100644 --- a/src/json.rs +++ b/src/json.rs @@ -115,6 +115,7 @@ pub struct Stream<'a> { #[derive(Serialize)] #[serde(rename_all="camelCase")] pub struct Signal<'a> { + pub id: u32, #[serde(serialize_with = "Signal::serialize_cameras")] pub cameras: (&'a db::Signal, &'a db::LockedDatabase), pub source: Uuid, @@ -249,6 +250,7 @@ impl<'a> Stream<'a> { impl<'a> Signal<'a> { pub fn wrap(s: &'a db::Signal, db: &'a db::LockedDatabase, _include_days: bool) -> Self { Signal { + id: s.id, cameras: (s, db), source: s.source, type_: s.type_, diff --git a/src/web.rs b/src/web.rs index 6c7efcc..189cfa1 100644 --- a/src/web.rs +++ b/src/web.rs @@ -178,6 +178,7 @@ fn internal_server_err>(err: E) -> Response { } fn from_base_error(err: base::Error) -> Response { + info!("base error: {:?}", &err); let status_code = match err.kind() { ErrorKind::PermissionDenied | ErrorKind::Unauthenticated => StatusCode::UNAUTHORIZED, ErrorKind::InvalidArgument => StatusCode::BAD_REQUEST, @@ -708,6 +709,7 @@ impl ServiceInner { // TODO: real error handling! this assumes all errors are due to lack of // authentication, when they could be logic errors in SQL or such. if let Ok((s, u)) = self.db.lock().authenticate_session(authreq.clone(), &sid.hash()) { + info!("authenticate_session success"); return Ok(Caller { permissions: s.permissions.clone(), session: Some(json::Session { @@ -716,8 +718,11 @@ impl ServiceInner { }), }); } + info!("authenticate_session failed"); } + info!("fallthrough"); + if let Some(s) = self.allow_unauthenticated_permissions.as_ref() { return Ok(Caller { permissions: s.clone(), @@ -749,6 +754,7 @@ fn extract_sid(req: &Request) -> Option { Some(c) => c, }; for mut cookie in hdr.as_bytes().split(|&b| b == b';') { + info!("got cookie: {:?}", String::from_utf8_lossy(cookie)); if cookie.starts_with(b" ") { cookie = &cookie[1..]; } @@ -756,6 +762,8 @@ fn extract_sid(req: &Request) -> Option { let s = &cookie[2..]; if let Ok(s) = auth::RawSessionId::decode_base64(s) { return Some(s); + } else { + info!("decode_base64 failure"); } } } @@ -1020,7 +1028,10 @@ impl ::hyper::service::Service for Service { fn wrap(is_private: bool, r: R) -> Box, Error = BoxedError> + Send + 'static> where R: Future, Error = Response> + Send + 'static { - return Box::new(r.or_else(|e| Ok(e)).map(move |mut r| { + return Box::new(r.or_else(|e| { + info!("returning error status {:?}", e.status()); + Ok(e) + }).map(move |mut r| { if is_private { r.headers_mut().insert("Cache-Control", HeaderValue::from_static("private")); }