cachix-api 0.3.0 → 0.4.0
raw patch · 19 files changed
+313/−275 lines, 19 filesdep +josePVP ok
version bump matches the API change (PVP)
Dependencies added: jose
API changes (from Hackage documentation)
- Cachix.Api.Types: NarC :: Text -> NarC
- Cachix.Api.Types: instance Data.Swagger.Internal.ParamSchema.ToParamSchema Cachix.Api.Types.NarC
- Cachix.Api.Types: instance Data.Swagger.Internal.Schema.ToSchema Cachix.Api.Types.NarC
- Cachix.Api.Types: instance GHC.Generics.Generic Cachix.Api.Types.NarC
- Cachix.Api.Types: instance Web.Internal.HttpApiData.FromHttpApiData Cachix.Api.Types.NarC
- Cachix.Api.Types: instance Web.Internal.HttpApiData.ToHttpApiData Cachix.Api.Types.NarC
- Cachix.Api.Types: newtype NarC
- Cachix.Types.Session: Session :: UserId -> Session
- Cachix.Types.Session: instance Data.Aeson.Types.FromJSON.FromJSON Cachix.Types.Session.Session
- Cachix.Types.Session: instance Data.Aeson.Types.ToJSON.ToJSON Cachix.Types.Session.Session
- Cachix.Types.Session: instance GHC.Generics.Generic Cachix.Types.Session.Session
- Cachix.Types.Session: instance GHC.Show.Show Cachix.Types.Session.Session
- Cachix.Types.Session: newtype Session
- Cachix.Types.Session: type UserId = Integer
+ Cachix.Api: NarFileName :: Text -> Text -> NarFileName
+ Cachix.Api: [contentHash] :: NarFileName -> Text
+ Cachix.Api: [delete] :: BinaryCacheAPI route -> route :- (CachixAuth :> Delete '[JSON] NoContent)
+ Cachix.Api: [extension] :: NarFileName -> Text
+ Cachix.Api: [serveNarContent] :: BinaryCacheStreamingAPI route -> route :- (CachixAuth :> ("serve" :> (Capture "storehash" Text :> (CaptureAll "filepath" Text :> (Summary "Serve a file from a given store path" :> Get '[OctetStream] (Headers '[Header "X-Content-Type-Options" Text] ByteString))))))
+ Cachix.Api: data NarFileName
+ Cachix.Types.CreateToken: CreateToken :: Text -> CreateToken
+ Cachix.Types.CreateToken: [description] :: CreateToken -> Text
+ Cachix.Types.CreateToken: data CreateToken
+ Cachix.Types.CreateToken: instance Data.Aeson.Types.FromJSON.FromJSON Cachix.Types.CreateToken.CreateToken
+ Cachix.Types.CreateToken: instance Data.Aeson.Types.ToJSON.ToJSON Cachix.Types.CreateToken.CreateToken
+ Cachix.Types.CreateToken: instance Data.Swagger.Internal.Schema.ToSchema Cachix.Types.CreateToken.CreateToken
+ Cachix.Types.CreateToken: instance GHC.Generics.Generic Cachix.Types.CreateToken.CreateToken
+ Cachix.Types.CreateToken: instance GHC.Show.Show Cachix.Types.CreateToken.CreateToken
+ Cachix.Types.NarFileName: NarFileName :: Text -> Text -> NarFileName
+ Cachix.Types.NarFileName: [contentHash] :: NarFileName -> Text
+ Cachix.Types.NarFileName: [extension] :: NarFileName -> Text
+ Cachix.Types.NarFileName: data NarFileName
+ Cachix.Types.NarFileName: instance GHC.Generics.Generic Cachix.Types.NarFileName.NarFileName
+ Cachix.Types.NarFileName: instance Web.Internal.HttpApiData.FromHttpApiData Cachix.Types.NarFileName.NarFileName
+ Cachix.Types.NarFileName: instance Web.Internal.HttpApiData.ToHttpApiData Cachix.Types.NarFileName.NarFileName
+ Cachix.Types.Session: JWTSession :: ClaimsSet -> Session
+ Cachix.Types.Session: data Session
- Cachix.Api: BinaryCacheAPI :: (route :- (CachixAuth :> Get '[JSON] BinaryCache)) -> (route :- (CachixAuth :> (ReqBody '[JSON] BinaryCacheCreate :> Post '[JSON] NoContent))) -> (route :- (CachixAuth :> ("nix-cache-info" :> Get '[XNixCacheInfo, JSON] NixCacheInfo))) -> (route :- (CachixAuth :> (Capture "narinfo" NarInfoC :> Get '[XNixNarInfo, JSON] NarInfo))) -> (route :- (CachixAuth :> (Capture "narinfo" NarInfoC :> Head))) -> (route :- (CachixAuth :> ("narinfo" :> (Summary "Given a list of store hashes, return a list of those that are missing" :> (ReqBody '[JSON] [Text] :> Post '[JSON] [Text]))))) -> (route :- (Capture "narinfo" NarInfoC :> (ReqBody '[JSON] NarInfoCreate :> Post '[JSON] NoContent))) -> (route :- (CachixAuth :> ("key" :> (ReqBody '[JSON] SigningKeyCreate :> Post '[JSON] NoContent)))) -> BinaryCacheAPI route
+ Cachix.Api: BinaryCacheAPI :: (route :- (CachixAuth :> Get '[JSON] BinaryCache)) -> (route :- (CachixAuth :> (ReqBody '[JSON] BinaryCacheCreate :> Post '[JSON] NoContent))) -> (route :- (CachixAuth :> Delete '[JSON] NoContent)) -> (route :- (CachixAuth :> ("nix-cache-info" :> Get '[XNixCacheInfo, JSON] NixCacheInfo))) -> (route :- (CachixAuth :> (Capture "narinfo" NarInfoC :> Get '[XNixNarInfo, JSON] NarInfo))) -> (route :- (CachixAuth :> (Capture "narinfo" NarInfoC :> Head))) -> (route :- (CachixAuth :> ("narinfo" :> (Summary "Given a list of store hashes, return a list of those that are missing" :> (ReqBody '[JSON] [Text] :> Post '[JSON] [Text]))))) -> (route :- (Capture "narinfo" NarInfoC :> (ReqBody '[JSON] NarInfoCreate :> Post '[JSON] NoContent))) -> (route :- (CachixAuth :> ("key" :> (ReqBody '[JSON] SigningKeyCreate :> Post '[JSON] NoContent)))) -> BinaryCacheAPI route
- Cachix.Api: BinaryCacheStreamingAPI :: (route :- (CachixAuth :> ("nar" :> (Capture "nar" NarC :> StreamGet NoFraming OctetStream (ConduitT () ByteString (ResourceT IO) ()))))) -> (route :- ("nar" :> (StreamBody NoFraming XNixNar (ConduitT () ByteString (ResourceT IO) ()) :> Post '[JSON] NoContent))) -> BinaryCacheStreamingAPI route
+ Cachix.Api: BinaryCacheStreamingAPI :: (route :- (CachixAuth :> ("nar" :> (Capture "nar" NarFileName :> StreamGet NoFraming OctetStream (ConduitT () ByteString (ResourceT IO) ()))))) -> (route :- ("nar" :> (StreamBody NoFraming XNixNar (ConduitT () ByteString (ResourceT IO) ()) :> Post '[JSON] NoContent))) -> (route :- (CachixAuth :> ("serve" :> (Capture "storehash" Text :> (CaptureAll "filepath" Text :> (Summary "Serve a file from a given store path" :> Get '[OctetStream] (Headers '[Header "X-Content-Type-Options" Text] ByteString))))))) -> BinaryCacheStreamingAPI route
- Cachix.Api: CachixAPI :: (route :- ("logout" :> (CachixAuth :> Post302 '[JSON] '[Header "Set-Cookie" SetCookie, Header "Set-Cookie" SetCookie]))) -> (route :- ("login" :> Get302 '[JSON] '[])) -> (route :- ("login" :> ("callback" :> (QueryParam "code" Text :> (QueryParam "state" Text :> Get302 '[JSON] '[Header "Set-Cookie" SetCookie, Header "Set-Cookie" SetCookie]))))) -> (route :- (CachixAuth :> ("user" :> Get '[JSON] User))) -> (route :- (CachixAuth :> ("token" :> Post '[JSON] Text))) -> (route :- (CachixAuth :> ("cache" :> Get '[JSON] [BinaryCacheAuthenticated]))) -> (route :- ("cache" :> (Capture "name" Text :> ToServantApi BinaryCacheAPI))) -> (route :- ("install" :> ToServantApi InstallAPI)) -> (route :- ("github" :> ToServantApi GitHubAPI)) -> CachixAPI route
+ Cachix.Api: CachixAPI :: (route :- ("logout" :> (CachixAuth :> Post302 '[JSON] '[Header "Set-Cookie" SetCookie, Header "Set-Cookie" SetCookie]))) -> (route :- ("login" :> Get302 '[JSON] '[])) -> (route :- ("login" :> ("callback" :> (QueryParam "code" Text :> (QueryParam "state" Text :> Get302 '[JSON] '[Header "Set-Cookie" SetCookie, Header "Set-Cookie" SetCookie]))))) -> (route :- (CachixAuth :> ("user" :> Get '[JSON] User))) -> (route :- (CachixAuth :> ("token" :> (ReqBody '[JSON] CreateToken :> Post '[JSON] Text)))) -> (route :- (CachixAuth :> ("cache" :> Get '[JSON] [BinaryCacheAuthenticated]))) -> (route :- ("cache" :> (Capture "name" Text :> ToServantApi BinaryCacheAPI))) -> (route :- ("install" :> ToServantApi InstallAPI)) -> (route :- ("github" :> ToServantApi GitHubAPI)) -> CachixAPI route
- Cachix.Api: [createToken] :: CachixAPI route -> route :- (CachixAuth :> ("token" :> Post '[JSON] Text))
+ Cachix.Api: [createToken] :: CachixAPI route -> route :- (CachixAuth :> ("token" :> (ReqBody '[JSON] CreateToken :> Post '[JSON] Text)))
- Cachix.Api: [nar] :: BinaryCacheStreamingAPI route -> route :- (CachixAuth :> ("nar" :> (Capture "nar" NarC :> StreamGet NoFraming OctetStream (ConduitT () ByteString (ResourceT IO) ()))))
+ Cachix.Api: [nar] :: BinaryCacheStreamingAPI route -> route :- (CachixAuth :> ("nar" :> (Capture "nar" NarFileName :> StreamGet NoFraming OctetStream (ConduitT () ByteString (ResourceT IO) ()))))
Files
- CHANGELOG.md +6/−0
- cachix-api.cabal +7/−1
- cachix-gen-swagger/Main.hs +1/−0
- src/Cachix/Api.hs +151/−136
- src/Cachix/Api/Error.hs +17/−17
- src/Cachix/Api/Signing.hs +7/−7
- src/Cachix/Api/Types.hs +24/−41
- src/Cachix/Types/BinaryCacheAuthenticated.hs +6/−7
- src/Cachix/Types/BinaryCacheCreate.hs +6/−7
- src/Cachix/Types/ContentTypes.hs +6/−13
- src/Cachix/Types/CreateToken.hs +17/−0
- src/Cachix/Types/GitHubTeam.hs +6/−7
- src/Cachix/Types/NarFileName.hs +25/−0
- src/Cachix/Types/NarInfoCreate.hs +10/−10
- src/Cachix/Types/Servant.hs +3/−3
- src/Cachix/Types/Session.hs +13/−14
- src/Cachix/Types/SigningKeyCreate.hs +6/−7
- src/Cachix/Types/SwaggerOrphans.hs +1/−4
- test/Main.hs +1/−1
CHANGELOG.md view
@@ -7,6 +7,12 @@ ## [Unreleased] +## [0.4.0] - 2020-01-10++- #249 Serve nar content+- #247 Generalize auth to just JWTs+- NarC -> NarFileName+ ## [0.3.0] - 2019-09-03 - #216 Add bulk store path query
cachix-api.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.2 name: cachix-api-version: 0.3.0+version: 0.4.0 synopsis: Servant HTTP API specification for https://cachix.org homepage: https://github.com/cachix/cachix#readme bug-reports: https://github.com/cachix/cachix/issues@@ -16,6 +16,7 @@ common defaults default-extensions:+ NoImplicitPrelude DeriveAnyClass DeriveGeneric OverloadedStrings@@ -42,7 +43,9 @@ Cachix.Types.BinaryCacheAuthenticated Cachix.Types.BinaryCacheCreate Cachix.Types.ContentTypes+ Cachix.Types.CreateToken Cachix.Types.GitHubTeam+ Cachix.Types.NarFileName Cachix.Types.NarInfoCreate Cachix.Types.Servant Cachix.Types.Session@@ -62,8 +65,10 @@ , exceptions , http-api-data , http-media+ , jose , lens , memory+ , protolude , resourcet , servant >=0.14.1 , servant-auth@@ -84,6 +89,7 @@ , aeson , base >=4.7 && <5 , cachix-api+ , protolude test-suite cachix-api-test import: defaults
cachix-gen-swagger/Main.hs view
@@ -2,6 +2,7 @@ import Cachix.Api (swaggerDoc) import Data.Aeson (encode)+import Protolude main :: IO () main = print $ encode swaggerDoc
src/Cachix/Api.hs view
@@ -14,15 +14,18 @@ BinaryCacheStreamingAPI (..), BinaryCachStreamingServantAPI, module Cachix.Api.Types,- module Cachix.Types.ContentTypes- )+ module Cachix.Types.ContentTypes,+ module Cachix.Types.NarFileName,+ ) where import Cachix.Api.Types import qualified Cachix.Types.BinaryCacheAuthenticated as BinaryCacheAuthenticated import qualified Cachix.Types.BinaryCacheCreate as BinaryCacheCreate import Cachix.Types.ContentTypes+import qualified Cachix.Types.CreateToken as CreateToken import qualified Cachix.Types.GitHubTeam as GitHubTeam+import Cachix.Types.NarFileName (NarFileName (..)) import qualified Cachix.Types.NarInfoCreate as NarInfoCreate import Cachix.Types.Servant (Get302, Head, Post302) import Cachix.Types.Session (Session)@@ -31,11 +34,10 @@ import Control.Lens import Control.Monad.Trans.Resource import Data.ByteString (ByteString)+import qualified Data.ByteString.Lazy as BSL import Data.Conduit (ConduitT)-import Data.Proxy (Proxy (..)) import Data.Swagger hiding (Header)-import Data.Text-import GHC.Generics (Generic)+import Protolude import Servant.API hiding (BasicAuth) import Servant.API.Generic import Servant.Auth@@ -47,161 +49,174 @@ data BinaryCacheAPI route = BinaryCacheAPI- { get- :: route- :- CachixAuth- :> Get '[JSON] BinaryCache,- create- :: route- :- CachixAuth- :> ReqBody '[JSON] BinaryCacheCreate.BinaryCacheCreate- :> Post '[JSON] NoContent,+ { get ::+ route+ :- CachixAuth+ :> Get '[JSON] BinaryCache,+ create ::+ route+ :- CachixAuth+ :> ReqBody '[JSON] BinaryCacheCreate.BinaryCacheCreate+ :> Post '[JSON] NoContent,+ delete ::+ route+ :- CachixAuth+ :> Delete '[JSON] NoContent, -- https://cache.nixos.org/nix-cache-info- nixCacheInfo- :: route- :- CachixAuth- :> "nix-cache-info"- :> Get '[XNixCacheInfo, JSON] NixCacheInfo,+ 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,- narinfoBulk- :: route- :- CachixAuth- :> "narinfo"- :> Summary "Given a list of store hashes, return a list of those that are missing"- :> ReqBody '[JSON] [Text]- :> Post '[JSON] [Text],- createNarinfo- :: route- :- Capture "narinfo" NarInfoC- :> ReqBody '[JSON] NarInfoCreate.NarInfoCreate- :> Post '[JSON] NoContent,- createKey- :: route- :- CachixAuth- :> "key"- :> ReqBody '[JSON] SigningKeyCreate.SigningKeyCreate- :> Post '[JSON] NoContent- }+ narinfo ::+ route+ :- CachixAuth+ :> Capture "narinfo" NarInfoC+ :> Get '[XNixNarInfo, JSON] NarInfo,+ narinfoHead ::+ route+ :- CachixAuth+ :> Capture "narinfo" NarInfoC+ :> Head,+ narinfoBulk ::+ route+ :- CachixAuth+ :> "narinfo"+ :> Summary "Given a list of store hashes, return a list of those that are missing"+ :> ReqBody '[JSON] [Text]+ :> Post '[JSON] [Text],+ 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- }+ nar ::+ route+ :- CachixAuth+ :> "nar"+ :> Capture "nar" NarFileName+ :> StreamGet NoFraming OctetStream (ConduitT () ByteString (ResourceT IO) ()),+ createNar ::+ route+ :- "nar"+ :> StreamBody NoFraming XNixNar (ConduitT () ByteString (ResourceT IO) ())+ :> Post '[JSON] NoContent,+ serveNarContent ::+ route+ :- CachixAuth+ :> "serve"+ :> Capture "storehash" Text+ :> CaptureAll "filepath" Text+ :> Summary "Serve a file from a given store path"+ :> Get '[OctetStream] (Headers '[Header "X-Content-Type-Options" Text] BSL.ByteString)+ } 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] '[]- }+ { 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]- }+ { 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- }+ { 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"+ :> ReqBody '[JSON] CreateToken.CreateToken+ :> 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+type BinaryCachStreamingServantAPI =+ "api" :> "v1" :> "cache" :> Capture "name" Text :> ToServantApi BinaryCacheStreamingAPI servantApi :: Proxy CachixServantAPI servantApi = Proxy
src/Cachix/Api/Error.hs view
@@ -1,26 +1,26 @@ module Cachix.Api.Error ( escalate,- escalateAs- )+ escalateAs,+ ) where import Control.Exception (Exception) import Control.Monad.Catch (MonadThrow (throwM))--{- | Examples:- > escalate . maybeToEither err404+import Protolude - | Note that exceptions gets handled by warp and logged (user sees just "Internal server")--}-escalateAs- :: (Exception exc, MonadThrow m)- => (l -> exc)- -> Either l a- -> m a+-- | Examples:+-- > escalate . maybeToEither err404+--+-- | Note that exceptions gets handled by warp and logged (user sees just "Internal server")+escalateAs ::+ (Exception exc, MonadThrow m) =>+ (l -> exc) ->+ Either l a ->+ m a escalateAs f = either (throwM . f) pure -escalate- :: (Exception exc, MonadThrow m)- => Either exc a- -> m a-escalate = escalateAs id+escalate ::+ (Exception exc, MonadThrow m) =>+ Either exc a ->+ m a+escalate = escalateAs identity
src/Cachix/Api/Signing.hs view
@@ -2,8 +2,8 @@ ( fingerprint, passthroughSizeSink, passthroughHashSinkB16,- passthroughHashSink- )+ passthroughHashSink,+ ) where import Control.Monad.IO.Class (MonadIO, liftIO)@@ -15,17 +15,17 @@ import Data.Conduit import qualified Data.Conduit.Combinators as CC import Data.IORef-import Data.String.Conv (toS) import qualified Data.Text as T-import Data.Text (Text)+import Protolude -- perl/lib/Nix/Manifest.pm:fingerprintPath -- NB: references must be sorted fingerprint :: Text -> Text -> Integer -> [Text] -> ByteString fingerprint storePath narHash narSize references =- toS- $ T.intercalate ";"- ["1", storePath, narHash, T.pack (show narSize), T.intercalate "," references]+ toS $+ T.intercalate+ ";"+ ["1", storePath, narHash, show narSize, T.intercalate "," references] -- Useful sinks for streaming nars sizeSink :: MonadIO m => ConduitT ByteString o m Integer
src/Cachix/Api/Types.hs view
@@ -2,10 +2,9 @@ import Control.DeepSeq (NFData) import Data.Aeson (FromJSON, ToJSON)-import Data.Monoid ((<>)) import Data.Swagger (ToParamSchema, ToSchema)-import Data.Text (Text, dropEnd, takeEnd)-import GHC.Generics (Generic)+import Data.Text (dropEnd, takeEnd)+import Protolude import Servant.API data NixCacheInfo@@ -13,39 +12,39 @@ { storeDir :: Text, wantMassQuery :: Integer, priority :: Integer- }+ } deriving (Generic, Show, FromJSON, ToJSON, ToSchema) -- narinfo url includes storePath hash and .narinfo suffix data NarInfo = NarInfo- { storePath :: Text,- -- ^ absolute path of the derivation in nix store+ { -- | absolute path of the derivation in nix store+ storePath :: Text,+ -- | relative url (to current domain) to download nar file url :: Text,- -- ^ relative url (to current domain) to download nar file+ -- | name of the compression algorithm, eg. xz compression :: Text,- -- ^ name of the compression algorithm, eg. xz- fileHash :: Text,- -- ^ sha256 hash of the compressed nar file+ -- | sha256 hash of the compressed nar file -- NOTE: to compute use "nix-hash --type sha256 --flat"- fileSize :: Integer,- -- ^ file size of compressed nar file+ fileHash :: Text,+ -- | file size of compressed nar file -- NOTE: du -b- narHash :: Text,- -- ^ sha256 hash of the decompressed nar file+ fileSize :: Integer,+ -- | sha256 hash of the decompressed nar file -- NOTE: to compute use "nix-hash --type sha256 --flat --base32"- narSize :: Integer,- -- ^ file size of decompressed nar file+ narHash :: Text,+ -- | file size of decompressed nar file -- NOTE: du -b- references :: [Text],- -- ^ immediate dependencies of the storePath+ narSize :: Integer,+ -- | immediate dependencies of the storePath -- NOTE: nix-store -q --references- deriver :: Text,- -- ^ relative store path (to nix store root) of the deriver+ references :: [Text],+ -- | relative store path (to nix store root) of the deriver -- NOTE: nix-store -q --deriver+ deriver :: Text,+ -- | signature of fields: storePath, narHash, narSize, refs sig :: Text- -- ^ signature of fields: storePath, narHash, narSize, refs- }+ } deriving (Generic, Show, FromJSON, ToJSON, ToSchema) data BinaryCache@@ -55,41 +54,25 @@ isPublic :: Bool, publicSigningKeys :: [Text], githubUsername :: Text- }+ } deriving (Show, Generic, FromJSON, ToJSON, ToSchema, NFData) newtype BinaryCacheError = BinaryCacheError { error :: Text- }+ } deriving (Generic, FromJSON, ToJSON) --- | Hash of nar.xz file-newtype NarC = NarC Text deriving (Generic, ToSchema, ToParamSchema)--instance FromHttpApiData NarC where-- parseUrlPiece s =- if takeEnd 7 s == ".nar.xz"- then Right $ NarC (dropEnd 7 s)- else Left ""--instance ToHttpApiData NarC where-- toUrlPiece (NarC n) = n <> ".nar.xz"- -- | Store path hash newtype NarInfoC = NarInfoC Text deriving (Generic, ToSchema, ToParamSchema) instance FromHttpApiData NarInfoC where- parseUrlPiece s = if takeEnd 8 s == ".narinfo" then Right $ NarInfoC (dropEnd 8 s) else Left "" instance ToHttpApiData NarInfoC where- toUrlPiece (NarInfoC n) = n <> ".narinfo" data User@@ -100,7 +83,7 @@ hasOrgsAcccess :: Bool, activeSubscription :: SubscriptionType, subscriptionAccountId :: Maybe Text- }+ } deriving (Generic, FromJSON, ToJSON, ToSchema) data SubscriptionType = Community | Starter | Basic | Pro
src/Cachix/Types/BinaryCacheAuthenticated.hs view
@@ -1,15 +1,14 @@ module Cachix.Types.BinaryCacheAuthenticated- ( BinaryCacheAuthenticated (..)- )+ ( BinaryCacheAuthenticated (..),+ ) where import Data.Aeson ( FromJSON,- ToJSON- )+ ToJSON,+ ) import Data.Swagger-import Data.Text (Text)-import GHC.Generics (Generic)+import Protolude -- | Binary Cache response content when user is authenticated data BinaryCacheAuthenticated@@ -19,5 +18,5 @@ publicSigningKeys :: [Text], isPublic :: Bool, totalFileSize :: Integer- }+ } deriving (Show, Generic, FromJSON, ToJSON, ToSchema)
src/Cachix/Types/BinaryCacheCreate.hs view
@@ -1,15 +1,14 @@ module Cachix.Types.BinaryCacheCreate- ( BinaryCacheCreate (..)- )+ ( BinaryCacheCreate (..),+ ) where import Data.Aeson ( FromJSON,- ToJSON- )+ ToJSON,+ ) import Data.Swagger-import Data.Text (Text)-import GHC.Generics (Generic)+import Protolude data BinaryCacheCreate = BinaryCacheCreate@@ -17,5 +16,5 @@ isPublic :: Bool, githubOrganization :: Maybe Text, githubTeamId :: Maybe Int- }+ } deriving (Show, Generic, FromJSON, ToJSON, ToSchema)
src/Cachix/Types/ContentTypes.hs view
@@ -3,15 +3,15 @@ module Cachix.Types.ContentTypes ( XNixNar, XNixNarInfo,- XNixCacheInfo- )+ XNixCacheInfo,+ ) where import Cachix.Api.Types-import Data.ByteString (ByteString)-import Data.ByteString.Lazy (fromStrict, toStrict)+import qualified Data.ByteString.Lazy as BSL import Data.Typeable (Typeable) import qualified Network.HTTP.Media as M+import Protolude import Servant.API data XNixNar deriving (Typeable)@@ -21,29 +21,22 @@ data XNixCacheInfo deriving (Typeable) instance Accept XNixCacheInfo where- contentType _ = "application" M.// "octet-stream" instance Accept XNixNarInfo where- contentType _ = "text" M.// "x-nix-narinfo" instance Accept XNixNar where- contentType _ = "application" M.// "x-nix-nar" instance MimeUnrender XNixCacheInfo NixCacheInfo where- mimeUnrender _ _ = Left "TODO" instance MimeUnrender XNixNarInfo NarInfo where- mimeUnrender _ _ = Left "TODO" instance MimeRender XNixNar ByteString where-- mimeRender _ = fromStrict+ mimeRender _ = BSL.fromStrict instance MimeUnrender XNixNar ByteString where-- mimeUnrender _ = Right . toStrict+ mimeUnrender _ = Right . BSL.toStrict
+ src/Cachix/Types/CreateToken.hs view
@@ -0,0 +1,17 @@+module Cachix.Types.CreateToken+ ( CreateToken (..),+ )+where++import Data.Aeson+ ( FromJSON,+ ToJSON,+ )+import Data.Swagger+import Protolude++data CreateToken+ = CreateToken+ { description :: Text+ }+ deriving (Show, Generic, FromJSON, ToJSON, ToSchema)
src/Cachix/Types/GitHubTeam.hs view
@@ -1,19 +1,18 @@ module Cachix.Types.GitHubTeam- ( GitHubTeam (..)- )+ ( GitHubTeam (..),+ ) where import Data.Aeson ( FromJSON,- ToJSON- )+ ToJSON,+ ) import Data.Swagger-import Data.Text (Text)-import GHC.Generics (Generic)+import Protolude data GitHubTeam = GitHubTeam { id :: Int, name :: Text- }+ } deriving (Generic, FromJSON, ToJSON, ToSchema)
+ src/Cachix/Types/NarFileName.hs view
@@ -0,0 +1,25 @@+module Cachix.Types.NarFileName+ ( NarFileName (..),+ )+where++import Data.Text (dropEnd, takeEnd)+import Protolude+import Servant.API++-- | <hash>.nar.xz file+data NarFileName+ = NarFileName+ { contentHash :: Text,+ extension :: Text+ }+ deriving (Generic)++instance FromHttpApiData NarFileName where+ parseUrlPiece s =+ if takeEnd 7 s == ".nar.xz"+ then Right $ NarFileName (dropEnd 7 s) "xz"+ else Left "Wrong extension"++instance ToHttpApiData NarFileName where+ toUrlPiece narfilename = contentHash narfilename <> ".nar." <> extension narfilename
src/Cachix/Types/NarInfoCreate.hs view
@@ -1,26 +1,26 @@ module Cachix.Types.NarInfoCreate ( NarInfoCreate (..), NarInfoInvalid,- isNarInfoCreateValid- )+ isNarInfoCreateValid,+ ) where -import Control.Exception (Exception) import Data.Aeson ( FromJSON,- ToJSON- )+ ToJSON,+ ) import Data.Swagger-import Data.Text (Text)-import GHC.Generics (Generic)+import Protolude -- TODO: get rid of c prefix -- | Client create type data NarInfoCreate = NarInfoCreate- { cStoreHash :: Text, -- ^ $storePrefix / $storeHash - $storeSuffix- cStoreSuffix :: Text, -- ^ $storePrefix / $storeHash - $storeSuffix+ { -- | \$storePrefix / $storeHash - $storeSuffix+ cStoreHash :: Text,+ -- | \$storePrefix / $storeHash - $storeSuffix+ cStoreSuffix :: Text, cNarHash :: Text, cNarSize :: Integer, cFileHash :: Text,@@ -28,7 +28,7 @@ cReferences :: [Text], cDeriver :: Text, cSig :: Text- }+ } deriving (Generic, Show, FromJSON, ToJSON, ToSchema) data NarInfoInvalid
src/Cachix/Types/Servant.hs view
@@ -6,11 +6,11 @@ module Cachix.Types.Servant ( Get302, Post302,- Head- )+ Head,+ ) where -import Data.Text (Text)+import Protolude import Servant.API -- Location header as per https://github.com/haskell-servant/servant/issues/117#issuecomment-381398666
src/Cachix/Types/Session.hs view
@@ -1,20 +1,19 @@-{-# LANGUAGE DeriveAnyClass #-}-{-# LANGUAGE DeriveGeneric #-}---- | Module for auth session storage+-- | Auth representations module Cachix.Types.Session ( Session (..),- UserId- )+ ) where -import Data.Aeson (FromJSON, ToJSON)-import GHC.Generics (Generic)--- TODO: move these two into Servant.Auth-import Servant.Auth.Server (FromJWT, ToJWT)+import qualified Crypto.JWT as JWT+import Protolude+import Servant.Auth.Server (FromJWT (..), ToJWT (..)) -type UserId = Integer+data Session+ = JWTSession JWT.ClaimsSet+ deriving (Eq) -newtype Session- = Session UserId- deriving (Eq, Show, Generic, FromJSON, ToJSON, FromJWT, ToJWT)+instance ToJWT Session where+ encodeJWT (JWTSession s) = s++instance FromJWT Session where+ decodeJWT cs = pure $ JWTSession cs
src/Cachix/Types/SigningKeyCreate.hs view
@@ -1,19 +1,18 @@ module Cachix.Types.SigningKeyCreate- ( SigningKeyCreate (..)- )+ ( SigningKeyCreate (..),+ ) where import Data.Aeson ( FromJSON,- ToJSON- )+ ToJSON,+ ) import Data.Swagger-import Data.Text (Text)-import GHC.Generics (Generic)+import Protolude -- | Conveys that a signing secret key was created, by sharing the public key. newtype SigningKeyCreate = SigningKeyCreate { publicKey :: Text- }+ } deriving (Show, Generic, FromJSON, ToJSON, ToSchema)
src/Cachix/Types/SwaggerOrphans.hs view
@@ -8,12 +8,9 @@ module Cachix.Types.SwaggerOrphans where -import Control.DeepSeq (NFData)-import Data.Proxy (Proxy(..))+import Protolude import Data.Conduit (ConduitT) import Data.Swagger (ToSchema(..))-import Servant.API (NoContent)- -- TODO: upstream to servant-conduit instance ToSchema i => ToSchema (ConduitT i o m r) where
test/Main.hs view
@@ -11,4 +11,4 @@ config = defaultConfig { configColorMode = ColorAlways- }+ }