Unverified Commit 12749ba5 authored by zauberstuhl's avatar zauberstuhl Committed by GitHub

Merge pull request #5 from ganggo/refactor_dispatcher_receiver_jobs

Refactor dispatcher receiver jobs
parents 5972d854 4a77bf4e
...@@ -18,6 +18,7 @@ package federation ...@@ -18,6 +18,7 @@ package federation
// //
const ( const (
TIME_FORMAT = "2006-01-02T15:04:05Z"
XMLNS = "https://joindiaspora.com/protocol" XMLNS = "https://joindiaspora.com/protocol"
XMLNS_ME = "http://salmon-protocol.org/ns/magic-env" XMLNS_ME = "http://salmon-protocol.org/ns/magic-env"
APPLICATION_XML = "application/xml" APPLICATION_XML = "application/xml"
...@@ -36,8 +37,4 @@ const ( ...@@ -36,8 +37,4 @@ const (
// webfinger // webfinger
WebFingerOstatus = "http://ostatus.org/schema/1.0/subscribe" WebFingerOstatus = "http://ostatus.org/schema/1.0/subscribe"
WebFingerHcard = "http://microformats.org/profile/hcard" WebFingerHcard = "http://microformats.org/profile/hcard"
// signature types
AuthorSignatureType = iota
ParentAuthorSignatureType
) )
...@@ -78,6 +78,8 @@ func AuthorSignature(data interface{}, order string, privKey []byte) (string, er ...@@ -78,6 +78,8 @@ func AuthorSignature(data interface{}, order string, privKey []byte) (string, er
if tag == o { if tag == o {
value := v.Field(i).Interface() value := v.Field(i).Interface()
switch v := value.(type) { switch v := value.(type) {
case Time:
text += v.Format(TIME_FORMAT) + ";"
case string: case string:
text += v + ";" text += v + ";"
case bool: case bool:
......
...@@ -20,6 +20,7 @@ package federation ...@@ -20,6 +20,7 @@ package federation
import ( import (
"errors" "errors"
"encoding/xml" "encoding/xml"
"time"
) )
type Message struct { type Message struct {
...@@ -49,6 +50,26 @@ type Entity struct { ...@@ -49,6 +50,26 @@ type Entity struct {
Data interface{} `xml:"-"` Data interface{} `xml:"-"`
} }
type Time struct {
time.Time
}
func (t *Time) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
e.EncodeElement(t.Format(TIME_FORMAT), start)
return nil
}
func (t *Time) UnmarshalXML(decoder *xml.Decoder, start xml.StartElement) error {
var value string
decoder.DecodeElement(&value, &start)
parse, err := time.Parse(TIME_FORMAT, value)
if err != nil {
return err
}
*t = Time{parse}
return nil
}
func (e *Entity) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { func (e *Entity) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
// NOTE since the encoder ignores the interface type // NOTE since the encoder ignores the interface type
// (see https://golang.org/src/encoding/xml/read.go#L377) // (see https://golang.org/src/encoding/xml/read.go#L377)
...@@ -69,14 +90,19 @@ func (e *Entity) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { ...@@ -69,14 +90,19 @@ func (e *Entity) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
(*e).Type = local (*e).Type = local
(*e).Data = content (*e).Data = content
case StatusMessage: case StatusMessage:
fallthrough
case Reshare:
content := EntityStatusMessage{} content := EntityStatusMessage{}
if err := d.DecodeElement(&content, &start); err != nil { if err := d.DecodeElement(&content, &start); err != nil {
return err return err
} }
(*e).Type = local (*e).Type = local
(*e).Data = content (*e).Data = content
case Reshare:
content := EntityReshare{}
if err := d.DecodeElement(&content, &start); err != nil {
return err
}
(*e).Type = local
(*e).Data = content
case Comment: case Comment:
content := EntityComment{} content := EntityComment{}
if err := d.DecodeElement(&content, &start); err != nil { if err := d.DecodeElement(&content, &start); err != nil {
......
...@@ -28,7 +28,7 @@ func TestEntitiesUnmarshalXML(t *testing.T) { ...@@ -28,7 +28,7 @@ func TestEntitiesUnmarshalXML(t *testing.T) {
var retractionRaw = []byte(`<retraction></retraction>`) var retractionRaw = []byte(`<retraction></retraction>`)
var profileRaw = []byte(`<profile></profile>`) var profileRaw = []byte(`<profile></profile>`)
var statusMessageRaw = []byte(`<status_message></status_message>`) var statusMessageRaw = []byte(`<status_message></status_message>`)
//var reshareRaw = []byte(`<reshare></reshare>`) var reshareRaw = []byte(`<reshare></reshare>`)
var commentRaw = []byte(`<comment></comment>`) var commentRaw = []byte(`<comment></comment>`)
var likeRaw = []byte(`<like></like>`) var likeRaw = []byte(`<like></like>`)
var contactRaw = []byte(`<contact></contact>`) var contactRaw = []byte(`<contact></contact>`)
...@@ -41,6 +41,10 @@ func TestEntitiesUnmarshalXML(t *testing.T) { ...@@ -41,6 +41,10 @@ func TestEntitiesUnmarshalXML(t *testing.T) {
if data, ok := entity.Data.(EntityRetraction); !ok { if data, ok := entity.Data.(EntityRetraction); !ok {
t.Errorf("Expected to be 'like', got %v", data) t.Errorf("Expected to be 'like', got %v", data)
} }
err = xml.Unmarshal(retractionRaw[:len(retractionRaw)-1], &entity)
if err == nil {
t.Errorf("Expected an error, got nil")
}
err = xml.Unmarshal(profileRaw, &entity) err = xml.Unmarshal(profileRaw, &entity)
if err != nil { if err != nil {
...@@ -49,6 +53,10 @@ func TestEntitiesUnmarshalXML(t *testing.T) { ...@@ -49,6 +53,10 @@ func TestEntitiesUnmarshalXML(t *testing.T) {
if data, ok := entity.Data.(EntityProfile); !ok { if data, ok := entity.Data.(EntityProfile); !ok {
t.Errorf("Expected to be 'profile', got %v", data) t.Errorf("Expected to be 'profile', got %v", data)
} }
err = xml.Unmarshal(profileRaw[:len(profileRaw)-1], &entity)
if err == nil {
t.Errorf("Expected an error, got nil")
}
err = xml.Unmarshal(statusMessageRaw, &entity) err = xml.Unmarshal(statusMessageRaw, &entity)
if err != nil { if err != nil {
...@@ -57,14 +65,22 @@ func TestEntitiesUnmarshalXML(t *testing.T) { ...@@ -57,14 +65,22 @@ func TestEntitiesUnmarshalXML(t *testing.T) {
if data, ok := entity.Data.(EntityStatusMessage); !ok { if data, ok := entity.Data.(EntityStatusMessage); !ok {
t.Errorf("Expected to be 'status_message', got %v", data) t.Errorf("Expected to be 'status_message', got %v", data)
} }
err = xml.Unmarshal(statusMessageRaw[:len(statusMessageRaw)-1], &entity)
if err == nil {
t.Errorf("Expected an error, got nil")
}
//err = xml.Unmarshal(reshareRaw, &entity) err = xml.Unmarshal(reshareRaw, &entity)
//if err != nil { if err != nil {
// t.Errorf("Some error occured while parsing: %v", err) t.Errorf("Some error occured while parsing: %v", err)
//} }
//if data, ok := entity.Data.(EntityStatusMessage); !ok { if data, ok := entity.Data.(EntityReshare); !ok {
// t.Errorf("Expected to be 'reshare', got %v", data) t.Errorf("Expected to be 'reshare', got %v", data)
//} }
err = xml.Unmarshal(reshareRaw[:len(reshareRaw)-1], &entity)
if err == nil {
t.Errorf("Expected an error, got nil")
}
err = xml.Unmarshal(commentRaw, &entity) err = xml.Unmarshal(commentRaw, &entity)
if err != nil { if err != nil {
...@@ -73,6 +89,10 @@ func TestEntitiesUnmarshalXML(t *testing.T) { ...@@ -73,6 +89,10 @@ func TestEntitiesUnmarshalXML(t *testing.T) {
if data, ok := entity.Data.(EntityComment); !ok { if data, ok := entity.Data.(EntityComment); !ok {
t.Errorf("Expected to be 'comment', got %v", data) t.Errorf("Expected to be 'comment', got %v", data)
} }
err = xml.Unmarshal(commentRaw[:len(commentRaw)-1], &entity)
if err == nil {
t.Errorf("Expected an error, got nil")
}
err = xml.Unmarshal(likeRaw, &entity) err = xml.Unmarshal(likeRaw, &entity)
if err != nil { if err != nil {
...@@ -81,6 +101,10 @@ func TestEntitiesUnmarshalXML(t *testing.T) { ...@@ -81,6 +101,10 @@ func TestEntitiesUnmarshalXML(t *testing.T) {
if data, ok := entity.Data.(EntityLike); !ok { if data, ok := entity.Data.(EntityLike); !ok {
t.Errorf("Expected to be 'like', got %v", data) t.Errorf("Expected to be 'like', got %v", data)
} }
err = xml.Unmarshal(likeRaw[:len(likeRaw)-1], &entity)
if err == nil {
t.Errorf("Expected an error, got nil")
}
err = xml.Unmarshal(contactRaw, &entity) err = xml.Unmarshal(contactRaw, &entity)
if err != nil { if err != nil {
...@@ -89,9 +113,46 @@ func TestEntitiesUnmarshalXML(t *testing.T) { ...@@ -89,9 +113,46 @@ func TestEntitiesUnmarshalXML(t *testing.T) {
if data, ok := entity.Data.(EntityContact); !ok { if data, ok := entity.Data.(EntityContact); !ok {
t.Errorf("Expected to be 'contact', got %v", data) t.Errorf("Expected to be 'contact', got %v", data)
} }
err = xml.Unmarshal(contactRaw[:len(contactRaw)-1], &entity)
if err == nil {
t.Errorf("Expected an error, got nil")
}
err = xml.Unmarshal(notSupportedRaw, &entity) err = xml.Unmarshal(notSupportedRaw, &entity)
if err == nil { if err == nil {
t.Errorf("Expected an error, got nil") t.Errorf("Expected an error, got nil")
} }
} }
func TestEntitiesTimeMarshalAndUnmarshal(t *testing.T) {
// federation time format
// 2006-01-02T15:04:05Z
var time = "2018-01-19T01:32:23Z"
var rawXml = "<time><CreatedAt>"+time+"</CreatedAt></time>";
var origTime = struct {
XMLName xml.Name `xml:"time"`
CreatedAt Time
}{}
err := xml.Unmarshal([]byte(rawXml), &origTime)
if err != nil {
t.Errorf("Some error occured while parsing: %v", err)
}
if origTime.CreatedAt.Time.Format(TIME_FORMAT) != time {
t.Errorf("Expected to be '%s', got '%s'",
origTime.CreatedAt.Time.Format(TIME_FORMAT))
}
result, err := xml.Marshal(origTime)
if err != nil {
t.Errorf("Some error occured while parsing: %v", err)
}
if string(result) != rawXml {
t.Errorf("Expected to be '%s', got '%s'", result, rawXml)
}
err = xml.Unmarshal([]byte("<time><CreatedAt></CreatedAt></time>"), &origTime)
if err == nil {
t.Errorf("Expected an error, got nil")
}
}
...@@ -17,38 +17,28 @@ package federation ...@@ -17,38 +17,28 @@ package federation
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
import ( import "encoding/xml"
"encoding/xml"
"errors"
)
type EntityComment struct { type EntityComment struct {
XMLName xml.Name `xml:"comment"` XMLName xml.Name `xml:"comment"`
Author string `xml:"author"` Author string `xml:"author"`
CreatedAt string `xml:"created_at"` CreatedAt Time `xml:"created_at"`
Guid string `xml:"guid"` Guid string `xml:"guid"`
ParentGuid string `xml:"parent_guid"` ParentGuid string `xml:"parent_guid"`
Text string `xml:"text"` Text string `xml:"text"`
AuthorSignature string `xml:"author_signature"` AuthorSignature string `xml:"author_signature"`
ParentAuthorSignature string `xml:"parent_author_signature"`
} }
func (e *EntityComment) SignatureOrder() string { func (e *EntityComment) SignatureOrder() string {
return "author created_at guid parent_guid text" return "author created_at guid parent_guid text"
} }
func (e *EntityComment) AppendSignature(privKey []byte, order string, typ int) error { func (e *EntityComment) AppendSignature(privKey []byte, order string) error {
signature, err := AuthorSignature(*e, order, privKey) signature, err := AuthorSignature(*e, order, privKey)
if err != nil { if err != nil {
return err return err
} }
(*e).AuthorSignature = signature
if AuthorSignatureType == typ {
(*e).AuthorSignature = signature
} else if ParentAuthorSignatureType == typ {
(*e).ParentAuthorSignature = signature
} else {
return errors.New("Unsupported author signature type!")
}
return nil return nil
} }
...@@ -17,7 +17,10 @@ package federation ...@@ -17,7 +17,10 @@ package federation
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
import "testing" import (
"testing"
"time"
)
func TestCommentSignatureOrder(t *testing.T) { func TestCommentSignatureOrder(t *testing.T) {
var comment EntityComment var comment EntityComment
...@@ -31,8 +34,8 @@ func TestCommentSignatureOrder(t *testing.T) { ...@@ -31,8 +34,8 @@ func TestCommentSignatureOrder(t *testing.T) {
func TestCommentAppendSignature(t *testing.T) { func TestCommentAppendSignature(t *testing.T) {
comment := EntityComment{ comment := EntityComment{
Author: "author@localhost", Author: "author@localhost",
CreatedAt: "01.01.1970",
Guid: "1234", Guid: "1234",
CreatedAt: Time{time.Now()},
ParentGuid: "4321", ParentGuid: "4321",
Text: "hello world", Text: "hello world",
} }
...@@ -41,12 +44,7 @@ func TestCommentAppendSignature(t *testing.T) { ...@@ -41,12 +44,7 @@ func TestCommentAppendSignature(t *testing.T) {
t.Errorf("Expected to be empty, got %s", comment.AuthorSignature) t.Errorf("Expected to be empty, got %s", comment.AuthorSignature)
} }
if comment.ParentAuthorSignature != "" { err := comment.AppendSignature(TEST_PRIV_KEY, comment.SignatureOrder())
t.Errorf("Expected to be empty, got %s", comment.AuthorSignature)
}
err := comment.AppendSignature(TEST_PRIV_KEY,
comment.SignatureOrder(), AuthorSignatureType)
if err != nil { if err != nil {
t.Errorf("Some error occured while parsing: %v", err) t.Errorf("Some error occured while parsing: %v", err)
} }
...@@ -55,13 +53,8 @@ func TestCommentAppendSignature(t *testing.T) { ...@@ -55,13 +53,8 @@ func TestCommentAppendSignature(t *testing.T) {
t.Errorf("Expected signature, was empty") t.Errorf("Expected signature, was empty")
} }
err = comment.AppendSignature(TEST_PRIV_KEY, err = comment.AppendSignature(TEST_PRIV_KEY, comment.SignatureOrder())
comment.SignatureOrder(), ParentAuthorSignatureType)
if err != nil { if err != nil {
t.Errorf("Some error occured while parsing: %v", err) t.Errorf("Some error occured while parsing: %v", err)
} }
if comment.ParentAuthorSignature == "" {
t.Errorf("Expected signature, was empty")
}
} }
...@@ -17,38 +17,28 @@ package federation ...@@ -17,38 +17,28 @@ package federation
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
import ( import "encoding/xml"
"encoding/xml"
"errors"
)
type EntityLike struct { type EntityLike struct {
XMLName xml.Name `xml:"like"` XMLName xml.Name `xml:"like"`
Positive bool `xml:"positive"` Positive bool `xml:"positive"`
Guid string `xml:"guid"` Guid string `xml:"guid"`
ParentGuid string `xml:"parent_guid"` ParentGuid string `xml:"parent_guid"`
TargetType string `xml:"parent_type"` ParentType string `xml:"parent_type"`
Author string `xml:"author"` Author string `xml:"author"`
AuthorSignature string `xml:"author_signature"` AuthorSignature string `xml:"author_signature"`
ParentAuthorSignature string `xml:"parent_author_signature"`
} }
func (e *EntityLike) SignatureOrder() string { func (e *EntityLike) SignatureOrder() string {
return "positive guid parent_guid target_type author" return "positive guid parent_guid parent_type author"
} }
func (e *EntityLike) AppendSignature(privKey []byte, order string, typ int) error { func (e *EntityLike) AppendSignature(privKey []byte, order string) error {
signature, err := AuthorSignature(*e, order, privKey) signature, err := AuthorSignature(*e, order, privKey)
if err != nil { if err != nil {
return err return err
} }
(*e).AuthorSignature = signature
if AuthorSignatureType == typ {
(*e).AuthorSignature = signature
} else if ParentAuthorSignatureType == typ {
(*e).ParentAuthorSignature = signature
} else {
return errors.New("Unsupported author signature type!")
}
return nil return nil
} }
...@@ -23,7 +23,7 @@ import "testing" ...@@ -23,7 +23,7 @@ import "testing"
func TestLikeSignatureOrder(t *testing.T) { func TestLikeSignatureOrder(t *testing.T) {
var like EntityLike var like EntityLike
expected := "positive guid parent_guid target_type author" expected := "positive guid parent_guid parent_type author"
if expected != like.SignatureOrder() { if expected != like.SignatureOrder() {
t.Errorf("Expected to be %s, got %s", expected, like.SignatureOrder()) t.Errorf("Expected to be %s, got %s", expected, like.SignatureOrder())
} }
...@@ -34,7 +34,7 @@ func TestLikeAppendSignature(t *testing.T) { ...@@ -34,7 +34,7 @@ func TestLikeAppendSignature(t *testing.T) {
Positive: true, Positive: true,
Guid: "1234", Guid: "1234",
ParentGuid: "4321", ParentGuid: "4321",
TargetType: "Post", ParentType: "Post",
Author: "author@localhost", Author: "author@localhost",
} }
...@@ -42,12 +42,7 @@ func TestLikeAppendSignature(t *testing.T) { ...@@ -42,12 +42,7 @@ func TestLikeAppendSignature(t *testing.T) {
t.Errorf("Expected to be empty, got %s", like.AuthorSignature) t.Errorf("Expected to be empty, got %s", like.AuthorSignature)
} }
if like.ParentAuthorSignature != "" { err := like.AppendSignature(TEST_PRIV_KEY, like.SignatureOrder())
t.Errorf("Expected to be empty, got %s", like.AuthorSignature)
}
err := like.AppendSignature(TEST_PRIV_KEY,
like.SignatureOrder(), AuthorSignatureType)
if err != nil { if err != nil {
t.Errorf("Some error occured while parsing: %v", err) t.Errorf("Some error occured while parsing: %v", err)
} }
...@@ -56,13 +51,8 @@ func TestLikeAppendSignature(t *testing.T) { ...@@ -56,13 +51,8 @@ func TestLikeAppendSignature(t *testing.T) {
t.Errorf("Expected signature, was empty") t.Errorf("Expected signature, was empty")
} }
err = like.AppendSignature(TEST_PRIV_KEY, err = like.AppendSignature(TEST_PRIV_KEY, like.SignatureOrder())
like.SignatureOrder(), ParentAuthorSignatureType)
if err != nil { if err != nil {
t.Errorf("Some error occured while parsing: %v", err) t.Errorf("Some error occured while parsing: %v", err)
} }
if like.ParentAuthorSignature == "" {
t.Errorf("Expected signature, was empty")
}
} }
...@@ -17,32 +17,36 @@ package federation ...@@ -17,32 +17,36 @@ package federation
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
// //
import ( import "encoding/xml"
"time"
"encoding/xml"
)
type EntityStatusMessage struct { type EntityStatusMessage struct {
XMLName xml.Name `xml:"status_message"` XMLName xml.Name `xml:"status_message"`
Author string `xml:"author"` Author string `xml:"author"`
Guid string `xml:"guid"` Guid string `xml:"guid"`
CreatedAt time.Time `xml:"created_at"` CreatedAt Time `xml:"created_at"`
ProviderName string `xml:"provider_display_name"` ProviderName string `xml:"provider_display_name"`
Text string `xml:"text,omitempty"` Text string `xml:"text,omitempty"`
Photo *EntityPhotos `xml:"photo,omitempty"` Photo *EntityPhotos `xml:"photo,omitempty"`
Location *EntityLocation `xml:"location,omitempty"` Location *EntityLocation `xml:"location,omitempty"`
Poll *EntityPoll `xml:"poll,omitempty"` Poll *EntityPoll `xml:"poll,omitempty"`
Public bool `xml:"public"` Public bool `xml:"public"`
// on reshare Event *EntityEvent `xml:"event,omitempty"`
RootHandle string `xml:"root_diaspora_id,omitempty"` }
RootGuid string `xml:"root_guid,omitempty"`
type EntityReshare struct {
XMLName xml.Name `xml:"reshare"`
Author string `xml:"author"`
Guid string `xml:"guid"`
CreatedAt Time `xml:"created_at"`
RootAuthor string `xml:"root_author"`
RootGuid string `xml:"root_guid"`
} }
type EntityPhoto struct { type EntityPhoto struct {
Guid string `xml:"guid"` Guid string `xml:"guid"`
Author string `xml:"author"` Author string `xml:"author"`
Public bool `xml:"public"` Public bool `xml:"public"`
CreatedAt time.Time `xml:"created_at"` CreatedAt Time `xml:"created_at"`
RemotePhotoPath string `xml:"remote_photo_path"` RemotePhotoPath string `xml:"remote_photo_path"`
RemotePhotoName string `xml:"remote_photo_name"` RemotePhotoName string `xml:"remote_photo_name"`
Text string `xml:"text"` Text string `xml:"text"`
...@@ -70,6 +74,14 @@ type EntityPollAnswer struct { ...@@ -70,6 +74,14 @@ type EntityPollAnswer struct {
Answer string `xml:"answer"` Answer string `xml:"answer"`
} }
type PollParticipation struct { type EntityEvent struct {
PollAnswerGuid string `xml:"poll_answer_guid"` Author string `xml:"author"`
Guid string `xml:"guid"`
Summary string `xml:"summary"`
Start Time `xml:"start"`
End Time `xml:"end"`
AllDay bool `xml:"all_day"`
Timezone string `xml:"timezone"`
Description string `xml:"description"`
Location *EntityLocation `xml:"location,omitempty"`
} }
...@@ -27,9 +27,9 @@ import ( ...@@ -27,9 +27,9 @@ import (
) )
type Test struct { type Test struct {
XMLName xml.Name `xml:"AB";json:"-"` XMLName xml.Name `xml:"AB" json:"-"`
A string `xml:"A";json:"A"` A string `xml:"A" json:"A"`
B string `xml:"B";json:"B"` B string `xml:"B" json:"B"`
} }
func TestPushToPrivate(t *testing.T) { func TestPushToPrivate(t *testing.T) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment