Giter Site home page Giter Site logo

foxbox's Introduction

FoxBox

Build Status Coverage Status License

Technologies

Rust

We're using Rust for the daemon/server.

Currently a fairly recent nightly is required. To determine which version of rust is being used, check the .travis.yml file.

Look for these lines near the top of the file:

rust:
  - nightly-YYYY-MM-DD

It's recommended that you use rustup to install and switch between versions of Rust and available toolchains. You should then be able to then use:

cd /your/path/to/foxbox     # Required, otherwise you might replace rustc for another project
rustup override set nightly-YYYY-MM-DD   # Replace with the correct date you found

After that, you should be all set in regard to compiling the project.

โš ๏ธ Warning

Sometimes, there might be a 1-day-difference between the date shown in .travis.yml and the one reported by rustc. For example nightly-2016-04-06 corresponds to:

$ rustc -V
rustc 1.9.0-nightly (241a9d0dd 2016-04-05)

Build requirements

Dependency Debian/Raspian Fedora Arch OS X (Homebrew)
libupnp libupnp-dev libupnp-devel extra/libupnp libupnp
libssl libssl-dev openssl-devel via base-devel openssl
libev libev-dev libev-devel ? libev
libavahi libavahi-client-dev avahi-devel extra/avahi n.a.
libsqlite3 libsqlite3-dev sqlite-devel core/sqlite sqlite
libespeak libespeak-dev espeak-devel community/espeak espeak
libdbus ? dbus-devel core/libdbus d-bus
libudev libudev-dev ? n.a. n.a.
pkg-config pkg-config ? pkg-config pkg-config

Node

We're using Node to run Selenium tests. Currently v4.x LTS. We plan to stay on stable LTS releases. It's recommended that you use nvm to install and switch between versions of Node.

Target hardware

We're using the Raspberry Pi 2 as a prototyping target (ARMv7). The target operating system is the latest Raspbian which is based on Debian 8.0 Jessie.

Contributing

Note: We're in an iterative prototyping phase of the project. Things are moving really fast so it may be easier to contribute when the dust starts to settle. You've been warned. :shipit:

Forks and feature branches

You should fork the main repo and create pull requests against feature branches of your fork. If you need some guidance with this see:

Setup

$ git clone [email protected]:<username>/foxbox.git
$ cd foxbox

Extra steps for Mac OS X

Foxbox requires some up-to-date libraries (like OpenSSL). In order to make sure you have the correct packages and bindings, we recommend you install brew and run:

brew install openssl libupnp sqlite libev
export LIBRARY_PATH=/usr/local/lib

Build time options

Disable authentication

You may want to disable endpoints authentication to ease your development process. You can do that by removing authentication from the default feature in the Cargo.toml file.

[features]
default = []
authentication = []

Runtime dependencies

Foxbox expects certain executables to be available in the PATH during its execution. Some are third party, others are built as components found in the components directory.

Dependency Optional? Where to find it
dnschallenge No (required for LetsEncrypt DNS-01 challenge) Built as a binary with cargo build in the same target directory as foxbox, see target/<profile> directory
bash No (required for LetsEncrypt client) System package manager

Running the daemon

$ ./run.sh

There are several command line options to start the daemon:

