kaustavha / gravity-interview

Gravitational interview - full stack challenge

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Getting started

3 main components, front-end, server, fakeiot data generator. and a DB.

  1. postgres setup https://docs.docker.com/samples/library/postgres/ Note: The pass is base64 mysqlpassword
docker run -d -p 5432:5432 --name my-postgres2 -e POSTGRES_PASSWORD=bXlzcWxwYXNzd29yZAo= postgres

psql -h localhost -p 5432 -U postgres -W
CREATE DATABASE iotdb;
\l
\q

  1. Go server
cd $GOPATH
// git clone this repo into src or install it similiar to fakeiot against the github url via go get

// install deps
go get github.com/jinzhu/gorm
go install github.com/jinzhu/gorm

// cd into the repo
go install && $GOPATH/bin/gravitational_interview
  1. Frontend
cd ui/
npm i
npm start
  1. FakeIOT: Startup the data generator
cd $GOPATH
go get github.com/gravitational/fakeiot
go install github.com/gravitational/fakeiot

$GOPATH/bin/fakeiot --token="YmVhcmVydG9rZW5wYXNzd29yZAo=" --url="https://127.0.0.1:8443" --ca-cert=./fixtures/ca-cert.pem test

$GOPATH/bin/fakeiot --token="YmVhcmVydG9rZW5wYXNzd29yZAo=" --url="https://127.0.0.1:8443" --ca-cert=./fixtures/ca-cert.pem run --period=100s --freq=1s --users=100 --account-id="5a28fa21-c70d-4bf3-b4c4-c4b109d5d269"

Note: To recreate the password

echo bearertokenpassword | base64  

Likewise the defaultSigningKey is echo mysecretsigningkey | base64 If the server is running you should see some output, also if youre logging into a DB you should see it update.


TLS / CACERT notes

Using the mock cert and keys from gravitational/fakeiot/fixtures. We'll need to copy over the fixtures dir into this projects root.

$GOPATH/bin/fakeiot --token="shmoken" --url="https://127.0.0.1:8443" --ca-cert=./fixtures/ca-cert.pem test

$GOPATH/bin/fakeiot --token=shmoken --url="https://127.0.0.1:8443" --ca-cert=./fixtures/ca-cert.pem run --period=10s --freq=1s --users=10

Basic Architecture

The front-end is scaffolded using create-react-app and then the interview html and css is added and minimally reactified. Front-end runs on :3000.
Using react-router-dom for routing. Haven't dug into the internals of create-react-app but ES6/7 features work fine :). Also using regular CSS.

The create-react-app development server has a proxy setting set in package.json to forward unknown routes to through to the backend running on :8000.

We store the admin account and its usercount, upgrade status etc in the DB
The server listens for posts from metrics and stores them in a table, and updates the admin account every time

The server is written in Go and used gorm


Testing

Testing philosophy: Test the top level to-be-consumed API, and test for the different cases handled by internals For server test: go test
For front-end tests: cd ui && npm test


Debugging react tests

The first issue you might face will be a complaint that the watcher can only run on Darwin: Soln: expo/expo#854

Second issue: Tests fail with:

TypeError: Cannot assign to read 
only property 'Symbol(Symbol.toString
Tag)' of object '#<process>'

Soln: jestjs/jest#8069 Use this: https://github.com/creationix/nvm And nvm use 11.10.1. Tim Caswell / Creationix the author can be one of my references too I think, I worked p retty closely with him back at Rackspace.


TODO

  • [] Security:

    • Env vars instead of hardcode
    • More secure secrets and passwords
  • front-end:

    • clean up old create-react-app scaffold code
      • auth storage
        • store in local storage - check if there and add to x-session-token header when sending reqs to server/ on first app load; on fail or logout selete the token from local storage or try cookies
      • securely send login form data to server? in header...
      • auto-redirect to db if valid auth in storage
      • websocket or quickpoll soln for dashboard progress updates
      • reactively showing prompts and alerts
      • 1 unit test
  • back-end

    • auth handling with bearer tokens in middleware and finished login route
    • dashboard route with(out) websocket handling
    • post handler from fakeiot data generator
    • database & orm for storing fakeiot data
    • edge case/bad data handling from fakeiot generator
    • figure out proper use of bearer tokens and CA certs for fakeiot
    • 1 unit test

Assumptions:

  • Frontend db polls the backend every 1s instead of keeping a socket open or any other solns - this is fragile and may stop updating the FE DB if we change tabs/windows and come back
  • backend - dashboard getinfo - doesnt hit database if we have an active account
  • we dont do any debouncing on front end button or user alerting on incorrect input
  • Multiple admin users are allowed to be logged in at the same time with different sessions but the same credentials
  • Auth based redirects are handled clientside not server side
  • we console.log any not ok responses on the frontend for debugging
  • Not sure if cross dependency between go packages is good, i.e. pkg 1 requires apis from pkg 2 and an interface of pkg 2 is instantiated when we init pkg 1
  • Ideally should use a FOSS auth handler like authboss but this is a good excercise in how these things work
  • authenticator has more users logic than i think is good, but i think its an acceptable tradeoff right now
  • if the iotdata generator posts 2 users with the same accid, userid, we assume it was a mistake and dont create a new user but update the timestamp
  • if the timestamp incoming is empty or equals to Time.IsZero() then we reject the metric - this case is not part of the iot data gen tests
  • metrics generator > we create a new item in the db every time, time out and batch write may be faster. We also update the active users details at this time if the acc id matches
  • iotdata http handler hands off iotdatahandler package, although for dashbooard and auth handlers we create the handlers from the authenticator package in package:main

About

Gravitational interview - full stack challenge


Languages

Language:Go 60.7%Language:JavaScript 28.6%Language:CSS 7.0%Language:HTML 3.6%