diff --git a/flow.go b/flow.go index 7befef5..0507e65 100644 --- a/flow.go +++ b/flow.go @@ -1,6 +1,10 @@ package main -import "errors" +import ( + "errors" + + "github.com/status-im/status-keycard-go/signal" +) func NewFlow(storageDir string) (*keycardFlow, error) { flow := &keycardFlow{ @@ -12,20 +16,20 @@ func NewFlow(storageDir string) (*keycardFlow, error) { } func (f *keycardFlow) Start(flowType FlowType, params map[string]string) error { - if f.state != IDLE { + if f.state != Idle { return errors.New("already running") } f.flowType = flowType f.params = params - f.state = RUNNING + f.state = Running go f.runFlow() return nil } func (f *keycardFlow) Resume(params map[string]string) error { - if f.state != PAUSED { + if f.state != Paused { return errors.New("only paused flows can be resumed") } @@ -33,7 +37,7 @@ func (f *keycardFlow) Resume(params map[string]string) error { f.params[k] = v } - f.state = RESUMING + f.state = Resuming f.wakeUp <- struct{}{} return nil @@ -42,12 +46,12 @@ func (f *keycardFlow) Resume(params map[string]string) error { func (f *keycardFlow) Cancel() error { prevState := f.state - if prevState != IDLE { + if prevState != Idle { return errors.New("cannot cancel idle flow") } - f.state = CANCELLING - if prevState == PAUSED { + f.state = Cancelling + if prevState == Paused { f.wakeUp <- struct{}{} } @@ -55,5 +59,79 @@ func (f *keycardFlow) Cancel() error { } func (f *keycardFlow) runFlow() { + repeat := true + var result map[string]string + for repeat { + switch f.flowType { + case GetStatus: + repeat, result = f.switchFlow() + } + } + + if f.state != Cancelling { + signal.SendEvent(FlowResult, result) + } + + f.state = Idle +} + +func (f *keycardFlow) switchFlow() (bool, map[string]string) { + kc := f.connect() + defer f.closeKeycard(kc) + + if kc == nil { + return false, map[string]string{"Error": "Couldn't connect to the card"} + } + + switch f.flowType { + case GetStatus: + return f.getStatusFlow(kc) + default: + return false, map[string]string{"Error": "Unknown flow"} + } +} + +func (f *keycardFlow) pause(action string, status map[string]string) { + signal.SendEvent(action, status) + f.state = Paused +} + +func (f *keycardFlow) pauseAndWait(action string, status map[string]string) { + f.pause(action, status) + <-f.wakeUp +} + +func (f *keycardFlow) closeKeycard(kc *keycardContext) { + if kc != nil { + kc.stop() + } +} + +func (f *keycardFlow) connect() *keycardContext { + kc, err := startKeycardContext() + + if err != nil { + return nil + } + + f.pause(InsertCard, map[string]string{}) + select { + case <-f.wakeUp: + if f.state != Cancelling { + panic("Resuming is not expected during connection") + } + return nil + case <-kc.connected: + if kc.runErr != nil { + return nil + } + + return kc + } +} + +func (f *keycardFlow) getStatusFlow(kc *keycardContext) (bool, map[string]string) { + + return false, nil } diff --git a/flow_types.go b/flow_types.go index a2f4c1e..111a587 100644 --- a/flow_types.go +++ b/flow_types.go @@ -1,31 +1,37 @@ package main type FlowType int -type RunState int +type runState int const ( - GET_STATUS FlowType = iota - RECOVER_ACCOUNT - LOAD_ACCOUNT - LOGIN - SIGN - CHANGE_CREDENTIALS - UNPAIR - UNPAIR_OTHERS - DELETE_ACCOUNT_AND_UNPAIR + GetStatus FlowType = iota + RecoverAccount + LoadAccount + Login + Sign + ChangeCredentials + UnpairThis + UnpairOthers + DeleteAccountAndUnpair ) const ( - IDLE RunState = iota - RUNNING - PAUSED - RESUMING - CANCELLING + Idle runState = iota + Running + Paused + Resuming + Cancelling +) + +const ( + FlowResult = "keycard.flow-result" + InsertCard = "keycard.action.insert-card" + CardInserted = "keycard.action.card-inserted" ) type keycardFlow struct { flowType FlowType - state RunState + state runState wakeUp chan (struct{}) storage string params map[string]string diff --git a/signal/events_keycard.go b/signal/events_keycard.go index c4dc70a..67bc068 100644 --- a/signal/events_keycard.go +++ b/signal/events_keycard.go @@ -7,3 +7,7 @@ const ( func SendKeycardConnected(event interface{}) { send(EventKeycardConnected, event) } + +func SendEvent(typ string, event interface{}) { + send(typ, event) +}