From 39e4ae766e167c5f44d723443319ceb853a5ec0d Mon Sep 17 00:00:00 2001 From: Xeronith Date: Fri, 14 Jul 2023 16:50:42 +0330 Subject: [PATCH] refactor(components): :zap: improve core components --- components/contracts/system_component.go | 2 +- components/contracts/system_dispatcher.go | 18 ++++++-- components/core/initializer.go | 16 ++++++- components/core/system_dispatcher.go | 52 +++++++++++++++++++---- 4 files changed, 73 insertions(+), 15 deletions(-) diff --git a/components/contracts/system_component.go b/components/contracts/system_component.go index 4a8647f..4e19892 100644 --- a/components/contracts/system_component.go +++ b/components/contracts/system_component.go @@ -26,7 +26,7 @@ type ( Atomic(handler TransactionHandler) error Schedule(spec string, callback func()) error GetSystemComponent(name string) ISystemComponent - RequestActivityStream(method, url, keyId, privateKey string, data []byte, output interface{}) error + RequestActivityStream(method, url, publicKeyId, privateKey string, input, output interface{}) error LogRemoteCall(context IContext, eventType uint32, source string, input, result interface{}, err error) // Document diff --git a/components/contracts/system_dispatcher.go b/components/contracts/system_dispatcher.go index 16f5d84..3a80b6b 100644 --- a/components/contracts/system_dispatcher.go +++ b/components/contracts/system_dispatcher.go @@ -1234,16 +1234,26 @@ type IDispatcher interface { // Join concatenates the elements of its first argument to create a single string. The separator // string is placed between elements in the resulting string. Join(elements []string, separator string) string + // MarshalJson returns the JSON representation of input and panics in case of an error. + MarshalJson(input any) string + // UnmarshalJson parses the JSON-encoded data and stores the result in the + // value pointed to by output. If output is nil or not a pointer, it panics. + UnmarshalJson(data []byte, output any) + // DecodeMapStructure takes an input structure and uses reflection to + // translate it to the output structure. output must be a pointer to a + // map or struct. It panics in case of an error. + DecodeMapStructure(input, output interface{}) IsTestEnvironment() bool IsDevelopmentEnvironment() bool IsStagingEnvironment() bool IsProductionEnvironment() bool - GetActivityStream(url string, data []byte, output interface{}) error - PostActivityStream(url string, data []byte, output interface{}) error - GetActivityStreamSigned(url, keyId, privateKey string, data []byte, output interface{}) error - PostActivityStreamSigned(url, keyId, privateKey string, data []byte, output interface{}) error + GetActorId() string + GetActivityStream(url string, input, output interface{}) error + PostActivityStream(url string, input, output interface{}) error + GetActivityStreamSigned(url string, input, output interface{}) error + PostActivityStreamSigned(url string, input, output interface{}) error UnmarshalActivityPubObjectOrLink([]byte) activitypub.ObjectOrLink UnmarshalActivityPubNote([]byte) *activitypub.Note } diff --git a/components/core/initializer.go b/components/core/initializer.go index d46d3ad..bccdefa 100644 --- a/components/core/initializer.go +++ b/components/core/initializer.go @@ -238,7 +238,19 @@ func (conductor *conductor) SignRequest(keyId, privateKey string, data []byte, r return nil } -func (conductor *conductor) RequestActivityStream(method, url, keyId, privateKey string, data []byte, output interface{}) error { +func (conductor *conductor) RequestActivityStream(method, url, publicKeyId, privateKey string, input, output interface{}) error { + var ( + data []byte + err error + ) + + if input != nil { + data, err = json.Marshal(input) + if err != nil { + return err + } + } + var reader io.Reader if data != nil { reader = bytes.NewBuffer(data) @@ -252,7 +264,7 @@ func (conductor *conductor) RequestActivityStream(method, url, keyId, privateKey req.Header.Set("Accept", "application/activity+json") if privateKey != "" { - if err := conductor.SignRequest(keyId, privateKey, data, req); err != nil { + if err := conductor.SignRequest(publicKeyId, privateKey, data, req); err != nil { return err } } diff --git a/components/core/system_dispatcher.go b/components/core/system_dispatcher.go index 25e24fc..3b60139 100644 --- a/components/core/system_dispatcher.go +++ b/components/core/system_dispatcher.go @@ -11,6 +11,7 @@ import ( "time" "github.com/go-ap/activitypub" + "github.com/mitchellh/mapstructure" . "github.com/reiver/greatape/components/contracts" "github.com/valyala/fastjson" . "github.com/xeronith/diamante/contracts/logging" @@ -318,6 +319,27 @@ func (dispatcher *dispatcher) Join(elements []string, separator string) string { return strings.Join(elements, separator) } +func (dispatcher *dispatcher) MarshalJson(input any) string { + data, err := json.Marshal(input) + if err != nil { + panic(err.Error()) + } + + return string(data) +} + +func (dispatcher *dispatcher) UnmarshalJson(data []byte, output any) { + if err := json.Unmarshal(data, output); err != nil { + panic(err.Error()) + } +} + +func (dispatcher *dispatcher) DecodeMapStructure(input, output interface{}) { + if err := mapstructure.Decode(input, output); err != nil { + panic(err.Error()) + } +} + func (dispatcher *dispatcher) IsTestEnvironment() bool { return dispatcher.conductor.IdentityManager().IsTestEnvironment() } @@ -334,20 +356,34 @@ func (dispatcher *dispatcher) IsProductionEnvironment() bool { return dispatcher.conductor.IdentityManager().IsProductionEnvironment() } -func (dispatcher *dispatcher) GetActivityStream(url string, data []byte, output interface{}) error { - return dispatcher.conductor.RequestActivityStream(http.MethodGet, url, "", "", data, output) +func (dispatcher *dispatcher) GetActorId() string { + config := dispatcher.conductor.Configuration().GetServerConfiguration() + return fmt.Sprintf("%s://%s/u/%s", config.GetProtocol(), config.GetFQDN(), dispatcher.identity.Username()) } -func (dispatcher *dispatcher) PostActivityStream(url string, data []byte, output interface{}) error { - return dispatcher.conductor.RequestActivityStream(http.MethodPost, url, "", "", data, output) +func (dispatcher *dispatcher) GetPublicKeyId(identity Identity) string { + config := dispatcher.conductor.Configuration().GetServerConfiguration() + return fmt.Sprintf("%s://%s/u/%s#main-key", config.GetProtocol(), config.GetFQDN(), identity.Username()) } -func (dispatcher *dispatcher) GetActivityStreamSigned(url, keyId, privateKey string, data []byte, output interface{}) error { - return dispatcher.conductor.RequestActivityStream(http.MethodGet, url, keyId, privateKey, data, output) +func (dispatcher *dispatcher) GetActivityStream(url string, input, output interface{}) error { + return dispatcher.conductor.RequestActivityStream(http.MethodGet, url, "", "", input, output) } -func (dispatcher *dispatcher) PostActivityStreamSigned(url, keyId, privateKey string, data []byte, output interface{}) error { - return dispatcher.conductor.RequestActivityStream(http.MethodPost, url, keyId, privateKey, data, output) +func (dispatcher *dispatcher) PostActivityStream(url string, input, output interface{}) error { + return dispatcher.conductor.RequestActivityStream(http.MethodPost, url, "", "", input, output) +} + +func (dispatcher *dispatcher) GetActivityStreamSigned(url string, input, output interface{}) error { + identity := dispatcher.identity + keyId := dispatcher.GetPublicKeyId(identity) + return dispatcher.conductor.RequestActivityStream(http.MethodGet, url, keyId, identity.PrivateKey(), input, output) +} + +func (dispatcher *dispatcher) PostActivityStreamSigned(url string, input, output interface{}) error { + identity := dispatcher.identity + keyId := dispatcher.GetPublicKeyId(identity) + return dispatcher.conductor.RequestActivityStream(http.MethodPost, url, keyId, identity.PrivateKey(), input, output) } func (dispatcher *dispatcher) UnmarshalActivityPubObjectOrLink(data []byte) activitypub.ObjectOrLink {