packages feed

password-types (empty) → 1.0.0.0

raw patch · 8 files changed

+320/−0 lines, 8 filesdep +QuickCheckdep +basedep +base-compatbuild-type:Customsetup-changed

Dependencies added: QuickCheck, base, base-compat, bytestring, doctest, memory, password-types, quickcheck-instances, tasty, tasty-quickcheck, template-haskell, text

Files

+ ChangeLog.md view
@@ -0,0 +1,7 @@+# Changelog for `password-types`++## 1.0.0.0++-   Split out this package from the `password` package to not saddle up+    users with a `cryptonite` dependency, when they might only want to+    use password data types.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) Dennis Gosnell, 2019; Felix Paulusma, 2020++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Dennis Gosnell, Felix Paulusma nor the names+      of other contributors may be used to endorse or promote products+      derived from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,12 @@+# password-types++[![Build Status](https://github.com/cdepillabout/password/workflows/password/badge.svg)](http://github.com/cdepillabout/password)+[![Hackage](https://img.shields.io/hackage/v/password-types.svg)](https://hackage.haskell.org/package/password-types)+[![Stackage LTS](http://stackage.org/package/password-types/badge/lts)](http://stackage.org/lts/package/password-types)+[![Stackage Nightly](http://stackage.org/package/password-types/badge/nightly)](http://stackage.org/nightly/package/password-types)+[![BSD3 license](https://img.shields.io/badge/license-BSD3-blue.svg)](./LICENSE)++This library provides datatypes for working with passwords and password hashes in Haskell.++Also, see the [password](https://hackage.haskell.org/package/password) package for+functions to hash and check passwords.
+ Setup.hs view
@@ -0,0 +1,33 @@+{-# LANGUAGE CPP #-}+{-# OPTIONS_GHC -Wall #-}+module Main (main) where++#ifndef MIN_VERSION_cabal_doctest+#define MIN_VERSION_cabal_doctest(x,y,z) 0+#endif++#if MIN_VERSION_cabal_doctest(1,0,0)++import Distribution.Extra.Doctest ( defaultMainWithDoctests )+main :: IO ()+main = defaultMainWithDoctests "doctests"++#else++#ifdef MIN_VERSION_Cabal+-- If the macro is defined, we have new cabal-install,+-- but for some reason we don't have cabal-doctest in package-db+--+-- Probably we are running cabal sdist, when otherwise using new-build+-- workflow+#warning You are configuring this package without cabal-doctest installed. \+         The doctests test-suite will not work as a result. \+         To fix this, install cabal-doctest before configuring.+#endif++import Distribution.Simple++main :: IO ()+main = defaultMain++#endif
+ password-types.cabal view
@@ -0,0 +1,86 @@+cabal-version: 1.12++name:           password-types+version:        1.0.0.0+category:       Data+synopsis:       Types for handling passwords+description:    A library providing types for working with plain-text and hashed passwords.+homepage:       https://github.com/cdepillabout/password/tree/master/password-types#readme+bug-reports:    https://github.com/cdepillabout/password/issues+author:         Dennis Gosnell, Felix Paulusma+maintainer:     cdep.illabout@gmail.com, felix.paulusma@gmail.com+copyright:      Copyright (c) Dennis Gosnell & Felix Paulusma, 2020+license:        BSD3+license-file:   LICENSE+build-type:     Custom+extra-source-files:+    README.md+    ChangeLog.md++custom-setup+  setup-depends:+      base+    , Cabal+    , cabal-doctest  >=1.0.6 && <1.1++source-repository head+  type: git+  location: https://github.com/cdepillabout/password++library+  hs-source-dirs:+      src+  exposed-modules:+      Data.Password.Types+  other-modules:+      Paths_password_types+  build-depends:+      base        >= 4.9 && < 5+    , bytestring            < 1+    , memory                < 0.16+    , text                  < 1.3+  ghc-options:+      -Wall+  default-language:+      Haskell2010++test-suite doctests+  type:+      exitcode-stdio-1.0+  hs-source-dirs:+      test/doctest+  main-is:+      doctest.hs+  ghc-options:+      -threaded -O2 -rtsopts -with-rtsopts=-N+  build-depends:+      base >=4.9 && <5+    , base-compat+    , doctest+    , password-types+    , QuickCheck+    , quickcheck-instances+    , template-haskell+  default-language:+      Haskell2010++test-suite password-types-tasty+  type:+      exitcode-stdio-1.0+  hs-source-dirs:+      test/tasty+  main-is:+      Spec.hs+  other-modules:+      Paths_password_types+  ghc-options:+      -threaded -O2 -rtsopts -with-rtsopts=-N+  build-depends:+      base >=4.9 && <5+    , password-types+    , quickcheck-instances+    , tasty+    , tasty-quickcheck+    , text+  default-language:+      Haskell2010
+ src/Data/Password/Types.hs view
@@ -0,0 +1,120 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-|+Module      : Data.Password.Types+Copyright   : (c) Dennis Gosnell, 2019; Felix Paulusma, 2020+License     : BSD-style (see LICENSE file)+Maintainer  : cdep.illabout@gmail.com+Stability   : experimental+Portability : POSIX++This library provides datatypes for interacting with passwords.+It provides the types 'Password' and 'PasswordHash', which correspond+to plain-text and hashed passwords.++== Special instances++There is an accompanying <http://hackage.haskell.org/package/password-instances password-instances>+package that provides canonical typeclass instances for+'Password' and 'PasswordHash' for many common typeclasses, like+<http://hackage.haskell.org/package/aeson/docs/Data-Aeson.html#t:FromJSON FromJSON> from+<http://hackage.haskell.org/package/aeson aeson>,+<http://hackage.haskell.org/package/persistent/docs/Database-Persist-Class.html#t:PersistField PersistField>+from+<http://hackage.haskell.org/package/persistent persistent>, etc.++See the <http://hackage.haskell.org/package/password-instances password-instances> package for more information.++== Phantom types++The 'PasswordHash' and 'Salt' data types have a phantom type parameter+to be able to make sure salts and hashes can carry information about the+algorithm they should be used with.++For example, the @bcrypt@ algorithm requires its salt to be exactly+16 bytes (128 bits) long, so this way you won't accidentally use a+@'Salt' PBKDF2@ when the hashing function requires a @'Salt' Bcrypt@.+And checking a password using @bcrypt@ would obviously fail if checked+against a @'PasswordHash' PBKDF2@.++-}++module Data.Password.Types (+    -- * Plain-text Password+    Password+  , mkPassword+    -- * Password Hashing+  , PasswordHash (..)+    -- ** Unsafe debugging function to show a Password+  , unsafeShowPassword+    -- * Hashing salts+  , Salt (..)+  ) where++import Data.ByteArray (constEq)+import Data.ByteString (ByteString)+import Data.Function (on)+import Data.String (IsString(..))+import Data.Text (Text)+import Data.Text.Encoding (encodeUtf8)++-- $setup+-- >>> :set -XOverloadedStrings++-- | A plain-text password.+--+-- This represents a plain-text password that has /NOT/ been hashed.+--+-- You should be careful with 'Password'. Make sure not to write it to logs or+-- store it in a database.+--+-- You can construct a 'Password' by using the 'mkPassword' function or as literal+-- strings together with the @OverloadedStrings@ pragma (or manually, by using+-- 'fromString' on a 'String'). Alternatively, you could also use some of the+-- instances in the <http://hackage.haskell.org/package/password-instances password-instances>+-- library.+newtype Password = Password Text+  deriving (IsString)++-- | CAREFUL: 'Show'-ing a 'Password' will always print @"**PASSWORD**"@+--+-- >>> show ("hello" :: Password)+-- "**PASSWORD**"+instance Show Password where+ show _ = "**PASSWORD**"++-- | Construct a 'Password'+mkPassword :: Text -> Password+mkPassword = Password+{-# INLINE mkPassword #-}++-- | This is an unsafe function that shows a password in plain-text.+--+-- >>> unsafeShowPassword ("foobar" :: Password)+-- "foobar"+--+-- You should generally __not use this function__ in production settings,+-- as you don't want to accidentally print a password anywhere, like+-- logs, network responses, database entries, etc.+--+-- This will mostly be used by other libraries to handle the actual+-- password internally, though it is conceivable that, even in a production+-- setting, a password might have to be handled in an unsafe manner at some point.+unsafeShowPassword :: Password -> Text+unsafeShowPassword (Password pass) = pass+{-# INLINE unsafeShowPassword #-}++-- | A hashed password.+--+-- This represents a password that has been put through a hashing function.+-- The hashed password can be stored in a database.+newtype PasswordHash a = PasswordHash+  { unPasswordHash :: Text+  } deriving (Ord, Read, Show)++instance Eq (PasswordHash a)  where+  (==) = constEq `on` encodeUtf8 . unPasswordHash++-- | A salt used by a hashing algorithm.+newtype Salt a = Salt+  { getSalt :: ByteString+  } deriving (Eq, Show)
+ test/doctest/doctest.hs view
@@ -0,0 +1,12 @@+module Main where++import Build_doctests (flags, pkgs, module_sources)+import System.Environment.Compat (unsetEnv)+import Test.DocTest (doctest)++main :: IO ()+main = do+  unsetEnv "GHC_ENVIRONMENT"+  doctest args+  where+    args = flags ++ pkgs ++ module_sources
+ test/tasty/Spec.hs view
@@ -0,0 +1,20 @@+module Main where++import Data.String (fromString)+import Data.Text (pack)+import Test.QuickCheck.Instances()+import Test.Tasty ( defaultMain, testGroup )+import Test.Tasty.QuickCheck ( (===), testProperty )++import Data.Password.Types ( mkPassword, unsafeShowPassword )++main :: IO ()+main = defaultMain $+  testGroup "Password"+    [ testProperty "mkPassword <-> unsafeShowPassword" $ \pass ->+        unsafeShowPassword (mkPassword pass) === pass+    , testProperty "Password always prints **PASSWORD**" $ \pass ->+        show (mkPassword pass) === "**PASSWORD**"+    , testProperty "fromString works" $ \pass ->+        unsafeShowPassword (fromString pass) === pack pass+    ]