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 (..)
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.Invite.Main as Invite
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.Versions.Main as Versions
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.LoginValues exposing (AccessToken(..))
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 =
{ eventId : String
, reason : Maybe String

View File

@ -1,11 +1,8 @@
module Internal.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.
module Internal.Api.Credentials exposing (..)
{-| 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

View File

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

View File

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