Parse PermissionLevel (a simple sum data type).

This commit is contained in:
Philippe Pittoli 2023-05-27 12:26:03 +02:00
parent d17e29c1f5
commit 9d3e139b52
4 changed files with 58 additions and 15 deletions

View File

@ -26,6 +26,7 @@
, "transformers"
, "tuples"
, "uint"
, "variant"
, "web-encoding"
, "web-events"
, "web-socket"

View File

@ -18,6 +18,7 @@ import Data.ArrayBuffer.Types (ArrayBuffer)
import App.Email as Email
import App.Phone as Phone
import App.UserPublic as UserPublic
import App.PermissionLevel as PermissionLevel
import Effect.Class (liftEffect)
import Data.Argonaut.Parser as JSONParser
@ -30,28 +31,25 @@ import App.IPC as IPC
Possible requests:
- 1 type AddUser = { shared_key :: String, login :: String, password :: String, email :: Maybe String, phone :: Maybe Phone.Phone, profile :: Maybe Hash(String, JSON::Any) }
- 2 type ValidateUser = { login :: String, activation_key :: String }
- 3 type GetUser = { user :: Int32 | String }
- 3 type GetUser = { user :: Int | String }
- 4 type GetUserByCredentials = { login :: String, password :: String }
- 6 type Register = { login :: String, password :: String, email :: Maybe String, phone :: Maybe Phone.Phone , profile :: Maybe Hash(String, JSON::Any) }
- 7 type UpdatePassword = { login :: String, old_password :: String, new_password :: String }
- 8 type ListUsers = { token :: Maybe String, key :: Maybe String }
- 9 type CheckPermission = { shared_key :: Maybe String, token :: Maybe String, user :: Int32 | String, service :: String, resource :: String }
- 10 type SetPermission = { shared_key :: String, user :: Int32 | String, service :: String, resource :: String, permission :: AuthD::User::PermissionLevel }
- 11 type PasswordRecovery = { user :: Int32 | String, password_renew_key :: String, new_password :: String }
- 12 type AskPasswordRecovery = { user :: Int32 | String, email :: String }
- 9 type CheckPermission = { shared_key :: Maybe String, token :: Maybe String, user :: Int | String, service :: String, resource :: String }
- 10 type SetPermission = { shared_key :: String, user :: Int | String, service :: String, resource :: String, permission :: PermissionLevel.PermissionLevel }
- 11 type PasswordRecovery = { user :: Int | String, password_renew_key :: String, new_password :: String }
- 12 type AskPasswordRecovery = { user :: Int | String, email :: String }
- 13 type SearchUser = { user :: String }
- 14 type EditProfile = { token :: String, new_profile :: Hash(String, JSON::Any) }
- 15 type EditProfileContent = { token :: Maybe String, shared_key :: Maybe String, user :: Int32 | String | Nil, new_profile :: Hash(String, JSON::Any) }
- 15 type EditProfileContent = { token :: Maybe String, shared_key :: Maybe String, user :: Int | String | Nil, new_profile :: Hash(String, JSON::Any) }
- 16 type EditContacts = { token :: String, email :: Maybe String, phone :: Maybe Phone.Phone }
- 17 type Delete = { shared_key :: Maybe String, login :: Maybe String, password :: Maybe String, user :: String | Int32 }
- 17 type Delete = { shared_key :: Maybe String, login :: Maybe String, password :: Maybe String, user :: String | Int }
- 18 type GetContacts = { token :: String }
-- Deletion can be triggered by either an admin or the user.
Possible answers:
- 6 type UsersList = { users :: Array(UserPublic.UserPublic) }
- 7 type PermissionCheck = { user :: Int32, service :: String, resource :: String, permission :: AuthD::User::PermissionLevel }
- 8 type PermissionSet = { user :: Int32, service :: String, resource :: String, permission :: AuthD::User::PermissionLevel }
- 11 type MatchingUsers = { users :: Array(UserPublic.UserPublic) }
-}
@ -66,6 +64,9 @@ type User = { user :: UserPublic.UserPublic }
type UserAdded = { user :: UserPublic.UserPublic }
type UserEdited = { uid :: Int }
type UserValidated = { user :: UserPublic.UserPublic }
type UsersList = { users :: Array UserPublic.UserPublic }
type PermissionCheck = { user :: Int, service :: String, resource :: String, permission :: PermissionLevel.PermissionLevel }
type PermissionSet = { user :: Int, service :: String, resource :: String, permission :: PermissionLevel.PermissionLevel }
type Password = String
type GetToken = { login :: String, password :: String }
@ -172,8 +173,8 @@ decode number string
12 -> error_management codecGotContacts GotContacts
_ -> Left UnknownNumber
-- 6 type UsersList = { users :: Array(UserPublic.UserPublic) }
-- 7 type PermissionCheck = { user :: Int32, service :: String, resource :: String, permission :: AuthD::User::PermissionLevel }
-- 8 type PermissionSet = { user :: Int32, service :: String, resource :: String, permission :: AuthD::User::PermissionLevel }
-- 7 type PermissionCheck = { user :: Int, service :: String, resource :: String, permission :: PermissionLevel.PermissionLevel }
-- 8 type PermissionSet = { user :: Int, service :: String, resource :: String, permission :: PermissionLevel.PermissionLevel }
-- 11 type MatchingUsers = { users :: Array(UserPublic.UserPublic) }
where
-- Signature is required since the compiler's guess is wrong.

View File

@ -0,0 +1,39 @@
-- | TODO: Phone module should include at least some sort of smart
-- | constructors, rejecting invalid phone numbers.
module App.PermissionLevel where
import Prelude
import Data.Codec.Argonaut (JsonCodec)
import Data.Codec.Argonaut as CA
import Data.Codec.Argonaut.Variant as CAV
import Data.Variant as V
import Data.Profunctor (dimap)
import Data.Either (Either(..))
import Type.Proxy (Proxy(..))
data PermissionLevel
= None
| Read
| Edit
| Admin
codec ∷ CA.JsonCodec PermissionLevel
codec =
dimap toVariant fromVariant $ CAV.variantMatch { permission: Right CA.string }
where
toVariant = case _ of
None → V.inj (Proxy ∷ _ "permission") "none"
Read → V.inj (Proxy ∷ _ "permission") "read"
Edit → V.inj (Proxy ∷ _ "permission") "edit"
Admin → V.inj (Proxy ∷ _ "permission") "admin"
fromVariant = V.match
{ permission:
\s -> case s of
"none" -> None
"read" -> Read
"edit" -> Edit
"admin" -> Admin
_ -> None
}

View File

@ -7,9 +7,11 @@ import Data.Codec.Argonaut as CA
import Data.Codec.Argonaut.Record as CAR
import Data.Newtype (class Newtype)
-- | Currently not the real type. Lacks the 'profile' attribute.
-- type UserPublic row = { login :: String, uid :: Int | row } -- profile :: JSON any
type UserPublic = { login :: String, uid :: Int } -- profile :: JSON any
-- | Currently not the real type.
-- | Lacks 'profile' and 'date_registration' attributes.
-- type UserPublic row = { login :: String, uid :: Int | row }
-- TODO: add profile :: JSON any, date_registration :: Maybe Time
type UserPublic = { login :: String, uid :: Int }
-- | UserPublic.codec can be used to parse and encode public user info,
-- | which can be exchanged in different messages.