Postgres & auth are beginning to function.
[?]
Feb 16, 2015, 12:24 AM
PBD7LZYQHXAA3KLH2ZUX5GW4UFML6BQ32KXZF4KZ6OYFASUYFJ5QCDependencies
- [2]
I2KHGVD4Require project permissions for access to most data. - [3]
GKGVYBZGAdded JSON serialization to TimeLog - [4]
NVOCQVASInitial failing tests. - [5]
TNR3TEHKSwitch to Postgres + snaplet arch compiles. - [6]
BROSTG5KBeginning of modularization of server. - [7]
VJPT6HDRFix remaining type errors after addition of login handler. - [8]
IZEVQF62Work in progress replacing sqlite with postgres. - [9]
Z7KS5XHHVery WIP. Wow. - [10]
BXGLKYRXAdded primitive user registration handler. - [*]
ADMKQQGCInitial empty Snap project. - [*]
OBFPJS2GProject successfully builds and tests under nix. - [*]
5W5M56VJMove library code to 'lib' - [*]
64C6AWH6Rename Ananke -> Quixotic, project reboot. - [*]
WO2MINIFAuctions now compile! - [*]
HE3JTXO3Added client call to payouts. - [*]
4IQVQL4TAdded client for payouts endpoint. - [*]
AXKKXBWNInitial attempt at writing down my ideas for a company based on trust.
Change contents
- edit in .gitignore at line 12[13.29]
localstablesnapletsregtest.confsite_key.txt - replacement in lib/Quixotic/Database/PostgreSQL.hs at line 152
"INSERT INTO bids (auction_id, user_id, bid_seconds, bid_amount, bid_time) values (?, ?, ?, ?, ?)""INSERT INTO bids (auction_id, bidder_id, bid_seconds, bid_amount, bid_time) values (?, ?, ?, ?, ?)" - replacement in lib/Quixotic/Database/PostgreSQL.hs at line 172
"INSERT INTO users (handle, btc_addr, email) VALUES (?, ?) RETURNING id""INSERT INTO users (handle, btc_addr, email) VALUES (?, ?, ?) RETURNING id" - file addition: Util[14.18]
- file addition: Http.hs[0.242]
module Quixotic.Util.Http whereimport ClassyPreludeimport Data.ByteString (split)import Data.Attoparsec.ByteStringimport qualified Data.ByteString.Base64 as B64type AuthHeader = (Text, ByteString)authHeaderParser :: Parser AuthHeaderauthHeaderParser = dolet isBase64Char w = (w >= 47 && w <= 57 ) ||(w >= 64 && w <= 90 ) ||(w >= 97 && w <= 122) ||(w == 43 || w == 61 )b64 <- string "Basic " *> takeWhile1 isBase64Chardecoded <- either fail pure $ B64.decode b64case split 58 decoded of(uname : pwd : []) -> pure $ (decodeUtf8 uname, pwd)_ -> fail "Could not unpack auth header into username and password components" - replacement in lib/Quixotic.hs at line 40
{ _projectId :: ProjectId{ _invitationProject :: ProjectId - edit in quixotic.cabal at line 30
Quixotic.Util.Http - edit in quixotic.cabal at line 35
, attoparsec >= 0.12.1.2 - edit in quixotic.cabal at line 37
, bytestring - edit in quixotic.cabal at line 53
, base64-bytestring >= 1.0.0.1 - edit in quixotic.cabal at line 71
, attoparsec - file addition: scripts[19.2]
- file addition: create_project.sh[0.1220]
#!/bin/bashcurl -v -u "nuttycom:kjntest" -H "Content-Type: application/json" -d '{"projectName":"the"}' http://localhost:8000/projects - file addition: create_user.sh[0.1220]
#!/bin/bashcurl -v -H "Content-Type: application/json" -d '{"username":"nuttycom", "password":"kjntest", "email":"kris@quixoticcompany.com", "btcAddr":"1KamUn1BaRMd2HwikyQWGTdUvfPScg9QA5"}' http://localhost:8000/register - edit in server/Main.hs at line 17
import Quixotic.Snaplet.Projects - replacement in server/Main.hs at line 52
, ("register", registerHandler), ("register", method POST registerHandler), ("projects", projectsHandler) - replacement in server/Main.hs at line 57
, ("projects/:projectId", ok), ("payouts/:projectId", payoutsHandler), ("projects/:projectId", method GET ok), ("payouts/:projectId", method GET payoutsHandler) - replacement in server/Quixotic/Snaplet/Auth.hs at line 7
import Data.ByteString (split)import Data.Attoparsec.ByteStringimport qualified Data.ByteString.Base64 as B64import Data.Attoparsec.ByteString (parseOnly) - edit in server/Quixotic/Snaplet/Auth.hs at line 11
import Quixotic.Util.Http (authHeaderParser) - edit in server/Quixotic/Snaplet/Auth.hs at line 18
type AuthHeader = (Text, ByteString) - edit in server/Quixotic/Snaplet/Auth.hs at line 19
authHeaderParser :: Parser AuthHeaderauthHeaderParser = dolet isBase64Char w = (w >= 47 && w <= 57 ) ||(w >= 64 && w <= 90 ) ||(w >= 97 && w <= 122) ||(w == 43 || w == 61 )b64 <- string "Basic" *> takeWhile1 isBase64Chardecoded <- either fail pure $ B64.decode b64case split 58 decoded of(uname : pwd : []) -> pure $ (decodeUtf8 uname, pwd)_ -> fail "Could not unpack auth header into username and password components" - edit in server/Quixotic/Snaplet/Auth.hs at line 23
logError rawHeader - edit in server/Quixotic/Snaplet/Auth.hs at line 46
QDB{..} <- view qdb <$> with qm get - replacement in server/Quixotic/Snaplet/Auth.hs at line 50
Just pid -> error $ "FIXME: implement project access check - got pid " ++ " " ++ show uid ++ " " ++ show pidJust pid -> doprojects <- liftPG . runReaderT $ findUserProjects uidif any (\p -> p ^. projectId == pid) projectsthen pure pidelse snapError 403 $ "User " ++ (tshow uid) ++ " does not have access to project " ++ (tshow pid) - file addition: Projects.hs[2.182]
{-# LANGUAGE TemplateHaskell #-}module Quixotic.Snaplet.Projects( projectsHandler) whereimport ClassyPreludeimport Control.Lensimport Control.Monad.Stateimport Data.Aeson as Aimport Quixoticimport Quixotic.Databaseimport Quixotic.Snapletimport Quixotic.Snaplet.Authimport Snap.Coreimport Snap.Snapletimport Snap.Snaplet.PostgresqlSimpledata CreateProject = CreateProject { createProjectName :: Text }instance FromJSON CreateProject whereparseJSON (Object v) = CreateProject <$> v .: "projectName"parseJSON _ = mzeroprojectsHandler :: Handler App App ()projectsHandler = dovoid $ method POST projectCreateHandlervoid $ method GET projectListHandlerprojectCreateHandler :: Handler App App ProjectIdprojectCreateHandler = doQDB{..} <- view qdb <$> with qm getuid <- requireUserIdrequestBody <- readRequestBody 4096cp <- maybe (snapError 400 "Could not parse project data") pure $ A.decode requestBodytimestamp <- liftIO getCurrentTimeliftPG . runReaderT . createProject $ Project (createProjectName cp) timestamp uidprojectListHandler :: Handler App App [Project]projectListHandler = ok - replacement in server/Quixotic/Snaplet/Users.hs at line 39
requestBody <- readRequestBody 0requestBody <- readRequestBody 4096 - replacement in server/Quixotic/Snaplet/Users.hs at line 41
authUser <- with auth $AU.createUser (userData ^. (cuser.username._UserName)) (userData ^. password)let createQUser = liftPG $ runReaderT (createUser $ userData ^. cuser)let createSUser = AU.createUser (userData ^. (cuser.username._UserName)) (userData ^. password)createQUser = liftPG $ runReaderT (createUser $ userData ^. cuser)authUser <- with auth createSUser - replacement in server/Quixotic/Snaplet.hs at line 51
ok :: MonadSnap m => m ()ok :: MonadSnap m => m a - edit in server/Quixotic/Snaplet.hs at line 56[2.3904]
- replacement in sql/quixotic-pg.sql at line 2
btc_addr varchar(34) primary keyid serial primary key,handle text not null,btc_addr text not null,email text not null);create table projects (id serial primary key,project_name text not null,inception_date timestamp without time zone not null,initiator_id integer references users (id) not null - replacement in sql/quixotic-pg.sql at line 15
create table users_trusted (create type event_t as enum ('start_work', 'stop_work');create table work_events ( - replacement in sql/quixotic-pg.sql at line 19
btc_addr varchar(34) references users (btc_addr) not null,trust_interval interval not null)project_id integer references projects(id) not null,user_id integer references users(id) not null,btc_addr text not null,event_type event_t not null,event_time timestamp without time zone not null); - replacement in sql/quixotic-pg.sql at line 26
create type event_type as enum ('start_work', 'stop_work');create table auctions (id serial primary key,project_id integer references projects(id) not null,initiator_id integer references users (id) not null,raise_amount numeric not null,end_time timestamp without time zone not null); - replacement in sql/quixotic-pg.sql at line 34
create table timelog (create table bids ( - replacement in sql/quixotic-pg.sql at line 36
btc_addr varchar(34) references users (btc_addr) not null,log_time timestamp without time zone not null,log_type event_type not null)[3.3467]auction_id integer references projects (id) not null,bidder_id integer references users (id) not null,bid_seconds integer not null,bid_amount numeric not null,bid_time timestamp without time zone not null); - file addition: Util[13.3700]
- file addition: HttpSpec.hs[0.4914]
{-# LANGUAGE OverloadedStrings, ScopedTypeVariables, NoImplicitPrelude #-}module Quixotic.Util.HttpSpec whereimport ClassyPreludeimport Quixotic.Util.Httpimport Data.Attoparsec.ByteStringimport Test.Hspecspec :: Specspec = dodescribe "HTTP Basic header parsing" $ doit "parses the Basic auth header" $ dolet rawHeader = "Basic bnV0dHljb206a2pudGVzdA=="(parseOnly authHeaderParser rawHeader) `shouldBe` (Right ("nuttycom", "kjntest"))main :: IO ()main = hspec spec