expose signal id in api

...and update api.md which described a different format than before or
after.
This commit is contained in:
Scott Lamb 2019-06-20 12:10:23 -07:00
parent 1c1a823759
commit 644ea4e6ea
3 changed files with 20 additions and 5 deletions

View File

@ -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 time zone. It is usually 24 hours after the start time. It
might be 23 hours or 25 hours during spring forward or fall might be 23 hours or 25 hours during spring forward or fall
back, respectively. back, respectively.
* `signals`: a map of all signals known to the server. Keys are ids. Values are * `signals`: a list of all signals known to the server. Each is a dictionary
dictionaries with the following properties: with the following properties:
* `id`: an integer identifier.
* `shortName`: a unique, human-readable description of the signal * `shortName`: a unique, human-readable description of the signal
* `cameras`: a map of associated cameras' UUIDs to the type of association: * `cameras`: a map of associated cameras' UUIDs to the type of association:
`direct` or `indirect`. See `db/schema.sql` for more description. `direct` or `indirect`. See `db/schema.sql` for more description.
@ -163,8 +164,9 @@ Example response:
}, },
... ...
], ],
"signals": { "signals": [
1: { {
"id": 1,
"shortName": "driveway motion", "shortName": "driveway motion",
"cameras": { "cameras": {
"fd20f7a2-9d69-4cb3-94ed-d51a20c3edfe": "direct" "fd20f7a2-9d69-4cb3-94ed-d51a20c3edfe": "direct"

View File

@ -115,6 +115,7 @@ pub struct Stream<'a> {
#[derive(Serialize)] #[derive(Serialize)]
#[serde(rename_all="camelCase")] #[serde(rename_all="camelCase")]
pub struct Signal<'a> { pub struct Signal<'a> {
pub id: u32,
#[serde(serialize_with = "Signal::serialize_cameras")] #[serde(serialize_with = "Signal::serialize_cameras")]
pub cameras: (&'a db::Signal, &'a db::LockedDatabase), pub cameras: (&'a db::Signal, &'a db::LockedDatabase),
pub source: Uuid, pub source: Uuid,
@ -249,6 +250,7 @@ impl<'a> Stream<'a> {
impl<'a> Signal<'a> { impl<'a> Signal<'a> {
pub fn wrap(s: &'a db::Signal, db: &'a db::LockedDatabase, _include_days: bool) -> Self { pub fn wrap(s: &'a db::Signal, db: &'a db::LockedDatabase, _include_days: bool) -> Self {
Signal { Signal {
id: s.id,
cameras: (s, db), cameras: (s, db),
source: s.source, source: s.source,
type_: s.type_, type_: s.type_,

View File

@ -178,6 +178,7 @@ fn internal_server_err<E: Into<Error>>(err: E) -> Response<Body> {
} }
fn from_base_error(err: base::Error) -> Response<Body> { fn from_base_error(err: base::Error) -> Response<Body> {
info!("base error: {:?}", &err);
let status_code = match err.kind() { let status_code = match err.kind() {
ErrorKind::PermissionDenied | ErrorKind::Unauthenticated => StatusCode::UNAUTHORIZED, ErrorKind::PermissionDenied | ErrorKind::Unauthenticated => StatusCode::UNAUTHORIZED,
ErrorKind::InvalidArgument => StatusCode::BAD_REQUEST, ErrorKind::InvalidArgument => StatusCode::BAD_REQUEST,
@ -708,6 +709,7 @@ impl ServiceInner {
// TODO: real error handling! this assumes all errors are due to lack of // TODO: real error handling! this assumes all errors are due to lack of
// authentication, when they could be logic errors in SQL or such. // 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()) { if let Ok((s, u)) = self.db.lock().authenticate_session(authreq.clone(), &sid.hash()) {
info!("authenticate_session success");
return Ok(Caller { return Ok(Caller {
permissions: s.permissions.clone(), permissions: s.permissions.clone(),
session: Some(json::Session { 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() { if let Some(s) = self.allow_unauthenticated_permissions.as_ref() {
return Ok(Caller { return Ok(Caller {
permissions: s.clone(), permissions: s.clone(),
@ -749,6 +754,7 @@ fn extract_sid(req: &Request<hyper::Body>) -> Option<auth::RawSessionId> {
Some(c) => c, Some(c) => c,
}; };
for mut cookie in hdr.as_bytes().split(|&b| b == b';') { for mut cookie in hdr.as_bytes().split(|&b| b == b';') {
info!("got cookie: {:?}", String::from_utf8_lossy(cookie));
if cookie.starts_with(b" ") { if cookie.starts_with(b" ") {
cookie = &cookie[1..]; cookie = &cookie[1..];
} }
@ -756,6 +762,8 @@ fn extract_sid(req: &Request<hyper::Body>) -> Option<auth::RawSessionId> {
let s = &cookie[2..]; let s = &cookie[2..];
if let Ok(s) = auth::RawSessionId::decode_base64(s) { if let Ok(s) = auth::RawSessionId::decode_base64(s) {
return Some(s); return Some(s);
} else {
info!("decode_base64 failure");
} }
} }
} }
@ -1020,7 +1028,10 @@ impl ::hyper::service::Service for Service {
fn wrap<R>(is_private: bool, r: R) fn wrap<R>(is_private: bool, r: R)
-> Box<dyn Future<Item = Response<Body>, Error = BoxedError> + Send + 'static> -> Box<dyn Future<Item = Response<Body>, Error = BoxedError> + Send + 'static>
where R: Future<Item = Response<Body>, Error = Response<Body>> + Send + 'static { where R: Future<Item = Response<Body>, Error = Response<Body>> + 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 { if is_private {
r.headers_mut().insert("Cache-Control", HeaderValue::from_static("private")); r.headers_mut().insert("Cache-Control", HeaderValue::from_static("private"));
} }