Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

New homepage and submit right on report page

  • Loading branch information...
commit 7ae33c0e7214e576fd2980fcfa58e7f93ff9c8e6 1 parent 56eed70
@singpolyma authored
View
48 Application.hs
@@ -10,19 +10,22 @@ import Network.Wai (Request(..), Response(..), Application)
import Network.HTTP.Types (ok200, notFound404, seeOther303, badRequest400, notAcceptable406, Status, ResponseHeaders)
import Network.Wai.Util (string, stringHeaders, json, bodyBytestring, redirect')
import Web.PathPieces (PathPiece(..))
+import Data.Time.Clock.POSIX (getPOSIXTime)
import Data.Base58Address (RippleAddress)
import Control.Error (readMay, headMay)
import Control.Monad.Trans (liftIO)
-import Database.SQLite.Simple (query, field, FromRow(..), Connection, open, close)
+import Database.SQLite.Simple (query, field, FromRow(..), Connection, open, close, query_)
import Database.SQLite.Simple.ToField (ToField(..))
import Data.Binary (Binary, decodeOrFail)
import Network.URI (URI(..))
import Network.URI.Partial (relativeTo)
import qualified Blaze.ByteString.Builder.Char.Utf8 as Blaze
import qualified Data.Text as T
+import qualified Data.Text.Encoding as T
import qualified Data.Text.Lazy.Builder as TL
import qualified Data.Aeson as Aeson
import qualified Data.ByteString.Lazy as LZ
+import qualified Data.ByteString as BS
import Records
import MustacheTemplates
@@ -50,16 +53,37 @@ responseTextBuilder s h = ResponseBuilder s h . Blaze.fromLazyText . TL.toLazyTe
on404 :: Application
on404 _ = string notFound404 [] "Not Found"
+home :: URI -> Connection -> Application
+home root db req =
+ return $ responseTextBuilder ok200 headers (viewHome htmlEscape $ HomeRec [Form $ forPath `relativeTo` root])
+ where
+ Just headers = stringHeaders [("Content-Type", "text/html; charset=utf8")]
+
+for :: URI -> Connection -> Application
+for root _ req = case adr of
+ Just adr -> redirect' seeOther303 [] (reportForPath adr `relativeTo` root)
+ Nothing -> string badRequest400 [] "Invalid Ripple.com address.\n"
+ where
+ adr = readMay =<< fmap T.unpack adrS
+ adrS = fmap (T.decodeUtf8 . fromMaybe BS.empty) $ lookup (fromString "address") (queryString req)
+
reportFor :: URI -> Connection -> RippleAddress -> Application
-reportFor _ db adr req = do
- assertions <- liftIO $ query db (fromString "SELECT `from`, `fromFingerprint`, `to`, `at`, `asserted`, `assertion` FROM assertions WHERE `to` = ?") [adr]
- case acceptType of
- "text/html" ->
- return $ responseTextBuilder ok200 headers (viewReport htmlEscape $ Report adr assertions)
- "application/json" ->
- json ok200 [] (Report adr assertions)
- _ -> string notAcceptable406 [] (intercalate "\n" supportedTypes)
+reportFor root db adr req = case gen of
+ Just x -> do
+ time <- liftIO (fmap floor getPOSIXTime :: IO Integer)
+ string ok200 disp (show time ++ ": " ++ show adr ++ " " ++ T.unpack x)
+ Nothing -> do
+ assertions <- liftIO $ query db (fromString "SELECT `from`, `fromFingerprint`, `to`, `at`, `asserted`, `assertion` FROM assertions WHERE `to` = ?") [adr]
+ case acceptType of
+ "text/html" ->
+ return $ responseTextBuilder ok200 headers (viewReport htmlEscape $ Report adr assertions)
+ "application/json" ->
+ json ok200 [] (Report adr assertions)
+ _ -> string notAcceptable406 [] (intercalate "\n" supportedTypes)
where
+ gen = fmap (T.decodeUtf8 . fromMaybe BS.empty) $ lookup (fromString "newAssertion") (queryString req)
+
+ Just disp = stringHeaders [("Content-Disposition", "attachment; filename=assertion.txt")]
Just headers = stringHeaders [("Content-Type", "text/html; charset=utf8")]
acceptType = fromMaybe (head supportedTypes) acceptType'
acceptType' = (selectAcceptType supportedTypes . parseHttpAccept) =<<
@@ -101,9 +125,3 @@ assertFor root db adr req = do
acceptType' = (selectAcceptType supportedTypes . parseHttpAccept) =<<
lookup (fromString "Accept") (requestHeaders req)
supportedTypes = ["text/html", "text/plain", "application/json"]
-
-submitFor :: URI -> Connection -> RippleAddress -> Application
-submitFor root _ adr req =
- return $ responseTextBuilder ok200 headers (viewSubmit htmlEscape $ SubmitForm adr (assertForPath adr `relativeTo` root))
- where
- Just headers = stringHeaders [("Content-Type", "text/html; charset=utf8")]
View
4 Makefile
@@ -7,8 +7,8 @@ Routes.hs: routes
PathHelpers.hs: routes
routeGenerator -p -n 2 $< > $@
-MustacheTemplates.hs: Records.hs view/report.mustache view/submit.mustache
- mustache2hs -m Records.hs view/report.mustache Report view/submit.mustache SubmitForm > $@
+MustacheTemplates.hs: Records.hs view/report.mustache view/home.mustache
+ mustache2hs -m Records.hs view/report.mustache Report view/home.mustache HomeRec > $@
clean:
find -name '*.o' -o -name '*.hi' | xargs $(RM)
View
8 Records.hs
@@ -33,8 +33,12 @@ instance TL.Buildable URI where
instance ToField RippleAddress where
toField adr = toField (show adr)
-data SubmitForm = SubmitForm {
- formAddress :: RippleAddress,
+data HomeRec = HomeRec {
+ forForm :: [Form]
+ }
+ deriving (Show, Eq)
+
+data Form = Form {
formAction :: URI
}
deriving (Show, Eq)
View
3  routes
@@ -1,3 +1,4 @@
+GET / => home
+GET /for/ => for
GET /for/: => reportFor
-GET /for/:/submit => submitFor
POST /for/: => assertFor
View
61 view/home.mustache
@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Ripple Union Credit Reports</title>
+
+ <style type="text/css">
+ html, body {
+ background-color: #abcdef;
+ font-family: "Liberation Sans", sans-serif;
+ }
+
+ body {
+ margin-left: 10%;
+ margin-right: 10%;
+ margin-top: 2em;
+ }
+
+ body > h1 {
+ overflow: hidden;
+ }
+
+ h1 * {
+ vertical-align: middle;
+ }
+
+ h1 img {
+ float: left;
+ padding-right: 5em;
+ }
+
+ .rippleAddress {
+ font-size: 0.5em;
+ }
+
+ a[rel=enclosure] img {
+ position: relative;
+ top: 4px;
+ }
+ </style>
+ </head>
+
+ <body>
+ <h1><img src="/logo.png" alt="Ripple Union" /> Credit Reports</h1>
+
+ <p>This credit reporting system is designed to give support to Ripple.com organizations and users who want to extend credit to other users. Every time a user to whom you have extended credit makes a payment on that credit, you may submit an OpenPGP signed message saying:</p>
+
+ <blockquote>&lt;unix timestamp of transaction&gt;: &lt;Ripple.com address of user&gt; made a payment</blockquote>
+
+ <p>If you have an agreement that payments should be made, and a user does not uphold this agreement, the format is the same as above but you say "missed a payment". If the user makes a payment, but then executes a chargeback (if you have, say, agreed to PayPal payments), you say "chargeback". If a user consistently behaves in an untrustworthy manner, say "not trusted". There are links on individual report pages to messages of the various types that you can simply download, sign with your OpenPGP key, and then upload again using the submit form for that address.</p>
+
+ <p>Note: <strong>signing subkeys are not supported</strong>. This is a technical limitation we hope will be lifted soon.</p>
+
+ {{#forForm}}
+ <form method="get" action="{{formAction}}">
+ <input type="text" name="address" placeholder="Ripple.com address" />
+ <input type="submit" value="View Report" />
+ </form>
+ {{/forForm}}
+ </body>
+</html>
View
51 view/report.mustache
@@ -1,7 +1,6 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
- <base href="http://rippleunion.com/" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Ripple Union Credit Report for {{address}}</title>
@@ -38,25 +37,47 @@
position: relative;
top: 4px;
}
+
+ input { display: block; }
</style>
</head>
<body>
<h1><img src="/logo.png" alt="Ripple Union" /> Credit Report for <span class="rippleAddress">{{address}}</span></h1>
- <ul>
- {{#assertions}}
- <li>
- <a href="data:application/pgp-encrypted;base64,{{signedAssertion}}" rel="enclosure"><img src="http://www.famfamfam.com/lab/icons/mini/icons/arrow_down.gif" alt="download signed assertion" title="download signed assertion" /></a>
-
- <time datetime="{{at8601}}">{{atHuman}}</time> —
- <a href="http://singpolyma.net:11371/pks/lookup?op=vindex&amp;search=0x{{#row}}{{fromFingerprint}}{{/row}}">{{keyId}}</a>
- asserted that this address
- {{#row}}
- {{asserted}}
- {{/row}}
- </li>
- {{/assertions}}
- </ul>
+ <section>
+ <h1>Assertions</h1>
+
+ <ul>
+ {{#assertions}}
+ <li>
+ <a href="data:application/pgp-encrypted;base64,{{signedAssertion}}" rel="enclosure"><img src="http://www.famfamfam.com/lab/icons/mini/icons/arrow_down.gif" alt="download signed assertion" title="download signed assertion" /></a>
+
+ <time datetime="{{at8601}}">{{atHuman}}</time> —
+ <a href="http://singpolyma.net:11371/pks/lookup?op=vindex&amp;search=0x{{#row}}{{fromFingerprint}}{{/row}}">{{keyId}}</a>
+ asserted that this address
+ {{#row}}
+ {{asserted}}
+ {{/row}}
+ </li>
+ {{/assertions}}
+ </ul>
+ </section>
+
+ <section>
+ <h1>Downloads to sign</h1>
+ <ul>
+ <li><a href="?newAssertion=made%20a%20payment">made a payment</a></li>
+ <li><a href="?newAssertion=missed%20a%20payment">missed a payment</a></li>
+ <li><a href="?newAssertion=chargeback">chargeback</a></li>
+ <li><a href="?newAssertion=not%20trusted">not trusted</a></li>
+ </ul>
+ </section>
+
+ <form method="post" action="" enctype="multipart/form-data">
+ <label for="assertion">Upload assertion</label>
+ <input type="file" id="assertion" name="assertion" />
+ <input type="submit" value="Submit" />
+ </form>
</body>
</html>
View
58 view/submit.mustache
@@ -1,58 +0,0 @@
-<!DOCTYPE html>
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <base href="http://rippleunion.com/" />
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
- <title>Submit Assertion for {{formAddress}}</title>
-
- <style type="text/css">
- html, body {
- background-color: #abcdef;
- font-family: "Liberation Sans", sans-serif;
- }
-
- body {
- margin-left: 10%;
- margin-right: 10%;
- margin-top: 2em;
- }
-
- body > h1 {
- overflow: hidden;
- }
-
- h1 * {
- vertical-align: middle;
- }
-
- h1 img {
- float: left;
- padding-right: 5em;
- }
-
- .rippleAddress {
- font-size: 0.5em;
- }
-
- a[rel=enclosure] img {
- position: relative;
- top: 4px;
- }
-
- input {
- display: block;
- }
- </style>
- </head>
-
- <body>
- <h1><img src="/logo.png" alt="Ripple Union" /> Submit Assertion for <span class="rippleAddress">{{formAddress}}</span></h1>
-
- <form method="post" action="{{formAction}}" enctype="multipart/form-data">
- <label for="assertion">OpenPGP signed assertion</label>
- <input type="file" id="assertion" name="assertion" />
- <input type="submit" value="Submit" />
- </form>
-
- </body>
-</html>
Please sign in to comment.
Something went wrong with that request. Please try again.