{-# LANGUAGE DataKinds #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE TypeOperators #-} module Cachix.Api ( servantApi , swaggerDoc , CachixAPI(..) , CachixServantAPI , CachixAuth , InstallAPI(..) , GitHubAPI(..) , BinaryCacheAPI(..) , BinaryCacheStreamingAPI(..) , BinaryCachStreamingServantAPI , module Cachix.Api.Types , module Cachix.Types.ContentTypes ) where import Control.Lens import Control.Monad.Trans.Resource import Data.ByteString (ByteString) import Data.Conduit (ConduitT) import Data.Proxy (Proxy(..)) import Data.Swagger hiding (Header) import Data.Text import GHC.Generics (Generic) import Servant.API hiding (BasicAuth) import Servant.API.Generic import Servant.Auth import Servant.Auth.Swagger () import Servant.Swagger import Web.Cookie (SetCookie) import Cachix.Types.ContentTypes import Cachix.Types.Servant (Get302, Post302, Head) import Cachix.Types.Session (Session) import Cachix.Types.SwaggerOrphans () import Cachix.Api.Types import qualified Cachix.Types.BinaryCacheCreate as BinaryCacheCreate import qualified Cachix.Types.BinaryCacheAuthenticated as BinaryCacheAuthenticated import qualified Cachix.Types.GitHubTeam as GitHubTeam import qualified Cachix.Types.NarInfoCreate as NarInfoCreate import qualified Cachix.Types.SigningKeyCreate as SigningKeyCreate type CachixAuth = Auth '[Cookie, JWT, BasicAuth] Session data BinaryCacheAPI route = BinaryCacheAPI { get :: route :- CachixAuth :> Get '[JSON] BinaryCache , create :: route :- CachixAuth :> ReqBody '[JSON] BinaryCacheCreate.BinaryCacheCreate :> Post '[JSON] NoContent -- https://cache.nixos.org/nix-cache-info , nixCacheInfo :: route :- CachixAuth :> "nix-cache-info" :> Get '[XNixCacheInfo, JSON] NixCacheInfo -- Hydra: src/lib/Hydra/View/NARInfo.pm , narinfo :: route :- CachixAuth :> Capture "narinfo" NarInfoC :> Get '[XNixNarInfo, JSON] NarInfo , narinfoHead :: route :- CachixAuth :> Capture "narinfo" NarInfoC :> Head , createNarinfo :: route :- Capture "narinfo" NarInfoC :> ReqBody '[JSON] NarInfoCreate.NarInfoCreate :> Post '[JSON] NoContent , createKey :: route :- CachixAuth :> "key" :> ReqBody '[JSON] SigningKeyCreate.SigningKeyCreate :> Post '[JSON] NoContent } deriving Generic -- | Streaming endpoints data BinaryCacheStreamingAPI route = BinaryCacheStreamingAPI { -- Hydra: src/lib/Hydra/View/NixNAR.pm nar :: route :- CachixAuth :> "nar" :> Capture "nar" NarC :> StreamGet NoFraming OctetStream (ConduitT () ByteString (ResourceT IO) ()) , createNar :: route :- "nar" :> StreamBody NoFraming XNixNar (ConduitT () ByteString (ResourceT IO) ()) :> Post '[JSON] NoContent } deriving Generic data InstallAPI route = InstallAPI { installGetLatest :: route :- Summary "Redirects to a tarball containing nix expression to build the latest version of cachix cli" :> Get302 '[JSON] '[] , installGetVersion :: route :- Summary "Redirects to a tarball containing nix expression to build given version of cachix cli" :> Capture "version" Text :> Get302 '[JSON] '[] } deriving Generic data GitHubAPI route = GitHubAPI { githubOrganizations :: route :- CachixAuth :> "orgs" :> Get '[JSON] [Text] , githubTeams :: route :- CachixAuth :> "orgs" :> Capture "org" Text :> "teams" :> Get '[JSON] [GitHubTeam.GitHubTeam] } deriving Generic data CachixAPI route = CachixAPI { logout :: route :- "logout" :> CachixAuth :> Post302 '[JSON] '[ Header "Set-Cookie" SetCookie , Header "Set-Cookie" SetCookie ] , login :: route :- "login" :> Get302 '[JSON] '[] , loginCallback :: route :- "login" :> "callback" :> QueryParam "code" Text :> QueryParam "state" Text :> Get302 '[JSON] '[ Header "Set-Cookie" SetCookie , Header "Set-Cookie" SetCookie ] , user :: route :- CachixAuth :> "user" :> Get '[JSON] User , createToken :: route :- CachixAuth :> "token" :> Post '[JSON] Text , caches :: route :- CachixAuth :> "cache" :> Get '[JSON] [BinaryCacheAuthenticated.BinaryCacheAuthenticated] , cache :: route :- "cache" :> Capture "name" Text :> ToServantApi BinaryCacheAPI , install :: route :- "install" :> ToServantApi InstallAPI , github :: route :- "github" :> ToServantApi GitHubAPI } deriving Generic type CachixServantAPI = "api" :> "v1" :> ToServantApi CachixAPI type BinaryCachStreamingServantAPI = "api" :> "v1" :> "cache" :> Capture "name" Text :> ToServantApi BinaryCacheStreamingAPI servantApi :: Proxy CachixServantAPI servantApi = Proxy swaggerDoc :: Swagger swaggerDoc = toSwagger servantApi & info.title .~ "cachix.org API" & info.version .~ "1.0" & info.description ?~ "TODO"