Bind to cryptoids
This commit is contained in:
parent
62c2320aef
commit
9de9032916
1
.gitignore
vendored
1
.gitignore
vendored
@ -2,6 +2,7 @@ dist*
|
|||||||
static/tmp/
|
static/tmp/
|
||||||
static/combined/
|
static/combined/
|
||||||
client_session_key.aes
|
client_session_key.aes
|
||||||
|
cryptoid_key.bf
|
||||||
*.hi
|
*.hi
|
||||||
*.o
|
*.o
|
||||||
*.sqlite3
|
*.sqlite3
|
||||||
|
|||||||
@ -32,5 +32,7 @@ database:
|
|||||||
database: "_env:PGDATABASE:uniworx"
|
database: "_env:PGDATABASE:uniworx"
|
||||||
poolsize: "_env:PGPOOLSIZE:10"
|
poolsize: "_env:PGPOOLSIZE:10"
|
||||||
|
|
||||||
|
cryptoid-keyfile: "_env:CRYPTOID_KEYFILE:cryptoid_key.bf"
|
||||||
|
|
||||||
copyright: Insert copyright statement here
|
copyright: Insert copyright statement here
|
||||||
#analytics: UA-YOURCODE
|
#analytics: UA-YOURCODE
|
||||||
|
|||||||
@ -58,6 +58,13 @@ dependencies:
|
|||||||
- filepath
|
- filepath
|
||||||
- transformers
|
- transformers
|
||||||
- wl-pprint-text
|
- wl-pprint-text
|
||||||
|
- uuid-types
|
||||||
|
- path-pieces
|
||||||
|
- uuid-crypto
|
||||||
|
- cryptoids-types
|
||||||
|
- cryptoids
|
||||||
|
- binary
|
||||||
|
- mtl
|
||||||
|
|
||||||
# The library contains all of our application code. The executable
|
# The library contains all of our application code. The executable
|
||||||
# defined below is just a thin wrapper.
|
# defined below is just a thin wrapper.
|
||||||
|
|||||||
2
routes
2
routes
@ -18,3 +18,5 @@
|
|||||||
/course/#TermIdentifier/#Text/edit CourseEditExistR GET
|
/course/#TermIdentifier/#Text/edit CourseEditExistR GET
|
||||||
/course/#TermIdentifier/#Text/show CourseShowR GET
|
/course/#TermIdentifier/#Text/show CourseShowR GET
|
||||||
|
|
||||||
|
-- For demonstration
|
||||||
|
/course/#CryptoUUIDCourse/edit CourseEditExistIDR GET
|
||||||
@ -55,14 +55,16 @@ mkYesodDispatch "UniWorX" resourcesUniWorX
|
|||||||
-- the place to put your migrate statements to have automatic database
|
-- the place to put your migrate statements to have automatic database
|
||||||
-- migrations handled by Yesod.
|
-- migrations handled by Yesod.
|
||||||
makeFoundation :: AppSettings -> IO UniWorX
|
makeFoundation :: AppSettings -> IO UniWorX
|
||||||
makeFoundation appSettings = do
|
makeFoundation appSettings@(AppSettings{..}) = do
|
||||||
-- Some basic initializations: HTTP connection manager, logger, and static
|
-- Some basic initializations: HTTP connection manager, logger, and static
|
||||||
-- subsite.
|
-- subsite.
|
||||||
appHttpManager <- newManager
|
appHttpManager <- newManager
|
||||||
appLogger <- newStdoutLoggerSet defaultBufSize >>= makeYesodLogger
|
appLogger <- newStdoutLoggerSet defaultBufSize >>= makeYesodLogger
|
||||||
appStatic <-
|
appStatic <-
|
||||||
(if appMutableStatic appSettings then staticDevel else static)
|
(if appMutableStatic then staticDevel else static)
|
||||||
(appStaticDir appSettings)
|
appStaticDir
|
||||||
|
|
||||||
|
appCryptoIDKey <- readKeyFile appCryptoIDKeyFile
|
||||||
|
|
||||||
-- We need a log function to create a connection pool. We need a connection
|
-- We need a log function to create a connection pool. We need a connection
|
||||||
-- pool to create our foundation. And we need our foundation to get a
|
-- pool to create our foundation. And we need our foundation to get a
|
||||||
@ -78,8 +80,8 @@ makeFoundation appSettings = do
|
|||||||
|
|
||||||
-- Create the database connection pool
|
-- Create the database connection pool
|
||||||
pool <- flip runLoggingT logFunc $ createPostgresqlPool
|
pool <- flip runLoggingT logFunc $ createPostgresqlPool
|
||||||
(pgConnStr $ appDatabaseConf appSettings)
|
(pgConnStr appDatabaseConf)
|
||||||
(pgPoolSize $ appDatabaseConf appSettings)
|
(pgPoolSize appDatabaseConf)
|
||||||
|
|
||||||
-- Perform database migration using our application's logging settings.
|
-- Perform database migration using our application's logging settings.
|
||||||
runLoggingT (runSqlPool (runMigration migrateAll) pool) logFunc
|
runLoggingT (runSqlPool (runMigration migrateAll) pool) logFunc
|
||||||
|
|||||||
36
src/CryptoID.hs
Normal file
36
src/CryptoID.hs
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
{-# LANGUAGE DataKinds #-}
|
||||||
|
{-# LANGUAGE NoImplicitPrelude #-}
|
||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
{-# LANGUAGE FlexibleInstances, TypeSynonymInstances #-}
|
||||||
|
{-# OPTIONS_GHC -fno-warn-orphans #-}
|
||||||
|
|
||||||
|
module CryptoID
|
||||||
|
( module CryptoID
|
||||||
|
, module Data.UUID.Cryptographic
|
||||||
|
, module Data.CryptoID.Poly
|
||||||
|
) where
|
||||||
|
|
||||||
|
import CryptoID.TH
|
||||||
|
|
||||||
|
import ClassyPrelude hiding (fromString)
|
||||||
|
import Model
|
||||||
|
|
||||||
|
import Data.CryptoID
|
||||||
|
import Data.CryptoID.Poly hiding (decrypt, encrypt)
|
||||||
|
|
||||||
|
import Data.UUID.Cryptographic
|
||||||
|
import Data.UUID.Types
|
||||||
|
import Web.PathPieces
|
||||||
|
|
||||||
|
|
||||||
|
instance PathPiece UUID where
|
||||||
|
fromPathPiece = fromString . unpack
|
||||||
|
toPathPiece = pack . toString
|
||||||
|
|
||||||
|
decKeysBinary [ ''SubmissionId
|
||||||
|
, ''CourseId
|
||||||
|
]
|
||||||
|
|
||||||
|
decTypeAliases [ "Submission"
|
||||||
|
, "Course"
|
||||||
|
]
|
||||||
38
src/CryptoID/TH.hs
Normal file
38
src/CryptoID/TH.hs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
{-# LANGUAGE NoImplicitPrelude #-}
|
||||||
|
{-# LANGUAGE TemplateHaskell #-}
|
||||||
|
{-# LANGUAGE ViewPatterns #-}
|
||||||
|
|
||||||
|
module CryptoID.TH where
|
||||||
|
|
||||||
|
import ClassyPrelude
|
||||||
|
|
||||||
|
import Language.Haskell.TH
|
||||||
|
|
||||||
|
import Data.CryptoID (CryptoID)
|
||||||
|
import Data.UUID.Types (UUID)
|
||||||
|
import Data.Binary (Binary(..))
|
||||||
|
|
||||||
|
import Database.Persist.Sql (toSqlKey, fromSqlKey)
|
||||||
|
|
||||||
|
|
||||||
|
decTypeAliases :: [String] -> Q [Dec]
|
||||||
|
decTypeAliases = return . concatMap decTypeAliases'
|
||||||
|
where
|
||||||
|
decTypeAliases' :: String -> [Dec]
|
||||||
|
decTypeAliases' n
|
||||||
|
= [ TySynD cryptoIDn [] $ ConT ''CryptoID `AppT` LitT (StrTyLit n)
|
||||||
|
, TySynD cryptoUUIDn [] $ ConT cryptoIDn `AppT` ConT ''UUID
|
||||||
|
]
|
||||||
|
where
|
||||||
|
cryptoIDn = mkName $ "CryptoID" ++ n
|
||||||
|
cryptoUUIDn = mkName $ "CryptoUUID" ++ n
|
||||||
|
|
||||||
|
decKeysBinary :: [Name] -> DecsQ
|
||||||
|
decKeysBinary = fmap concat . mapM decKeyBinary
|
||||||
|
where
|
||||||
|
decKeyBinary :: Name -> DecsQ
|
||||||
|
decKeyBinary (conT -> t)
|
||||||
|
= [d| instance Binary $(t) where
|
||||||
|
get = $(varE 'toSqlKey) <$> get
|
||||||
|
put = put . $(varE 'fromSqlKey)
|
||||||
|
|]
|
||||||
@ -50,6 +50,7 @@ data UniWorX = UniWorX
|
|||||||
, appConnPool :: ConnectionPool -- ^ Database connection pool.
|
, appConnPool :: ConnectionPool -- ^ Database connection pool.
|
||||||
, appHttpManager :: Manager
|
, appHttpManager :: Manager
|
||||||
, appLogger :: Logger
|
, appLogger :: Logger
|
||||||
|
, appCryptoIDKey :: CryptoIDKey
|
||||||
}
|
}
|
||||||
|
|
||||||
data MenuItem = MenuItem
|
data MenuItem = MenuItem
|
||||||
@ -177,6 +178,7 @@ instance Yesod UniWorX where
|
|||||||
isAuthorized (TermEditExistR _) _ = return Authorized
|
isAuthorized (TermEditExistR _) _ = return Authorized
|
||||||
isAuthorized CourseEditR _ = return Authorized
|
isAuthorized CourseEditR _ = return Authorized
|
||||||
isAuthorized (CourseEditExistR _ _) _ = return Authorized
|
isAuthorized (CourseEditExistR _ _) _ = return Authorized
|
||||||
|
isAuthorized (CourseEditExistIDR _) _ = return Authorized
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -19,6 +19,8 @@ import Yesod.Form.Bootstrap3
|
|||||||
import Colonnade
|
import Colonnade
|
||||||
import Yesod.Colonnade
|
import Yesod.Colonnade
|
||||||
|
|
||||||
|
import qualified Data.UUID.Cryptographic as UUID
|
||||||
|
|
||||||
|
|
||||||
getCourseListR :: Handler TypedContent
|
getCourseListR :: Handler TypedContent
|
||||||
getCourseListR = redirect TermShowR
|
getCourseListR = redirect TermShowR
|
||||||
@ -77,6 +79,12 @@ getCourseEditExistR tid csh = do
|
|||||||
course <- runDB $ getBy $ CourseTermShort (TermKey tid) csh
|
course <- runDB $ getBy $ CourseTermShort (TermKey tid) csh
|
||||||
courseEditHandler course
|
courseEditHandler course
|
||||||
|
|
||||||
|
getCourseEditExistIDR :: CryptoUUIDCourse -> Handler Html
|
||||||
|
getCourseEditExistIDR cID = do
|
||||||
|
cIDKey <- getsYesod appCryptoIDKey
|
||||||
|
courseID <- UUID.decrypt cIDKey cID
|
||||||
|
courseEditHandler =<< runDB (getEntity courseID)
|
||||||
|
|
||||||
|
|
||||||
courseEditHandler :: Maybe (Entity Course) -> Handler Html
|
courseEditHandler :: Maybe (Entity Course) -> Handler Html
|
||||||
courseEditHandler course = do
|
courseEditHandler course = do
|
||||||
|
|||||||
@ -34,12 +34,16 @@ import Data.Text.Encoding.Error (UnicodeException(..))
|
|||||||
import qualified Data.Text.Lazy.Encoding as Lazy.Text
|
import qualified Data.Text.Lazy.Encoding as Lazy.Text
|
||||||
|
|
||||||
import qualified Data.ByteString.Lazy as Lazy (ByteString)
|
import qualified Data.ByteString.Lazy as Lazy (ByteString)
|
||||||
|
import qualified Data.ByteString.Lazy as Lazy.ByteString
|
||||||
|
|
||||||
import Text.Read (readEither)
|
import Text.Read (readEither)
|
||||||
|
|
||||||
import GHC.Generics (Generic)
|
import GHC.Generics (Generic)
|
||||||
import Data.Typeable (Typeable)
|
import Data.Typeable (Typeable)
|
||||||
|
|
||||||
|
import Data.Binary (encode, decode)
|
||||||
|
import qualified Data.CryptoID.Poly as Poly
|
||||||
|
|
||||||
|
|
||||||
instance HasResolution prec => Pretty (Fixed prec) where
|
instance HasResolution prec => Pretty (Fixed prec) where
|
||||||
pretty = pretty . show
|
pretty = pretty . show
|
||||||
@ -48,7 +52,7 @@ instance HasResolution prec => Pretty (Fixed prec) where
|
|||||||
data Rating = Rating
|
data Rating = Rating
|
||||||
{ ratingCourseName :: Text
|
{ ratingCourseName :: Text
|
||||||
, ratingSheetName :: Text
|
, ratingSheetName :: Text
|
||||||
, ratingSubmissionId :: SubmissionId
|
, ratingSubmissionId :: CryptoIDSubmission ByteString -- ^ 'SubmissionId'
|
||||||
, ratingComment :: Maybe Text
|
, ratingComment :: Maybe Text
|
||||||
, ratingPoints :: Maybe Points
|
, ratingPoints :: Maybe Points
|
||||||
} deriving (Read, Show, Eq, Generic, Typeable)
|
} deriving (Read, Show, Eq, Generic, Typeable)
|
||||||
@ -67,10 +71,12 @@ instance Exception RatingException
|
|||||||
|
|
||||||
|
|
||||||
getRating :: SubmissionId -> YesodDB UniWorX (Maybe Rating)
|
getRating :: SubmissionId -> YesodDB UniWorX (Maybe Rating)
|
||||||
getRating ratingSubmissionId = runMaybeT $ do
|
getRating submissionId = runMaybeT $ do
|
||||||
Submission{ submissionSheetId, submissionRatingComment = ratingComment, submissionRatingPoints = ratingPoints } <- MaybeT $ get ratingSubmissionId
|
Submission{ submissionSheetId, submissionRatingComment = ratingComment, submissionRatingPoints = ratingPoints } <- MaybeT $ get submissionId
|
||||||
Sheet{ sheetCourseId, sheetName = ratingSheetName } <- MaybeT $ get submissionSheetId
|
Sheet{ sheetCourseId, sheetName = ratingSheetName } <- MaybeT $ get submissionSheetId
|
||||||
Course{ courseName = ratingCourseName } <- MaybeT $ get sheetCourseId
|
Course{ courseName = ratingCourseName } <- MaybeT $ get sheetCourseId
|
||||||
|
cIDKey <- getsYesod appCryptoIDKey
|
||||||
|
ratingSubmissionId <- Poly.encrypt cIDKey . Lazy.ByteString.toStrict $ encode submissionId
|
||||||
return Rating{..}
|
return Rating{..}
|
||||||
|
|
||||||
formatRating :: Rating -> Lazy.ByteString
|
formatRating :: Rating -> Lazy.ByteString
|
||||||
|
|||||||
@ -12,3 +12,5 @@ import Yesod.Core.Types as Import (loggerSet)
|
|||||||
import Yesod.Default.Config2 as Import
|
import Yesod.Default.Config2 as Import
|
||||||
|
|
||||||
import Data.Fixed as Import
|
import Data.Fixed as Import
|
||||||
|
|
||||||
|
import CryptoID as Import
|
||||||
|
|||||||
@ -59,6 +59,7 @@ data AppSettings = AppSettings
|
|||||||
-- ^ Copyright text to appear in the footer of the page
|
-- ^ Copyright text to appear in the footer of the page
|
||||||
, appAnalytics :: Maybe Text
|
, appAnalytics :: Maybe Text
|
||||||
-- ^ Google Analytics code
|
-- ^ Google Analytics code
|
||||||
|
, appCryptoIDKeyFile :: FilePath
|
||||||
|
|
||||||
, appAuthDummyLogin :: Bool
|
, appAuthDummyLogin :: Bool
|
||||||
-- ^ Indicate if auth dummy login should be enabled.
|
-- ^ Indicate if auth dummy login should be enabled.
|
||||||
@ -87,6 +88,7 @@ instance FromJSON AppSettings where
|
|||||||
|
|
||||||
appCopyright <- o .: "copyright"
|
appCopyright <- o .: "copyright"
|
||||||
appAnalytics <- o .:? "analytics"
|
appAnalytics <- o .:? "analytics"
|
||||||
|
appCryptoIDKeyFile <- o .: "cryptoid-keyfile"
|
||||||
|
|
||||||
appAuthDummyLogin <- o .:? "auth-dummy-login" .!= defaultDev
|
appAuthDummyLogin <- o .:? "auth-dummy-login" .!= defaultDev
|
||||||
|
|
||||||
|
|||||||
@ -10,4 +10,7 @@ extra-deps:
|
|||||||
- colonnade-1.1.1
|
- colonnade-1.1.1
|
||||||
- yesod-colonnade-1.1.0
|
- yesod-colonnade-1.1.0
|
||||||
- zip-stream-0.1.0.1
|
- zip-stream-0.1.0.1
|
||||||
|
- uuid-crypto-1.1.0
|
||||||
|
- cryptoids-0.1.0
|
||||||
|
- cryptoids-types-0.0.0
|
||||||
resolver: lts-9.3
|
resolver: lts-9.3
|
||||||
|
|||||||
Reference in New Issue
Block a user