Implement Credentials conversion into API

pull/1/head
Bram van den Heuvel 2023-03-13 17:04:52 +01:00
parent 81a591383f
commit e7804b096f
6 changed files with 103 additions and 163 deletions

View File

@ -1,7 +1,7 @@
module Internal.Api.CredUpdate exposing (..) module Internal.Api.CredUpdate exposing (..)
import Internal.Api.Chain as Chain exposing (IdemChain, TaskChain) import Internal.Api.Chain as Chain exposing (IdemChain, TaskChain)
import Internal.Tools.Context as Context exposing (VB, VBA, VBAT) import Internal.Api.Credentials as Credentials exposing (Credentials)
import Internal.Api.GetEvent.Main as GetEvent import Internal.Api.GetEvent.Main as GetEvent
import Internal.Api.Invite.Main as Invite import Internal.Api.Invite.Main as Invite
import Internal.Api.JoinedMembers.Main as JoinedMembers import Internal.Api.JoinedMembers.Main as JoinedMembers
@ -12,6 +12,7 @@ import Internal.Api.SendStateKey.Main as SendStateKey
import Internal.Api.Sync.Main as Sync import Internal.Api.Sync.Main as Sync
import Internal.Api.Versions.Main as Versions import Internal.Api.Versions.Main as Versions
import Internal.Api.Versions.V1.Versions as V import Internal.Api.Versions.V1.Versions as V
import Internal.Tools.Context as Context exposing (VB, VBA, VBAT)
import Internal.Tools.Exceptions as X import Internal.Tools.Exceptions as X
import Internal.Tools.LoginValues exposing (AccessToken(..)) import Internal.Tools.LoginValues exposing (AccessToken(..))
import Internal.Tools.SpecEnums as Enums import Internal.Tools.SpecEnums as Enums
@ -215,6 +216,34 @@ loginWithUsernameAndPassword ({ username, password } as data) context =
) )
{-| Make a VB-context based chain.
-}
makeVB : Credentials -> TaskChain CredUpdate {} (VB {})
makeVB cred =
cred
|> Credentials.baseUrl
|> withBaseUrl
|> Chain.andThen (versions (Credentials.versions cred))
{-| Make a VBA-context based chain.
-}
makeVBA : Credentials -> TaskChain CredUpdate {} (VBA {})
makeVBA cred =
cred
|> makeVB
|> Chain.andThen (accessToken (Credentials.accessToken cred))
{-| Make a VBAT-context based chain.
-}
makeVBAT : (Int -> String) -> Credentials -> TaskChain CredUpdate {} (VBAT {})
makeVBAT toString cred =
cred
|> makeVBA
|> Chain.andThen (withTransactionId toString)
type alias RedactInput = type alias RedactInput =
{ eventId : String { eventId : String
, reason : Maybe String , reason : Maybe String

View File

@ -1,11 +1,8 @@
module Internal.Credentials exposing (..) module Internal.Api.Credentials exposing (..)
{-| The `Credentials` type serves as an extra layer between the internal Room/Event types
and the types that the user may deal with directly.
Since pointers cannot point to values that the `Vault` type has,
the `Vault` type passes information down in the form of a `Credentials` type.
{-| The `Credentials` type stitches the Vault together to the Matrix API.
It stores tokens and values needed to interact with the API, and it provides
the necessary context when the user aims to talk to the Matrix API.
-} -}
import Internal.Api.Versions.V1.Versions as V import Internal.Api.Versions.V1.Versions as V

View File

@ -5,10 +5,8 @@ module Internal.Api.Task exposing (..)
import Hash import Hash
import Internal.Api.Chain as Chain import Internal.Api.Chain as Chain
import Internal.Api.CredUpdate as C exposing (CredUpdate) import Internal.Api.CredUpdate as C
import Internal.Api.Versions.V1.Versions as V import Internal.Api.Credentials exposing (Credentials)
import Internal.Tools.LoginValues exposing (AccessToken)
import Internal.Tools.SpecEnums as Enums
import Json.Encode as E import Json.Encode as E
@ -16,89 +14,48 @@ type alias FutureTask =
C.FutureTask C.FutureTask
type alias GetEventInput = getEvent : C.GetEventInput -> Credentials -> FutureTask
{ accessToken : AccessToken getEvent data cred =
, baseUrl : String C.makeVBA cred
, eventId : String |> Chain.andThen (C.getEvent data)
, roomId : String
, versions : Maybe V.Versions
}
getEvent : GetEventInput -> FutureTask
getEvent { accessToken, baseUrl, eventId, roomId, versions } =
C.withBaseUrl baseUrl
|> Chain.andThen (C.versions versions)
|> Chain.andThen (C.accessToken accessToken)
|> Chain.andThen (C.getEvent { eventId = eventId, roomId = roomId })
|> C.toTask |> C.toTask
type alias InviteInput = invite : C.InviteInput -> Credentials -> FutureTask
{ accessToken : AccessToken invite data cred =
, baseUrl : String C.makeVBA cred
, reason : Maybe String |> Chain.andThen (C.invite data)
, roomId : String
, userId : String
, versions : Maybe V.Versions
}
invite : InviteInput -> FutureTask
invite { accessToken, baseUrl, reason, roomId, userId, versions } =
C.withBaseUrl baseUrl
|> Chain.andThen (C.versions versions)
|> Chain.andThen (C.accessToken accessToken)
|> Chain.andThen (C.invite { reason = reason, roomId = roomId, userId = userId })
|> C.toTask |> C.toTask
type alias JoinedMembersInput = joinedMembers : C.JoinedMembersInput -> Credentials -> FutureTask
{ accessToken : AccessToken joinedMembers data cred =
, baseUrl : String C.makeVBA cred
, roomId : String |> Chain.andThen (C.joinedMembers data)
, versions : Maybe V.Versions
}
joinedMembers : JoinedMembersInput -> FutureTask
joinedMembers { accessToken, baseUrl, roomId, versions } =
C.withBaseUrl baseUrl
|> Chain.andThen (C.versions versions)
|> Chain.andThen (C.accessToken accessToken)
|> Chain.andThen (C.joinedMembers { roomId = roomId })
|> C.toTask |> C.toTask
type alias RedactInput = type alias RedactInput =
{ accessToken : AccessToken { eventId : String
, baseUrl : String
, eventId : String
, extraTransactionNoise : String , extraTransactionNoise : String
, reason : Maybe String , reason : Maybe String
, roomId : String , roomId : String
, versions : Maybe V.Versions
} }
redact : RedactInput -> FutureTask redact : RedactInput -> Credentials -> FutureTask
redact { accessToken, baseUrl, eventId, extraTransactionNoise, reason, roomId, versions } = redact { eventId, extraTransactionNoise, reason, roomId } cred =
C.withBaseUrl baseUrl cred
|> Chain.andThen (C.versions versions) |> C.makeVBAT
|> Chain.andThen (C.accessToken accessToken) (\now ->
|> Chain.andThen [ Hash.fromInt now
(C.withTransactionId , Hash.fromString eventId
(\now -> , Hash.fromString extraTransactionNoise
[ Hash.fromInt now , Hash.fromString (reason |> Maybe.withDefault "noreason")
, Hash.fromString baseUrl , Hash.fromString roomId
, Hash.fromString eventId ]
, Hash.fromString extraTransactionNoise |> List.foldl Hash.independent (Hash.fromString "redact")
, Hash.fromString (reason |> Maybe.withDefault "noreason") |> Hash.toString
, Hash.fromString roomId
]
|> List.foldl Hash.independent (Hash.fromString "redact")
|> Hash.toString
)
) )
|> Chain.andThen (C.redact { eventId = eventId, reason = reason, roomId = roomId }) |> Chain.andThen (C.redact { eventId = eventId, reason = reason, roomId = roomId })
|> Chain.andThen |> Chain.andThen
@ -107,85 +64,42 @@ redact { accessToken, baseUrl, eventId, extraTransactionNoise, reason, roomId, v
type alias SendMessageEventInput = type alias SendMessageEventInput =
{ accessToken : AccessToken { content : E.Value
, baseUrl : String
, content : E.Value
, eventType : String , eventType : String
, extraTransactionNoise : String , extraTransactionNoise : String
, roomId : String , roomId : String
, versions : Maybe V.Versions
} }
sendMessageEvent : SendMessageEventInput -> FutureTask sendMessageEvent : SendMessageEventInput -> Credentials -> FutureTask
sendMessageEvent { accessToken, baseUrl, content, eventType, extraTransactionNoise, roomId, versions } = sendMessageEvent { content, eventType, extraTransactionNoise, roomId } cred =
C.withBaseUrl baseUrl cred
|> Chain.andThen (C.versions versions) |> C.makeVBAT
|> Chain.andThen (C.accessToken accessToken) (\now ->
|> Chain.andThen [ Hash.fromInt now
(C.withTransactionId , Hash.fromString (E.encode 0 content)
(\now -> , Hash.fromString eventType
[ Hash.fromInt now , Hash.fromString extraTransactionNoise
, Hash.fromString baseUrl , Hash.fromString roomId
, Hash.fromString (E.encode 0 content) ]
, Hash.fromString eventType |> List.foldl Hash.independent (Hash.fromString "send message")
, Hash.fromString extraTransactionNoise |> Hash.toString
, Hash.fromString roomId
]
|> List.foldl Hash.independent (Hash.fromString "send message")
|> Hash.toString
)
) )
|> Chain.andThen (C.sendMessageEvent { content = content, eventType = eventType, roomId = roomId }) |> Chain.andThen (C.sendMessageEvent { content = content, eventType = eventType, roomId = roomId })
-- TODO: Get event from API to see what it looks like -- TODO: Get event from API to see what it looks like
|> C.toTask |> C.toTask
type alias SendStateKeyInput = sendStateKey : C.SendStateEventInput -> Credentials -> FutureTask
{ accessToken : AccessToken sendStateKey data cred =
, baseUrl : String C.makeVBA cred
, content : E.Value |> Chain.andThen (C.sendStateEvent data)
, eventType : String
, roomId : String
, stateKey : String
, versions : Maybe V.Versions
}
sendStateKey : SendStateKeyInput -> FutureTask
sendStateKey { accessToken, baseUrl, content, eventType, roomId, stateKey, versions } =
C.withBaseUrl baseUrl
|> Chain.andThen (C.versions versions)
|> Chain.andThen (C.accessToken accessToken)
|> Chain.andThen (C.sendStateEvent { content = content, eventType = eventType, roomId = roomId, stateKey = stateKey })
-- TODO: Get event from API to see what it looks like -- TODO: Get event from API to see what it looks like
|> C.toTask |> C.toTask
type alias SyncInput = sync : C.SyncInput -> Credentials -> FutureTask
{ accessToken : AccessToken sync data cred =
, baseUrl : String C.makeVBA cred
, filter : Maybe String |> Chain.andThen (C.sync data)
, fullState : Maybe Bool
, setPresence : Maybe Enums.UserPresence
, since : Maybe String
, timeout : Maybe Int
, versions : Maybe V.Versions
}
sync : SyncInput -> FutureTask
sync { accessToken, baseUrl, filter, fullState, setPresence, since, timeout, versions } =
C.withBaseUrl baseUrl
|> Chain.andThen (C.versions versions)
|> Chain.andThen (C.accessToken accessToken)
|> Chain.andThen
(C.sync
{ filter = filter
, fullState = fullState
, setPresence = setPresence
, since = since
, timeout = timeout
}
)
|> C.toTask |> C.toTask

View File

@ -7,10 +7,10 @@ resend other events or forward them elsewhere.
-} -}
import Internal.Api.Credentials exposing (Credentials)
import Internal.Api.GetEvent.Main as GetEvent import Internal.Api.GetEvent.Main as GetEvent
import Internal.Api.GetEvent.V1.SpecObjects as GetEventSO import Internal.Api.GetEvent.V1.SpecObjects as GetEventSO
import Internal.Api.Sync.V2.SpecObjects as SyncSO import Internal.Api.Sync.V2.SpecObjects as SyncSO
import Internal.Credentials exposing (Credentials)
import Internal.Tools.Timestamp exposing (Timestamp) import Internal.Tools.Timestamp exposing (Timestamp)
import Internal.Values.Event as Internal import Internal.Values.Event as Internal
import Json.Encode as E import Json.Encode as E

View File

@ -5,9 +5,9 @@ module Internal.Room exposing (..)
import Dict import Dict
import Internal.Api.CredUpdate exposing (CredUpdate) import Internal.Api.CredUpdate exposing (CredUpdate)
import Internal.Api.Credentials as Credentials exposing (Credentials)
import Internal.Api.Sync.V2.SpecObjects as Sync import Internal.Api.Sync.V2.SpecObjects as Sync
import Internal.Api.Task as Api import Internal.Api.Task as Api
import Internal.Credentials as Credentials exposing (Credentials)
import Internal.Event as Event exposing (Event) import Internal.Event as Event exposing (Event)
import Internal.Tools.Exceptions as X import Internal.Tools.Exceptions as X
import Internal.Tools.Hashdict as Hashdict import Internal.Tools.Hashdict as Hashdict

View File

@ -9,8 +9,8 @@ This file combines the internal functions with the API endpoints to create a ful
import Dict import Dict
import Internal.Api.CredUpdate exposing (CredUpdate(..)) import Internal.Api.CredUpdate exposing (CredUpdate(..))
import Internal.Api.Credentials as Credentials exposing (Credentials)
import Internal.Api.Task as Api import Internal.Api.Task as Api
import Internal.Context as Context exposing (Context)
import Internal.Event as Event import Internal.Event as Event
import Internal.Room as Room import Internal.Room as Room
import Internal.Tools.Exceptions as X import Internal.Tools.Exceptions as X
@ -29,7 +29,7 @@ the right keys and tokens to get the right information.
type Vault type Vault
= Vault = Vault
{ cred : Internal.IVault { cred : Internal.IVault
, context : Context , context : Credentials
} }
@ -41,8 +41,8 @@ when the access token expires, is revoked or something else happens.
-} -}
fromAccessToken : { baseUrl : String, accessToken : String } -> Vault fromAccessToken : { baseUrl : String, accessToken : String } -> Vault
fromAccessToken { baseUrl, accessToken } = fromAccessToken { baseUrl, accessToken } =
Context.fromBaseUrl baseUrl Credentials.fromBaseUrl baseUrl
|> Context.addToken accessToken |> Credentials.addToken accessToken
|> (\context -> |> (\context ->
{ cred = Internal.init, context = context } { cred = Internal.init, context = context }
) )
@ -53,8 +53,8 @@ fromAccessToken { baseUrl, accessToken } =
-} -}
fromLoginVault : { username : String, password : String, baseUrl : String } -> Vault fromLoginVault : { username : String, password : String, baseUrl : String } -> Vault
fromLoginVault { username, password, baseUrl } = fromLoginVault { username, password, baseUrl } =
Context.fromBaseUrl baseUrl Credentials.fromBaseUrl baseUrl
|> Context.addUsernameAndPassword |> Credentials.addUsernameAndPassword
{ username = username { username = username
, password = password , password = password
} }
@ -69,7 +69,7 @@ fromLoginVault { username, password, baseUrl } =
getRoomById : String -> Vault -> Maybe Room.Room getRoomById : String -> Vault -> Maybe Room.Room
getRoomById roomId (Vault { cred, context }) = getRoomById roomId (Vault { cred, context }) =
Internal.getRoomById roomId cred Internal.getRoomById roomId cred
|> Maybe.map (Room.withContext context) |> Maybe.map (Room.withCredentials context)
{-| Insert an internal room type into the credentials. {-| Insert an internal room type into the credentials.
@ -83,7 +83,7 @@ insertInternalRoom iroom (Vault data) =
-} -}
insertRoom : Room.Room -> Vault -> Vault insertRoom : Room.Room -> Vault -> Vault
insertRoom = insertRoom =
Room.withoutContext >> insertInternalRoom Room.withoutCredentials >> insertInternalRoom
{-| Update the Vault type with new values {-| Update the Vault type with new values
@ -143,7 +143,7 @@ updateWith credUpdate ((Vault ({ cred, context } as data)) as credentials) =
case jroom.timeline of case jroom.timeline of
Just timeline -> Just timeline ->
room room
|> Room.withoutContext |> Room.withoutCredentials
|> IRoom.addEvents |> IRoom.addEvents
{ events = { events =
List.map List.map
@ -165,7 +165,7 @@ updateWith credUpdate ((Vault ({ cred, context } as data)) as credentials) =
} }
Nothing -> Nothing ->
Room.withoutContext room Room.withoutCredentials room
-- Add new room -- Add new room
Nothing -> Nothing ->
@ -181,14 +181,14 @@ updateWith credUpdate ((Vault ({ cred, context } as data)) as credentials) =
|> Vault |> Vault
UpdateAccessToken token -> UpdateAccessToken token ->
Vault { data | context = Context.addToken token context } Vault { data | context = Credentials.addToken token context }
UpdateVersions versions -> UpdateVersions versions ->
Vault { data | context = Context.addVersions versions context } Vault { data | context = Credentials.addVersions versions context }
-- TODO: Save all info -- TODO: Save all info
LoggedInWithUsernameAndPassword _ output -> LoggedInWithUsernameAndPassword _ output ->
Vault { data | context = Context.addToken output.accessToken context } Vault { data | context = Credentials.addToken output.accessToken context }
{-| Synchronize credentials {-| Synchronize credentials
@ -196,14 +196,14 @@ updateWith credUpdate ((Vault ({ cred, context } as data)) as credentials) =
sync : Vault -> Task X.Error CredUpdate sync : Vault -> Task X.Error CredUpdate
sync (Vault { cred, context }) = sync (Vault { cred, context }) =
Api.sync Api.sync
{ accessToken = Context.accessToken context { accessToken = Credentials.accessToken context
, baseUrl = Context.baseUrl context , baseUrl = Credentials.baseUrl context
, filter = Nothing , filter = Nothing
, fullState = Nothing , fullState = Nothing
, setPresence = Nothing , setPresence = Nothing
, since = Internal.getSince cred , since = Internal.getSince cred
, timeout = Just 30 , timeout = Just 30
, versions = Context.versions context , versions = Credentials.versions context
} }
@ -213,4 +213,4 @@ rooms : Vault -> List Room.Room
rooms (Vault { cred, context }) = rooms (Vault { cred, context }) =
cred cred
|> Internal.getRooms |> Internal.getRooms
|> List.map (Room.withContext context) |> List.map (Room.withCredentials context)