{-# LANGUAGE DeriveGeneric #-} module Network.Oz.Types ( OzTicket(..) , OzSealedTicket(..) , OzApp(..) , OzGrant(..) , OzExt(..) , TicketOpts(..) , defaultTicketOpts , OzAppId , OzUserId , OzGrantId , OzPermission , OzScope , OzTicketId , OzLoadApp , OzLoadGrant , Endpoints(..) , defaultEndpoints ) where import Crypto.Hash.Algorithms (SHA256 (..)) import Data.Aeson (Object) import Data.ByteString (ByteString) import Data.Text (Text) import Data.Time.Clock (NominalDiffTime) import Data.Time.Clock.POSIX (POSIXTime) import GHC.Generics import Data.Default (Default(..)) import Network.Hawk (HawkAlgo) import Network.Hawk.Types import qualified Network.Iron as Iron -- | Identifies an Oz Application type OzAppId = Text -- | Identifies a user type OzUserId = Text -- | Identifies an Oz grant type OzGrantId = Text -- | Tag representing permissions of application type OzPermission = Text -- | Set of permissions for application type OzScope = [OzPermission] -- | Oz ticket identifier, which is also a 'Network.Iron' encrypted -- version of the ticket. type OzTicketId = Text -- | An object describing an application. data OzApp = OzApp { ozAppId :: OzAppId -- ^ The application identifier -- | An array with the default application scope. , ozAppScope :: Maybe OzScope -- | If true, the application is allowed to delegate a -- ticket to another application. Defaults to false. , ozAppDelegate :: Bool -- | The shared secret used to authenticate. , ozAppKey :: Key -- | The HMAC algorithm used to authenticate. , ozAppAlgorithm :: HawkAlgo } deriving (Show, Generic) -- | A grant is the authorization given to an application by a user to -- access the user's protected resources. Grants can be persisted in a -- database (usually to support revocation) or can be self describing -- (using an encoded identifier). data OzGrant = OzGrant { ozGrantId :: OzGrantId -- ^ The grant identifier -- | The application identifier. , ozGrantApp :: OzAppId -- | The user identifier. , ozGrantUser :: OzUserId -- | Grant expiration time , ozGrantExp :: POSIXTime -- | An array with the scope granted by the user to the application. , ozGrantScope :: Maybe OzScope } deriving (Show, Generic) -- | An object used to include custom server data in the ticket and -- response. The public part is included in the Oz reponse under -- ticket.ext. The private part is only available within the encoded -- ticket. data OzExt = OzExt { ozExtPublic :: Object -- ^ Public ext; included in response , ozExtPrivate :: Object -- ^ Private ext; only in encoded ticket. } deriving (Show, Eq, Generic) instance Monoid OzExt where mempty = OzExt mempty mempty mappend (OzExt a b) (OzExt c d) = OzExt (mappend a c) (mappend b d) -- | A sealed ticket is the result of 'Network.Oz.Ticket.issue'. It is -- JSON-encoded and given to the app. -- -- Unlike most Hawk credential identifiers, the Oz ticket identifier -- is an encoded Iron string which when decoded contains an 'OzTicket' data OzSealedTicket = OzSealedTicket { ozTicket :: OzTicket , ozTicketKey :: Key -- ^ A shared secret used to authenticate. , ozTicketAlgorithm :: HawkAlgo -- ^ The HMAC algorithm used to authenticate (e.g. HMAC-SHA256). , ozTicketExt :: Object -- ^ Custom server public data attached to the ticket. , ozTicketId :: OzTicketId -- ^ The ticket identifier used for making authenticated Hawk requests. } deriving (Show, Generic) -- | An object describing a ticket and its public properties. An Oz -- ticket is a set of Hawk credentials used by the application to -- access protected resources. Just like any other Hawk credentials. data OzTicket = OzTicket { -- | Ticket expiration time. ozTicketExp :: POSIXTime -- | The application id the ticket was issued to. , ozTicketApp :: OzAppId -- | The user id if the ticket represents access to -- user resources. If no user id is included, the -- ticket allows the application access to the -- application own resources only. , ozTicketUser :: Maybe OzUserId -- | The ticket scope. Defaults to @[]@ if no scope is -- specified. , ozTicketScope :: OzScope -- | If user is set, includes the grant identifier -- referencing the authorization granted by the user -- to the application. Can be a unique identifier or -- string encoding the grant information as long as -- the server is able to parse the information later. , ozTicketGrant :: Maybe OzGrantId -- | If false, the ticket cannot be delegated -- regardless of the application permissions. Defaults -- to true which means use the application permissions -- to delegate. , ozTicketDelegate :: Bool -- | If the ticket is the result of access delegation, -- the application id of the delegating application. , ozTicketDlg :: Maybe OzAppId } deriving (Show, Generic) -- | Ticket generation options. The default values are: -- -- * One hour ticket lifetime. -- * One minute RSVP lifetime. -- * Use the application permissions to delegate. -- * 'Network.Iron.defaults' Iron configuration. -- * 32 byte Hawk key length. -- * 'Crypto.Hash.Algorithms.SHA256' message authentication. -- * No ext data. data TicketOpts = TicketOpts { ticketOptsTicketTtl :: NominalDiffTime -- ^ Ticket lifetime , ticketOptsRsvpTtl :: NominalDiffTime -- ^ RSVP lifetime -- | If false, the ticket cannot be delegated -- regardless of the application -- permissions. , ticketOptsDelegate :: Bool -- | Overrides the default Iron configuration. , ticketOptsIron :: Iron.Options -- | The Hawk key length in bytes. , ticketOptsKeyBytes :: Int -- | The Hawk HMAC algorithm. , ticketOptsHmacAlgorithm :: HawkAlgo -- | Custom server data to be included in the ticket. , ticketOptsExt :: OzExt } defaultTicketOpts :: TicketOpts defaultTicketOpts = TicketOpts 3600 60 True iron 32 (HawkAlgo SHA256) mempty where iron = Iron.options Iron.AES256CBC Iron.SHA256 256 100000 instance Default TicketOpts where def = defaultTicketOpts -- | User-supplied function to look up an Oz app definition by its -- identifier. type OzLoadApp = OzAppId -> IO (Either String OzApp) -- | User-supplied function to look up an Oz grant by its identifier. type OzLoadGrant = OzGrantId -> IO (Either String (OzGrant, Maybe OzExt)) -- | Describes the URL configuration of the Oz server. data Endpoints = Endpoints { endpointApp :: Text , endpointReissue :: Text , endpointRsvp :: Text } deriving Show -- | A normal set of endpoint URL paths. defaultEndpoints :: Endpoints defaultEndpoints = Endpoints "/oz/app" "/oz/reissue" "/oz/rsvp"