Skip to content

Library for easy obfuscation and deobfuscation of integer IDs in custom data types

License

Notifications You must be signed in to change notification settings

foxhound-systems/hs-obfuscate

Repository files navigation

Obfuscate

This library makes it easy to use obfuscation in your application code, allowing you to obscure numeric ids before sending them to a client (such as in a JSON API or other web service). This library is backed by foxhound-systems/hashids-st, which itself is an implementation of the Hashids.org obfuscation interface.

Implementation

The Web.Obfuscate module provides CanObfuscate and CanDeobfuscate typeclasses along with several default instances for basic data types. In addition to manually defining your own instances, Web.Obfuscate.TH will derive a sensible default using deriveObfuscate.

Example Usage

Basic Usage

import Web.Obfuscate
import Hashids

...

hashidsContext :: HashidsContext
hashidsContext = ctx
    where
      (Right ctx) = mkHashidsContext "test-salt-please-ignore" 7 defaultAlphabet

getUser :: Obfuscated UserId -> IO (User)
getUser obfuscatedUserId =
    maybeUserId <- deobfuscate hashidsContext obfuscatedUserId
    case maybeUserId of
        Just userId ->
          fetchUserById userId

        Nothing ->
          throwIO err400

Deriving Obfuscation Instances with Template Haskell

{-# LANGUAGE TemplateHaskell #-}

module ForumResponse
  where

import Web.Obfuscate
import Web.Obfuscate.TH
import qualified Data.Text as T

-- Another module that defines another custom obfuscatable type
import ForumAdministrator

data ForumResponse = ForumResponse
  { frForumId :: ForumId
  , frName :: Text
  , frDescription :: Text
  , frCreator :: ForumAdministrator
  , frAdministrators :: [ForumAdministrator]
  }

$(deriveObfuscate defaultObfuscationOptions ''ForumResponse)

The above Template Haskell code will generate something like the following:

data ObfuscatedForumResponse = ObfuscatedForumResponse
    { obfrForumId :: Obfuscated ForumId
    , obfrName :: Text
    , obfrDescription :: Text
    , obfrCreator :: Obfuscated ForumAdministrator
    , obfrAdministrators :: Obfuscated [ForumAdministrator]
    }

type instance Obfuscated ForumResponse = ObfuscatedForumResponse

instance CanObfuscate ForumResponse where
    obfuscate ctx forumResponse =
        ObfuscatedForumResponse
            { obfrForumId = obfuscate ctx $ frForumId forumResponse
            , obfrName = frName forumResponse
            , obfrDescription = frDescription forumResponse
            , obfrCreator = obfuscate ctx $ frCreator forumResponse
            , obfrAdministrators = obfuscate ctx $ frAdministrators forumResponse
            }

instance CanDeobfuscateForumResponse where
    deobfuscate ctx obfuscatedForumResponse = do
        forumId <- deobfuscate ctx $ obfrForumId obfuscatedForumResponse
        creator <- deobfuscate ctx $ obfrCreator obfuscatedForumResponse
        administrators <- deobfuscate ctx $ obfrAdministrators obfuscatedForumResponse
        pure $ ForumResponse
            { frForumId = forumId
            , frName = obfrName obfuscatedForumResponse
            , frDescription = obfrDescription obfuscatedForumResponse
            , frCreator = creator
            , frAdministrators = administrators
            }

Development

Development of this library is done using Nix. With nix installed, following command to start a ghcid session in an isolated environment and run the reloading tests:

nix-shell --run "make tests-watch"

Run nix-build to perform a full build of the library.

License

See the LICENSE file.

About

Library for easy obfuscation and deobfuscation of integer IDs in custom data types

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published