diff --git a/fsm/cmd/test/test.go b/fsm/cmd/test/test.go index 42fa7ba..4e17a0f 100644 --- a/fsm/cmd/test/test.go +++ b/fsm/cmd/test/test.go @@ -1,6 +1,8 @@ package main import ( + "github.com/depools/dc4bc/fsm/fsm" + "github.com/depools/dc4bc/fsm/types/responses" "log" "github.com/depools/dc4bc/fsm/state_machines" @@ -28,8 +30,44 @@ func main() { }, }, ) - log.Println("Response", resp) log.Println("Err", err) log.Println("Dump", string(dump)) + processResponse(resp) + +} + +func processResponse(resp *fsm.Response) { + switch resp.State { + // Await proposals + case fsm.State("validate_proposal"): + data, ok := resp.Data.(responses.ProposalParticipantInvitationsResponse) + if !ok { + log.Printf("undefined response type for state \"%s\"\n", resp.State) + return + } + sendInvitations(data) + + case fsm.State("validation_canceled_by_participant"): + updateDashboardWithCanceled("Participant") + case fsm.State("validation_canceled_by_timeout"): + updateDashboardWithCanceled("Timeout") + default: + log.Printf("undefined response type for state \"%s\"\n", resp.State) + } +} + +func sendInvitations(invitations responses.ProposalParticipantInvitationsResponse) { + for _, invitation := range invitations { + log.Printf( + "Dear %s, please encrypt value \"%s\" with your key, fingerprint: %s\n", + invitation.Title, + invitation.EncryptedInvitation, + invitation.PubKeyFingerprint, + ) + } +} + +func updateDashboardWithCanceled(msg string) { + log.Printf("Breaking news! Proposal canceled with reason: %s\n", msg) } diff --git a/fsm/fsm/fsm.go b/fsm/fsm/fsm.go index bf0ddda..78f0479 100644 --- a/fsm/fsm/fsm.go +++ b/fsm/fsm/fsm.go @@ -246,6 +246,9 @@ func (f *FSM) Do(event Event, args ...interface{}) (resp *Response, err error) { } err = f.setState(event) + if err == nil { + resp.State = f.currentState + } return } diff --git a/fsm/fsm/fsm_machines_data_test.go b/fsm/fsm/fsm_machines_data_test.go deleted file mode 100644 index 5aa2dba..0000000 --- a/fsm/fsm/fsm_machines_data_test.go +++ /dev/null @@ -1,67 +0,0 @@ -package fsm - -type testMachineFSM struct { - *FSM -} - -const ( - FSM1Name = "fsm1" - // Init process from global idle state - FSM1StateInit = StateGlobalIdle - FSM2StateInit = StateGlobalIdle - // Set up data - FSM1StateStage1 = State("state_fsm1_stage1") - // Process data - FSM1StateStage2 = State("state_fsm1_stage2") - // Cancelled with internal event - FSM1StateCanceledByInternal = State("state_fsm1_canceled") - // Cancelled with external event - FSM1StateCanceled2 = State("state_fsm1_canceled2") - // Out endpoint to switch - FSM1StateOutToFSM2 = State("state_fsm1_out_to_fsm2") - FSM1StateOutToFSM3 = State("state_fsm1_out_to_fsm3") - - // Events - EventFSM1Init = Event("event_fsm1_init") - EventFSM1Cancel = Event("event_fsm1_cancel") - EventFSM1Process = Event("event_fsm1_process") - - // Internal events - EventFSM1Internal = Event("event_internal_fsm1") - EventFSM1CancelByInternal = Event("event_internal_fsm1_cancel") - EventFSM1InternalOut2 = Event("event_internal_fsm1_out") -) - -var ( - testing1Events = []EventDesc{ - // Init - {Name: EventFSM1Init, SrcState: []State{FSM2StateInit}, DstState: FSM1StateStage1}, - {Name: EventFSM1Internal, SrcState: []State{FSM1StateStage1}, DstState: FSM1StateStage2, IsInternal: true}, - - // Cancellation events - {Name: EventFSM1CancelByInternal, SrcState: []State{FSM1StateStage2}, DstState: FSM1StateCanceledByInternal, IsInternal: true}, - {Name: EventFSM1Cancel, SrcState: []State{FSM1StateStage2}, DstState: FSM1StateCanceled2}, - - // Out - {Name: EventFSM1Process, SrcState: []State{FSM1StateStage2}, DstState: FSM1StateOutToFSM2}, - {Name: EventFSM1InternalOut2, SrcState: []State{FSM1StateStage2}, DstState: FSM1StateOutToFSM3, IsInternal: true}, - } - - testing1Callbacks = Callbacks{ - EventFSM1Init: actionSetUpData, - EventFSM1InternalOut2: actionEmitOut2, - EventFSM1Process: actionProcessData, - } -) - -func actionSetUpData(event Event, args ...interface{}) (response interface{}, err error) { - return -} - -func actionProcessData(event Event, args ...interface{}) (response interface{}, err error) { - return -} - -func actionEmitOut2(event Event, args ...interface{}) (response interface{}, err error) { - return -} diff --git a/fsm/fsm/fsm_machines_test.go b/fsm/fsm/fsm_machines_test.go index 55b0ebd..281ce23 100644 --- a/fsm/fsm/fsm_machines_test.go +++ b/fsm/fsm/fsm_machines_test.go @@ -4,14 +4,68 @@ import ( "testing" ) -var testingFSM *FSM +const ( + testName = "fsm_test" + // Init process from global idle state + stateInit = StateGlobalIdle + // Set up data + stateStage1 = State("state_stage1") + // Process data + stateStage2 = State("state_stage2") + // Cancelled with internal event + stateCanceledByInternal = State("state_canceled") + // Cancelled with external event + stateCanceled2 = State("state_canceled2") + // Out endpoint to switch + stateOutToFSM2 = State("state_out_to_fsm2") + + // Events + eventInit = Event("event_init") + eventCancel = Event("event_cancel") + eventProcess = Event("event_process") + + // Internal events + eventInternal = Event("event_internal") + eventCancelByInternal = Event("event_internal_cancel") + eventInternalOut2 = Event("event_internal_out") +) + +var ( + testingFSM *FSM + + testingEvents = []EventDesc{ + // Init + {Name: eventInit, SrcState: []State{stateInit}, DstState: stateStage1}, + {Name: eventInternal, SrcState: []State{stateStage1}, DstState: stateStage2, IsInternal: true}, + + // Cancellation events + {Name: eventCancelByInternal, SrcState: []State{stateStage2}, DstState: stateCanceledByInternal, IsInternal: true}, + {Name: eventCancel, SrcState: []State{stateStage2}, DstState: stateCanceled2}, + + // Out + {Name: eventProcess, SrcState: []State{stateStage2}, DstState: stateOutToFSM2}, + {Name: eventInternalOut2, SrcState: []State{stateStage2}, DstState: stateOutToFSM2, IsInternal: true}, + } + + testingCallbacks = Callbacks{ + eventInit: func(event Event, args ...interface{}) (interface{}, error) { + return nil, nil + }, + eventInternalOut2: func(event Event, args ...interface{}) (interface{}, error) { + return nil, nil + }, + eventProcess: func(event Event, args ...interface{}) (interface{}, error) { + return nil, nil + }, + } +) func init() { testingFSM = MustNewFSM( - FSM1Name, - FSM1StateInit, - testing1Events, - testing1Callbacks, + testName, + stateInit, + testingEvents, + testingCallbacks, ) } @@ -212,22 +266,22 @@ func TestMustNewFSM_State_Final_Not_Found_Panic(t *testing.T) { } func TestFSM_Name(t *testing.T) { - if testingFSM.Name() != FSM1Name { - t.Errorf("expected machine name \"%s\"", FSM1Name) + if testingFSM.Name() != testName { + t.Errorf("expected machine name \"%s\"", testName) } } func TestFSM_EntryEvent(t *testing.T) { - if testingFSM.InitialState() != FSM1StateInit { - t.Errorf("expected initial state \"%s\"", FSM1StateInit) + if testingFSM.InitialState() != stateInit { + t.Errorf("expected initial state \"%s\"", stateInit) } } func TestFSM_EventsList(t *testing.T) { eventsList := []Event{ - EventFSM1Init, - EventFSM1Cancel, - EventFSM1Process, + eventInit, + eventCancel, + eventProcess, } if !compareEventsArr(testingFSM.EventsList(), eventsList) { @@ -238,9 +292,9 @@ func TestFSM_EventsList(t *testing.T) { func TestFSM_StatesList(t *testing.T) { statesList := []State{ - FSM1StateInit, - FSM1StateStage1, - FSM1StateStage2, + stateInit, + stateStage1, + stateStage2, } if !compareStatesArr(testingFSM.StatesSourcesList(), statesList) { diff --git a/fsm/state_machines/signature_proposal_fsm/actions.go b/fsm/state_machines/signature_proposal_fsm/actions.go index 190a49c..5e2d504 100644 --- a/fsm/state_machines/signature_proposal_fsm/actions.go +++ b/fsm/state_machines/signature_proposal_fsm/actions.go @@ -72,13 +72,27 @@ func (s *SignatureProposalFSM) actionInitProposal(event fsm.Event, args ...inter } } - /*s.state = &fsm_pool.FSMachine{ - Id: signingId, - State: stateAwaitProposalConfirmation, + // Make response + + responseData := make(responses.ProposalParticipantInvitationsResponse, 0) + + for participantId, proposal := range payload.ProposalPayload { + encryptedInvitationSecret, err := encryptWithPubKey(proposal.PublicKey, proposal.InvitationSecret) + if err != nil { + return nil, errors.New("cannot encryptWithPubKey") + } + responseEntry := &responses.ProposalParticipantInvitationEntryResponse{ + Title: proposal.Title, + PubKeyFingerprint: participantId, + EncryptedInvitation: encryptedInvitationSecret, + } + responseData = append(responseData, responseEntry) } - s.state.Payload.ProposalPayload = &privateParticipantsList*/ + + // Change state + return internal.MachineCombinedResponse{ - Response: responses.ProposalParticipantInvitationsResponse{}, + Response: responseData, Payload: &payload, }, nil } diff --git a/fsm/state_machines/signature_proposal_fsm/helpers.go b/fsm/state_machines/signature_proposal_fsm/helpers.go index 4954b81..e50f4cd 100644 --- a/fsm/state_machines/signature_proposal_fsm/helpers.go +++ b/fsm/state_machines/signature_proposal_fsm/helpers.go @@ -57,3 +57,7 @@ func generateRandomString(s int) (string, error) { b, err := generateRandomBytes(s) return base64.URLEncoding.EncodeToString(b), err } + +func encryptWithPubKey(key []byte, value string) (string, error) { + return value, nil +}