-v, --verbose : Toggle verbose output.
-l, --local-name <hostname> : Set local hostname. Linux only. Requires to be a member of the netdev group.
-p, --port <port>  : Set port to listen on for http connections. [default: 3000]
-w, --wsport <wsport> : Set port to listen on for websocket. [default: 4000]
-d, --profile <path> : Set profile path to store user data.
-r, --register <url> : URL of registration endpoint [default: https://localhost:4443]
-t, --tunnel <tunnel> : Set the tunnel endpoint hostname. If omitted, the tunnel is disabled.
-s, --tunnel-secret <secret> : Set the tunnel shared secret. [default: secret]
-c, --config <namespace;key;value> :  Set configuration override
-h, --help : Print this help menu.
--disable-tls : Run as a plain HTTP server, disabling encryption.
--dns-domain <domain> : Set the top level domain for public DNS. If omitted, the tunnel is disabled
--dns-api <url> : Set the DNS API endpoint

Currently you would likely want to start the daemon like this:

./run.sh -- -r https://knilxof.org:4443 --disable-tls

That means that your foxbox will be using our dev registration server and you will be disabling TLS support. We hope to have out-of-the-box TLS support ready pretty soon, but for now disabling it is the easiest way to run foxbox.

If you want to use TLS you'll likely want to add target/<profile> (eg: target/debug) to your PATH so that dnschallenge is found properly.

Enable tunneling support

If you want to access your foxbox from outside of the network where it is running, you'll need to enable tunneling support. To do that you need to specify the address of the tunneling server that you want to use and the shared secret for this server (if any) to access to your foxbox from outside of your foxbox' local network.

./run.sh -- -r https://knilxof.org:4443 -t knilxof.org:443 -s secret --disable-tls

In the example above, knilxof.org:443 is the location of our tunneling dev server, which has a not-that-secret-anymore value that you'll need to ask for on IRC. You are supposed to substitute <yourname> by the subdomain of your choice, but take into account that you'll need to keep the domain name of the tunneling server, in this case .knilxof.org. Starting the daemon with the command line options above you should be able to access your foxbox through http://yourname.knilxof.org.

Custom local hostname

To run with custom local host name (eg. foxbox.local):

$ ./run.sh -- -l foxbox

NOTE: currently changing of host name is done via avahi-daemon and therefore supported only on Linux platform. To be able to change local host machine name user must be either included into netdev group or allow any other suitable user group to manage host name by adding the following policy to /etc/dbus-1/system.d/avahi-dbus.conf:

<policy group="any_suitable_group_name">
  <allow send_destination="org.freedesktop.Avahi"/>
  <allow receive_sender="org.freedesktop.Avahi"/>
</policy>

Custom Philips Hue nUPNP server

$ ./run.sh -- -c "philips_hue;nupnp_url;http://localhost:8002/"

Interacting with the daemon

Once you have your foxbox up and running you can try our demo application by browsing to https://fxbox.github.io/app.

Alternatively, you can use the foxbox' current REST API

Rust tests

$ cargo test

Selenium tests

You'll need to make sure you install the dependencies via:

$ npm install

Then you can run the Selenium tests via:

$ ./run.sh -- --disable-tls
$ npm run test-selenium

Cross compiling to ARM

There is no one solution for this. The process will be different depending on your operating system. You may be able to build on a RPi, but the larger the application gets, the slower and more painful this will be (not recommended).

Linux

There is support to cross-compile with a Docker image targetting the Raspberry Pi (model 2 and up) in the tools/docker directory.

For an extensive write-up about cross compiling Rust programs see:

Mac OS X

Cross compiling on Mac hasn't been documented. A PR is welcomed. ๐Ÿ˜‰

foxbox's People

Contributors

amarok1412 avatar aosmond avatar arcturus avatar azasypkin avatar cr avatar dhylands avatar fabricedesre avatar ferjm avatar hfiguiere avatar isabelrios avatar jedireza avatar johanlorenzo avatar julienw avatar mcav avatar michaelkohler avatar michielbdejong avatar mikehenrty avatar nojunpark avatar samgiles avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

foxbox's Issues

Each `service` should run in a separate process

A service should probably run in a separate process - easy upgrades, safety from crashes etc. See brief discussion on #22.

We should use https://github.com/servo/ipc-channel, it probably needs extending though:

Servers only accept one client at a time.

These processes probably need some sort of supervisor to keep them alive. As will the tunnel_controller, which will control the lifecycle of the tunnel process.

  • Generic process supervisor API
  • One process per service
  • IPC protocol between service and controller - probably CSP based on ipc-channel

Reduce compile (and test) time: Split FoxBox into many small crates

Initial problem

Changing one single unit test takes about 30s to compile and execute; even if you changed a simple assertion.

Proposed solution

Split FoxBox into many small crates.

Reason: As infered above, FoxBox lives in a single crate. If one line changes (test included), the whole crate is recompiled, no matter if file is a deep dependency or not. A crate is a compilation unit. This means every module is merged within 1 file before being compiled. You can see the generated file by adding -Z unstable-options --pretty expanded to the rustc command line. As a consequence and if I understood correctly, you can only use multi-threading to compile the dependency of a crate, and not the crate itself.

Potential other solution

rustc has gotten a perf regression for about a year: rust-lang/rust#25069 . There has been no activity on this bug for the last 8 months, though.

Investigation details, and discarded suspects

Here below, the default steps are:

  1. Compile a test build from scratch and run them (cargo test)
  2. In one of the unit tests, add/change an assertion to a dummy one (i.e: assert!(true))
  3. time cargo test
  4. Repeat the steps a few more time to see the trend

The tests themselves migh take long to be executed

Comment out all the tests but one. That one should be simple, and redo the process detailed above. After 5 tries, the average time decreased from 30s to ยฑ27s.

Stainless macros might take long to generate the tests structure

Take the simple test you had in the previous part. Transform it to use the standard way of define tests. E.g.:

#[test]
fn my_test() {
  assert!(true);
}

As a consequence, the time remains about the same as in the part above.

Unit tests might only use 1 thread

time cargo test -j4 takes the same time as if -j1 was used. After looking up, 1 crate is compiled in 1 thread.

Unit tests might not take long if they were not living along the production code

Fast way: Checkout this branch.

Longer way:

  1. Comment out the last unit test
  2. Rename src/main.rs to src/lib.rs
  3. Create a file called tests/foo.rs
  4. Import foxbox as an extern crate and use it in a simple test.
  5. Do the regular steps. โš ๏ธ The build was less stable, I got the compiler crash at the first time. Then if I re-run it, the tests are correctly executed. Some warnings were showed. I believe no crash would happen if the warning were fixed.

For each test defined under tests/, a new binary is create. Then, cargo can use more than 1 thread. I'm not sure if this speeds up the compilation. Like said above, the compiler crashed the first time. When it happens, I remain at something around 24s.

Specify the network interface to use to extract the local ip from

In #58 we added the client side to connect to the registry service to allow discovery.

In the case of multiple interfaces connected to internet (weird but possible specially if we are in a rpi2), we should provide a way to hook the discovery of the ip to a selected interface specified by the user via command line parameters.

Hue Adapter instability over high-latency networks

I could crash the hue adapter by running multiple discos in parallel over a packet-lossy WiFi link for several minutes. I didn't run with a backtrace, so I'm just leaving the error message here for now:

thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: "PoisonError { inner: .. }"', ../src/libcore/result.rs:746

After it first appeared, it kept repeating and no more API requests would be handled until restart.

Support third-party adapters

Ideally, we'd like to be able to install drivers/adapters just like apps, using a SmartDevice, perhaps with a reboot.

We need physical units

Consider a IoT heater. Setting it to 100ยบF or 100ยบC will cause very different results and possibly life-threatening accidents.

So when dealing with temperature, we'll need to know which unit is expected by the device and which unit is entered through the UX, then perform conversions as needed.

I'm not sure at which layer we need to do this.

ip_camera_adapter: Make sure ipv6 cameras are supported

The D-Link cameras that we're supporting don't seem to support IPv6, but when we have support for a Raspberry Pi as a camera, then we need to make sure that everything works properly using IPv6 addresses for the camera.

Introduce Telemetry

We'll need to:

  • pull in Telemetry for Rust;
  • fix Telemetry for Rust to match the format used by the server (that's on me, already pretty advanced WIP);
  • instrument the code with Telemetry;
  • get a product id;
  • implement upload;
  • look at graphs.

Not necessarily in this order.

OS X builds broken by multicast_dns

This is a build on OS X:

$ rustc -V
rustc 1.8.0-nightly (c92e910c1 2016-02-21)
$ cargo build
   Compiling multicast_dns v0.1.0 (https://github.com/fxbox/multicast-dns.git?rev=b87f76a#b87f76af)
/Users/cruetten/.multirust/toolchains/nightly-2016-02-22/cargo/git/checkouts/multicast-dns-d51af2fa146824d6/b87f76a/src/adapters/fake/adapter.rs:76:5: 78:6 error: method `add_name_alias` has an incompatible type for trait:
 expected (),
    found struct `collections::string::String` [E0053]
/Users/cruetten/.multirust/toolchains/nightly-2016-02-22/cargo/git/checkouts/multicast-dns-d51af2fa146824d6/b87f76a/src/adapters/fake/adapter.rs:76     fn add_name_alias(&self, host_name: &str) -> String {
/Users/cruetten/.multirust/toolchains/nightly-2016-02-22/cargo/git/checkouts/multicast-dns-d51af2fa146824d6/b87f76a/src/adapters/fake/adapter.rs:77         host_name.to_owned()
/Users/cruetten/.multirust/toolchains/nightly-2016-02-22/cargo/git/checkouts/multicast-dns-d51af2fa146824d6/b87f76a/src/adapters/fake/adapter.rs:78     }
/Users/cruetten/.multirust/toolchains/nightly-2016-02-22/cargo/git/checkouts/multicast-dns-d51af2fa146824d6/b87f76a/src/adapters/fake/adapter.rs:76:5: 78:6 help: run `rustc --explain E0053` to see a detailed explanation
error: aborting due to previous error
Could not compile `multicast_dns`.

To learn more, run the command again with --verbose.

I need to revert to commit 85ca6d9 be able to build.

Integrate Thinkerbell

We need to make Thinkerbell usable from the FoxBox, and hey, while we're at it, let's make it an Adapter, with the following services:

Built-in service

Setters

  • Add a new rule.

One service per rule

Getters

  • Is the rule enabled/disabled?

Setters

  • Remove the rule.
  • Enable/disable the rule.

Blockers

Introduce Crash Monitoring

The Foxbox is supposed to run for several years. So we need to survive crashes โ€“ and fix them.

This means:

  • having a watchdog that can monitor the fxbox process(es) and relaunch them as needed;
  • having a crash reporter to upload crash stacks and metadata.

This bug will probably be split in sub-bugs once we have a clearer idea how to do both.

Proper shutdown sequence

We don't have a shutdown sequence, but we really should have one. Would be useful to stop/restart when updating for instance.

@mcav is that something you would be interested in?

Intermittent test failures in service_router

I'm getting intermittent test failures running cargo test:

  • test service_router::service_router::services::should_make_service_available ... FAILED
  • test service_router::service_router::services::should_return_an_error_if_no_service_was_found ... FAILED
  • test service_router::service_router::services::should_create_list.json ... FAILED

The error is always:

thread 'service_router::service_router::services::should_make_service_available' panicked at 'called Result::unwrap()on anErr value: IronError { error: StringError("Unauthorized"), response: HTTP/1.1 401 Unauthorized Unauthorized

Looks like another init race condition.

ip_camera_adapter: Implement a storage quota

Currently, if you take enough snapshots then it will eventually fill the disk.

Instead we should have something like keep the last N snapshots for each camera (simplest) or implement a max storage (per camera or globally).

foxbox.conf error should be slienced

Upon executing fxbox, following error message is shown:
ERROR:foxbox::config_store: Unable to open configuration file foxbox.conf: No such file or directory (os error 2). According to fabrice, this is actually not an error.
ccing @cr for resolution.

We need an API to monitor changes to the properties of one or more devices

Most Apps (both Control and Monitor) will need to monitor changes to device properties.

For instance:

  • the Remote Control for temperature needs to display the room temperature, in real-time;
  • an Intrusion Monitor App needs to be informed whenever presence sensors change value;
  • a plant watering monitor app needs to determine when the humidity goes below some value;
  • ...

To implement any of these apps, we need an API that will monitor a set of properties of devices and callback each time the value of a given property of a given device enter/leaves some interval (or at each change if no interval is specified).

We need this API at least in WebSocket, as all consumers can be built on top of WebSocket. Ideally, we'd like to provide a concise JS API on top of the WebSocket API. It would be useful to have this API available to Rust code, too, for the sake of the rules engine and Monitor Workers.

I'll describe a pseudo-API in Rust, because I have attempted to do it in other languages and it was actually more complicated:

trait Watcher {
  /// Create a new watcher.
  pub fn new() -> Watcher;

  /// Watch a property of a device.
  ///
  /// If the device is smart enough, 
  ///
  /// # Example
  ///
  /// let witness = watcher.add(&the_terminator,
  ///                                           &InputCapability::DetectSarahConnor,
  ///                                           &Range::any(),
  ///                                           &tx);
  ///
  /// Until `witness` is dropped, whenever property `DetectSarahConnor` of `the_terminator`
  /// changes, the watcher will send a message on `tx`.
  ///
  /// let witness_2 = watcher.add(&the_terminator,
  ///                                               &InputCapability::Ammo,
  ///                                               &Range::boundary(100),
  ///                                                &tx_2);
  ///
  /// Until `witness_2` is dropped, whenever property `Ammo` of `the_terminator` goes
  /// above/beyond 100, the watcher will send a message on `tx_2`.
  pub fn<T> add(&mut self, &Device, &InputCapability<T>, &Range<T>, &Sender<T>) -> Witness;
}

/// A structure used to stop watching a property once it is dropped.
pub struct Witness {
  // ...
}

This depends heavily on our ongoing efforts on Taxonomy.

Note that JS versions of this API will most likely use a addEventListener/removeEventListener pair, rather than channels (unless streams have been standardized by then). The server will monitor WebSocket disconnection to ensure garbage-collection of Watcher.

Cc @mcav, @jedireza, @davidflanagan .

ip_camera_adapter: Persist cameras

We should persist the discovered cameras in a database so that we don't need to wait for upnp before needing to access a camera.

The database would also need to store the username and password needed to access the camera, as well as a user-friendly name for the UI.

(Very) basic foxbox discovery (includes setup app to foxbox)

To get started with the "Discovering the Foxbox (includes setup app to foxbox)", I will try to implement the following super-basic and non-secure FTU flow:

  • Connect the foxbox via ethernet
  • Browse to http://foxlink.local/
  • It shows you a page where you set the admin password
  • When you submit the html form, it shows a page that suggests hyperlinks to a http-hosted admin app.

To do:

  • Set hostname to 'foxlink.local' 'foxbox.local' during RPi image build process.
  • Update https://github.com/fxbox/foxbox/blob/master/static/index.html adding the 'set admin password' form which does an xhr api call and then shows a http hyperlink to our basic web app.
  • Add basic user manual to docs describing the setup flow.
  • Add basic UI test that sets the admin password and checks that the hyperlink to the basic web app is shown on success.
  • Manual testing on an actual RPi.

Using dimmable light (LWB006) will cause JSON parse error

Following is the JSON info of the dimmable light sent from the philips hub:
"1":{
"state": {
"on":false,
"bri":0,
"alert":"none",
"reachable":false
},
"type": "Dimmable light",
"name": "Hue white lamp 1",
"modelid": "LWB006",
"manufacturername": "Philips",
"uniqueid":"00:17:88:01:10:34:95:dd-0b",
"swversion": "",
"pointsymbol": {
"1":"none", "2":"none", "3":"none", "4":"none", "5":"none", "6":"none", "7":"none", "8":"none"
}

And this is the JSON info of a color light:
"1": {
"state": {
"on": true,
"bri": 254,
"hue": 14910,
"sat": 144,
"effect": "none",
"xy": [
0.4596,
0.4105
],
"ct": 370,
"alert": "none",
"colormode": "ct",
"reachable": false
},
"type": "Extended color light",
"name": "Hue color lamp 1",
"modelid": "LCT007",
"manufacturername": "Philips",
"uniqueid": "00:17:88:01:10:41:87:79-0b",
"swversion": "66014919"
}

because the dimmable light is missing some fields compared to the color light, it will cause foxbox to have a JSON parse error since it appears that there is only one SettingsLightState in src/adapters/philips_hue/hub_api/structs.rs

We need local time

Many use cases rely on the local time, foxbox-side. This means that we need to be able to set the local time.

Mock authorization flow

Authorization to 3rd party apps is outside of the scope of the prototype. However, we know that we don't want 3rd party apps asking users to enter their username & password (iif we finally use user&pass...), so we can at least mock an authorization flow where the user is redirected to the box to enter her credentials and we redirect the user back to the app with a fake auth token.

Concerned about requiring nightly Rust

I just wanted to voice a concern about using features that require us to use nightly Rust. I'd prefer us to only use features available in stable Rust so we can make cutting releases easy and not end up in a situation where we have to refactor (backwards).

For example in #29 we chose to use the docopt! macro when we could've just kept the original semantics and got the same functionality.

It's not only the docopt! macro. There are features in the serde_json crate too IIRC. I was planning to remove serde_json and use rustc_serialize::json instead.

Now that a lot of us are adding code I think we should be aware and agree how best to handle this, even if that decision is to keep nightly Rust.

Thoughts?

We need an API to find out which devices are available

We need to provide an API that lets applications find out which devices are available for a specific purpose. This API will be used both server-side (in the rules engine, in Monitor Workers) and client-side (in client web apps).

We need this API at least in REST, as all consumers can be built on top of REST. Ideally, we'd like to provide a concise JS API on top of the REST API. It would be useful to have this API available to Rust code, too, for the sake of the rules engine and possibly Monitor Workers.

I'll describe a possible API in Rust, because I have attempted to do it in other languages and it was actually more complicated:

/// Get the list of all available devices that can fulfill a service.
///
/// # Example
///
///  let devices = get_devices(DeviceKind::RobotFromTheFuture,
///                            &vec![InputCapability::DetectSarahConnor, InputCapability::DetectJohnConnor, InputCapability::IsControlledBySkynet],
///                            &vec![OutputCapability::Terminate]);
///
/// for terminator in devices {
///     // ...
/// }
fn get_devices(&DeviceKind, &Vec<InputCapability>, &Vec<OutputCapability>) -> Vec<Device>

This depends heavily on our ongoing efforts on Taxonomy.

Note that JS versions of this API will return a Promise, rather than blocking.

Scripts for registering/renewing LetsEncrypt certs and setting/updating DNS records

Deploy-time:

  • Register LetsEncrypt certs for a.<hash>.knilxof.org, b.<hash>.knilxof.org, local.<hash>.knilxof.org, and remote.<hash>.knilxof.org.
  • Set a.<hash>.knilxof.org and local.<hash>.knilxof.org A records to current local IP address.
  • Set remote.<hash>.knilxof.org A record to the tunnel's public IP address.
  • Set current preferred mirror to a.<hash>.knilxof.org (see below).

Run-time when certs are about to expire:

  • Renew LetsEncrypt certs for a.<hash>.knilxof.org, b.<hash>.knilxof.org, local.<hash>.knilxof.org, and remote.<hash>.knilxof.org.

Run-time when local IP address changes (if current preferred mirror is a.):

  • Set b.<hash>.knilxof.org and local.<hash>.knilxof.org A record to new local IP address.
  • Set current preferred mirror to b.<hash>.knilxof.org.
  • Remove A record for a.<hash>.knilxof.org.

Run-time when local IP address changes (if current preferred mirror is b.):

  • Set a.<hash>.knilxof.org and local.<hash>.knilxof.org A record to new local IP address.
  • Set current preferred mirror to a.<hash>.knilxof.org.
  • Remove A record for b.<hash>.knilxof.org.

On https://local.<hash>.knilxof.org/ we just publish the list of mirrors (a. and b.), and which of them is currently live, and the client remembers this, then redirects to the live one.

When the Box becomes unreachable on the current mirror, the client tries another one from the list.

This way, the client only queries DNS for local. when scanning the QR code, and not during normal operation, so by the next time the Box's IP address changes, it will have been flushed from DNS cache.

When using the registration server instead of the QR code, the Box could even announce the current preferred mirror directly to the registration-server.

If we see the IP switches too often, we could also rotate >2 mirrors .

API end-point for discovering public tunnel address

At first, the App connects to the Box on its local IP (as discovered through nupnp). Once the App has successfully authenticated, it should have some way to ask the Box for its tunnel address (if any).

Authentication seems broken

I did a git clean -x -d -f to remove all files not checked into github

I then did a cargo build

I then browsed to http://localhost:3000 and was asked to enter my admin password (rather than the ask/confirm). Checking the filesystem, users_db.sqlite doesn't even exist yet. And of course, because I haven't set a password, all passwords come back as unauthorized.

So something about authentication seems totally broken.

Tagging @ferjm so that he sees this.

Running with RUST_LOG=foxbox=trace cargo run yields no interesting information.

If I enter a password and click Signin then I get back an Unauthorized error, and an empty users_db.sqlite is created. If I browse the database using sqlitebrowser it shows no rows in the table.

Self-signed cert

Building on #13, switch from http to https.

After I get that working, I'll look at improving it further, e.g. avoid bad UX of adding the exception for the self-signed cert, and not requiring the connection to the router to be via ethernet.

Split setup and login flows.

We shouldn't be showing the setup or login screen depending on the session token that is stored in the browser. Instead, the server should decide which flow to show based on the existence of an admin account.

Intermittent kcov failures

I'm seeing quite a lot of intermittent failures from kcov. It looks like sometimes it can't find the foxbox executable. @JohanLorenzo does that ring a bell?

Here's a log extract with such a failure:

Scanning dependencies of target kcov
[ 25%] Building CXX object src/CMakeFiles/kcov.dir/capabilities.cc.o
[ 27%] Building CXX object src/CMakeFiles/kcov.dir/collector.cc.o
[ 30%] Building CXX object src/CMakeFiles/kcov.dir/configuration.cc.o
[ 32%] Building CXX object src/CMakeFiles/kcov.dir/engine-factory.cc.o
[ 35%] Building CXX object src/CMakeFiles/kcov.dir/engines/bash-engine.cc.o
[ 37%] Building CXX object src/CMakeFiles/kcov.dir/engines/gcov-engine.cc.o
[ 40%] Building CXX object src/CMakeFiles/kcov.dir/engines/python-engine.cc.o
[ 42%] Building CXX object src/CMakeFiles/kcov.dir/filter.cc.o
[ 45%] Building CXX object src/CMakeFiles/kcov.dir/gcov.cc.o
[ 47%] Building CXX object src/CMakeFiles/kcov.dir/main.cc.o
[ 50%] Building CXX object src/CMakeFiles/kcov.dir/merge-file-parser.cc.o
[ 52%] Building CXX object src/CMakeFiles/kcov.dir/output-handler.cc.o
[ 55%] Building CXX object src/CMakeFiles/kcov.dir/parsers/dummy-address-verifier.cc.o
[ 57%] Building CXX object src/CMakeFiles/kcov.dir/parser-manager.cc.o
[ 60%] Building CXX object src/CMakeFiles/kcov.dir/reporter.cc.o
[ 62%] Building CXX object src/CMakeFiles/kcov.dir/utils.cc.o
[ 65%] Building CXX object src/CMakeFiles/kcov.dir/writers/cobertura-writer.cc.o
[ 67%] Building CXX object src/CMakeFiles/kcov.dir/writers/coveralls-writer.cc.o
[ 70%] Building CXX object src/CMakeFiles/kcov.dir/writers/html-writer.cc.o
[ 72%] Building CXX object src/CMakeFiles/kcov.dir/writers/writer-base.cc.o
[ 75%] Building CXX object src/CMakeFiles/kcov.dir/engines/ptrace.cc.o
[ 77%] Building CXX object src/CMakeFiles/kcov.dir/engines/kernel-engine.cc.o
[ 80%] Building CXX object src/CMakeFiles/kcov.dir/parsers/elf-parser.cc.o
[ 82%] Building CXX object src/CMakeFiles/kcov.dir/solib-handler.cc.o
[ 85%] Building C object src/CMakeFiles/kcov.dir/solib-parser/phdr_data.c.o
[ 87%] Building CXX object src/CMakeFiles/kcov.dir/library.cc.o
[ 90%] Building CXX object src/CMakeFiles/kcov.dir/bash-redirector-library.cc.o
[ 92%] Building CXX object src/CMakeFiles/kcov.dir/python-helper.cc.o
[ 95%] Building CXX object src/CMakeFiles/kcov.dir/bash-helper.cc.o
[ 97%] Building CXX object src/CMakeFiles/kcov.dir/html-data-files.cc.o
[100%] Building C object src/CMakeFiles/kcov.dir/version.c.o
Linking CXX executable kcov
[100%] Built target kcov
+cd -
/home/travis/build/fxbox/foxbox
+compile_foxbox_with_dead_code
++cargo test --no-run --verbose
++sed --quiet 's/.*`\(rustc .* --test .*\)`.*/\1/p'
src/controller.rs:207:5: 207:23 warning: struct field is never used: `controller`, #[warn(dead_code)] on by default
src/controller.rs:207     controller: FoxBox,
                          ^~~~~~~~~~~~~~~~~~
+RUSTC_COMMAND='rustc src/main.rs --crate-name foxbox --crate-type bin -g --test --cfg feature=\"default\" --cfg feature=\"authentication\" -C metadata=a9cabe0dc62944c7 -C extra-filename=-a9cabe0dc62944c7 --out-dir /home/travis/build/fxbox/foxbox/target/debug --emit=dep-info,link -L dependency=/home/travis/build/fxbox/foxbox/target/debug -L dependency=/home/travis/build/fxbox/foxbox/target/debug/deps --extern iron_test=/home/travis/build/fxbox/foxbox/target/debug/deps/libiron_test-1e845ce178cfe460.rlib --extern mount=/home/travis/build/fxbox/foxbox/target/debug/deps/libmount-354041ca4f0dc0b3.rlib --extern stainless=/home/travis/build/fxbox/foxbox/target/debug/deps/libstainless-ba9d17ed65ee54dc.so --extern crypto=/home/travis/build/fxbox/foxbox/target/debug/deps/libcrypto-97872ea539a059cd.rlib --extern ws=/home/travis/build/fxbox/foxbox/target/debug/deps/libws-d2f82be550680a28.rlib --extern xml=/home/travis/build/fxbox/foxbox/target/debug/deps/libxml-7f9311e89a955d7f.rlib --extern multicast_dns=/home/travis/build/fxbox/foxbox/target/debug/deps/libmulticast_dns-3de45b741afde594.rlib --extern serde_json=/home/travis/build/fxbox/foxbox/target/debug/deps/libserde_json-53d3e106cfb5207d.rlib --extern env_logger=/home/travis/build/fxbox/foxbox/target/debug/deps/libenv_logger-1963490441847a73.rlib --extern staticfile=/home/travis/build/fxbox/foxbox/target/debug/deps/libstaticfile-b1081474074fbce3.rlib --extern docopt_macros=/home/travis/build/fxbox/foxbox/target/debug/deps/libdocopt_macros-c07846471a9a5fbf.so --extern serde=/home/travis/build/fxbox/foxbox/target/debug/deps/libserde-50d4f336f4dbf399.rlib --extern unicase=/home/travis/build/fxbox/foxbox/target/debug/deps/libunicase-f807684b8c0dd9b5.rlib --extern clippy=/home/travis/build/fxbox/foxbox/target/debug/deps/libclippy-ab1b8e06a6a9105d.so --extern iron=/home/travis/build/fxbox/foxbox/target/debug/deps/libiron-291b005d9cf352e3.rlib --extern regex=/home/travis/build/fxbox/foxbox/target/debug/deps/libregex-1a3a0af90d20fdaf.rlib --extern router=/home/travis/build/fxbox/foxbox/target/debug/deps/librouter-eafcd78868655893.rlib --extern log=/home/travis/build/fxbox/foxbox/target/debug/deps/liblog-35b3ccf0458f5f8d.rlib --extern hyper=/home/travis/build/fxbox/foxbox/target/debug/deps/libhyper-93452a301949bf5b.rlib --extern rustc_serialize=/home/travis/build/fxbox/foxbox/target/debug/deps/librustc_serialize-ee878f05d7532512.rlib --extern foxbox_users=/home/travis/build/fxbox/foxbox/target/debug/deps/libfoxbox_users-b57eb8ad4eab3730.rlib --extern url=/home/travis/build/fxbox/foxbox/target/debug/deps/liburl-f77b9d6b20364f2d.rlib --extern uuid=/home/travis/build/fxbox/foxbox/target/debug/deps/libuuid-541c72a101b6b06d.rlib --extern serde_macros=/home/travis/build/fxbox/foxbox/target/debug/deps/libserde_macros-1109154aa8830403.so --extern time=/home/travis/build/fxbox/foxbox/target/debug/deps/libtime-1aeb304d6ae03c62.rlib --extern docopt=/home/travis/build/fxbox/foxbox/target/debug/deps/libdocopt-584bf737f155d9e1.rlib --extern get_if_addrs=/home/travis/build/fxbox/foxbox/target/debug/deps/libget_if_addrs-8d1ccb2dabd39bd9.rlib --extern mio=/home/travis/build/fxbox/foxbox/target/debug/deps/libmio-b7b0ae0672144946.rlib --extern libc=/home/travis/build/fxbox/foxbox/target/debug/deps/liblibc-f1a4f924481a5b7d.rlib -L native=/home/travis/build/fxbox/foxbox/target/debug/build/openssl-0c4b4a6cb21fd5d4/out -L native=/home/travis/build/fxbox/foxbox/target/debug/build/openssl-sys-extras-3867c37901e58a23/out -L native=/usr/lib/x86_64-linux-gnu -L native=/home/travis/build/fxbox/foxbox/target/debug/build/rust-crypto-97872ea539a059cd/out -L native=/usr/lib/x86_64-linux-gnu'
+eval rustc src/main.rs --crate-name foxbox --crate-type bin -g --test --cfg 'feature=\"default\"' --cfg 'feature=\"authentication\"' -C metadata=a9cabe0dc62944c7 -C extra-filename=-a9cabe0dc62944c7 --out-dir /home/travis/build/fxbox/foxbox/target/debug --emit=dep-info,link -L dependency=/home/travis/build/fxbox/foxbox/target/debug -L dependency=/home/travis/build/fxbox/foxbox/target/debug/deps --extern iron_test=/home/travis/build/fxbox/foxbox/target/debug/deps/libiron_test-1e845ce178cfe460.rlib --extern mount=/home/travis/build/fxbox/foxbox/target/debug/deps/libmount-354041ca4f0dc0b3.rlib --extern stainless=/home/travis/build/fxbox/foxbox/target/debug/deps/libstainless-ba9d17ed65ee54dc.so --extern crypto=/home/travis/build/fxbox/foxbox/target/debug/deps/libcrypto-97872ea539a059cd.rlib --extern ws=/home/travis/build/fxbox/foxbox/target/debug/deps/libws-d2f82be550680a28.rlib --extern xml=/home/travis/build/fxbox/foxbox/target/debug/deps/libxml-7f9311e89a955d7f.rlib --extern multicast_dns=/home/travis/build/fxbox/foxbox/target/debug/deps/libmulticast_dns-3de45b741afde594.rlib --extern serde_json=/home/travis/build/fxbox/foxbox/target/debug/deps/libserde_json-53d3e106cfb5207d.rlib --extern env_logger=/home/travis/build/fxbox/foxbox/target/debug/deps/libenv_logger-1963490441847a73.rlib --extern staticfile=/home/travis/build/fxbox/foxbox/target/debug/deps/libstaticfile-b1081474074fbce3.rlib --extern docopt_macros=/home/travis/build/fxbox/foxbox/target/debug/deps/libdocopt_macros-c07846471a9a5fbf.so --extern serde=/home/travis/build/fxbox/foxbox/target/debug/deps/libserde-50d4f336f4dbf399.rlib --extern unicase=/home/travis/build/fxbox/foxbox/target/debug/deps/libunicase-f807684b8c0dd9b5.rlib --extern clippy=/home/travis/build/fxbox/foxbox/target/debug/deps/libclippy-ab1b8e06a6a9105d.so --extern iron=/home/travis/build/fxbox/foxbox/target/debug/deps/libiron-291b005d9cf352e3.rlib --extern regex=/home/travis/build/fxbox/foxbox/target/debug/deps/libregex-1a3a0af90d20fdaf.rlib --extern router=/home/travis/build/fxbox/foxbox/target/debug/deps/librouter-eafcd78868655893.rlib --extern log=/home/travis/build/fxbox/foxbox/target/debug/deps/liblog-35b3ccf0458f5f8d.rlib --extern hyper=/home/travis/build/fxbox/foxbox/target/debug/deps/libhyper-93452a301949bf5b.rlib --extern rustc_serialize=/home/travis/build/fxbox/foxbox/target/debug/deps/librustc_serialize-ee878f05d7532512.rlib --extern foxbox_users=/home/travis/build/fxbox/foxbox/target/debug/deps/libfoxbox_users-b57eb8ad4eab3730.rlib --extern url=/home/travis/build/fxbox/foxbox/target/debug/deps/liburl-f77b9d6b20364f2d.rlib --extern uuid=/home/travis/build/fxbox/foxbox/target/debug/deps/libuuid-541c72a101b6b06d.rlib --extern serde_macros=/home/travis/build/fxbox/foxbox/target/debug/deps/libserde_macros-1109154aa8830403.so --extern time=/home/travis/build/fxbox/foxbox/target/debug/deps/libtime-1aeb304d6ae03c62.rlib --extern docopt=/home/travis/build/fxbox/foxbox/target/debug/deps/libdocopt-584bf737f155d9e1.rlib --extern get_if_addrs=/home/travis/build/fxbox/foxbox/target/debug/deps/libget_if_addrs-8d1ccb2dabd39bd9.rlib --extern mio=/home/travis/build/fxbox/foxbox/target/debug/deps/libmio-b7b0ae0672144946.rlib --extern libc=/home/travis/build/fxbox/foxbox/target/debug/deps/liblibc-f1a4f924481a5b7d.rlib -L native=/home/travis/build/fxbox/foxbox/target/debug/build/openssl-0c4b4a6cb21fd5d4/out -L native=/home/travis/build/fxbox/foxbox/target/debug/build/openssl-sys-extras-3867c37901e58a23/out -L native=/usr/lib/x86_64-linux-gnu -L native=/home/travis/build/fxbox/foxbox/target/debug/build/rust-crypto-97872ea539a059cd/out -L native=/usr/lib/x86_64-linux-gnu -C link-dead-code
++rustc src/main.rs --crate-name foxbox --crate-type bin -g --test --cfg 'feature="default"' --cfg 'feature="authentication"' -C metadata=a9cabe0dc62944c7 -C extra-filename=-a9cabe0dc62944c7 --out-dir /home/travis/build/fxbox/foxbox/target/debug --emit=dep-info,link -L dependency=/home/travis/build/fxbox/foxbox/target/debug -L dependency=/home/travis/build/fxbox/foxbox/target/debug/deps --extern iron_test=/home/travis/build/fxbox/foxbox/target/debug/deps/libiron_test-1e845ce178cfe460.rlib --extern mount=/home/travis/build/fxbox/foxbox/target/debug/deps/libmount-354041ca4f0dc0b3.rlib --extern stainless=/home/travis/build/fxbox/foxbox/target/debug/deps/libstainless-ba9d17ed65ee54dc.so --extern crypto=/home/travis/build/fxbox/foxbox/target/debug/deps/libcrypto-97872ea539a059cd.rlib --extern ws=/home/travis/build/fxbox/foxbox/target/debug/deps/libws-d2f82be550680a28.rlib --extern xml=/home/travis/build/fxbox/foxbox/target/debug/deps/libxml-7f9311e89a955d7f.rlib --extern multicast_dns=/home/travis/build/fxbox/foxbox/target/debug/deps/libmulticast_dns-3de45b741afde594.rlib --extern serde_json=/home/travis/build/fxbox/foxbox/target/debug/deps/libserde_json-53d3e106cfb5207d.rlib --extern env_logger=/home/travis/build/fxbox/foxbox/target/debug/deps/libenv_logger-1963490441847a73.rlib --extern staticfile=/home/travis/build/fxbox/foxbox/target/debug/deps/libstaticfile-b1081474074fbce3.rlib --extern docopt_macros=/home/travis/build/fxbox/foxbox/target/debug/deps/libdocopt_macros-c07846471a9a5fbf.so --extern serde=/home/travis/build/fxbox/foxbox/target/debug/deps/libserde-50d4f336f4dbf399.rlib --extern unicase=/home/travis/build/fxbox/foxbox/target/debug/deps/libunicase-f807684b8c0dd9b5.rlib --extern clippy=/home/travis/build/fxbox/foxbox/target/debug/deps/libclippy-ab1b8e06a6a9105d.so --extern iron=/home/travis/build/fxbox/foxbox/target/debug/deps/libiron-291b005d9cf352e3.rlib --extern regex=/home/travis/build/fxbox/foxbox/target/debug/deps/libregex-1a3a0af90d20fdaf.rlib --extern router=/home/travis/build/fxbox/foxbox/target/debug/deps/librouter-eafcd78868655893.rlib --extern log=/home/travis/build/fxbox/foxbox/target/debug/deps/liblog-35b3ccf0458f5f8d.rlib --extern hyper=/home/travis/build/fxbox/foxbox/target/debug/deps/libhyper-93452a301949bf5b.rlib --extern rustc_serialize=/home/travis/build/fxbox/foxbox/target/debug/deps/librustc_serialize-ee878f05d7532512.rlib --extern foxbox_users=/home/travis/build/fxbox/foxbox/target/debug/deps/libfoxbox_users-b57eb8ad4eab3730.rlib --extern url=/home/travis/build/fxbox/foxbox/target/debug/deps/liburl-f77b9d6b20364f2d.rlib --extern uuid=/home/travis/build/fxbox/foxbox/target/debug/deps/libuuid-541c72a101b6b06d.rlib --extern serde_macros=/home/travis/build/fxbox/foxbox/target/debug/deps/libserde_macros-1109154aa8830403.so --extern time=/home/travis/build/fxbox/foxbox/target/debug/deps/libtime-1aeb304d6ae03c62.rlib --extern docopt=/home/travis/build/fxbox/foxbox/target/debug/deps/libdocopt-584bf737f155d9e1.rlib --extern get_if_addrs=/home/travis/build/fxbox/foxbox/target/debug/deps/libget_if_addrs-8d1ccb2dabd39bd9.rlib --extern mio=/home/travis/build/fxbox/foxbox/target/debug/deps/libmio-b7b0ae0672144946.rlib --extern libc=/home/travis/build/fxbox/foxbox/target/debug/deps/liblibc-f1a4f924481a5b7d.rlib -L native=/home/travis/build/fxbox/foxbox/target/debug/build/openssl-0c4b4a6cb21fd5d4/out -L native=/home/travis/build/fxbox/foxbox/target/debug/build/openssl-sys-extras-3867c37901e58a23/out -L native=/usr/lib/x86_64-linux-gnu -L native=/home/travis/build/fxbox/foxbox/target/debug/build/rust-crypto-97872ea539a059cd/out -L native=/usr/lib/x86_64-linux-gnu -C link-dead-code
src/controller.rs:207:5: 207:23 warning: struct field is never used: `controller`, #[warn(dead_code)] on by default
src/controller.rs:207     controller: FoxBox,
                          ^~~~~~~~~~~~~~~~~~
+run_tests_and_coverage
++find /home/travis/build/fxbox/foxbox/tools/../target/debug -maxdepth 1 -executable -name 'foxbox-*'
+FOXBOX_UNIT_TEST_BINARY='/home/travis/build/fxbox/foxbox/tools/../target/debug/foxbox-5fe0ccd2f25574e9
/home/travis/build/fxbox/foxbox/tools/../target/debug/foxbox-a9cabe0dc62944c7'
+RUST_BACKTRACE=1
+/home/travis/build/fxbox/foxbox/tools/../target/kcov/kcov-30/src/kcov '--exclude-path=~/.cargo,                    /home/travis/build/fxbox/foxbox/tools/../src/stubs,                    /home/travis/build/fxbox/foxbox/tools/../target' --coveralls-id=114424535 /home/travis/build/fxbox/foxbox/tools/../target/coverage-report/ '/home/travis/build/fxbox/foxbox/tools/../target/debug/foxbox-5fe0ccd2f25574e9
/home/travis/build/fxbox/foxbox/tools/../target/debug/foxbox-a9cabe0dc62944c7'
kcov: error: Can't find or open /home/travis/build/fxbox/foxbox/tools/../target/debug/foxbox-5fe0ccd2f25574e9
/home/travis/build/fxbox/foxbox/tools/../target/debug/foxbox-a9cabe0dc62944c7

The command "$TRAVIS_BUILD_DIR/tools/execute-unit-tests-with-coverage" exited with 1.
$ jshint static/main/js/*.js static/setup/js/*.js test/selenium/*.js

The command "jshint static/main/js/*.js static/setup/js/*.js test/selenium/*.js" exited with 0.
$ (cargo run -- -n $BOX_HOST_NAME -p $BOX_PORT &> /dev/null &) ; npm test

> [email protected] test /home/travis/build/fxbox/foxbox
> rm -f *sqlite && ./node_modules/.bin/mocha test/selenium/*_test.js

CORS headers on login 401

When you use the wrong 'admin' password to try to log in to the app, you see a NetworkError instead of a 'Wrong password' error, and a CORS-related error in the console:

screen shot 2016-03-07 at 10 08 55

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.