Cleanup
This commit is contained in:
parent
76f9e14b93
commit
5fc3b48e70
4 changed files with 64 additions and 37 deletions
19
TODO
19
TODO
|
@ -13,7 +13,7 @@
|
|||
[✔] Handle being followed
|
||||
[✔] When followed, the handler should write the new follower to file
|
||||
[✔] Make sure we send our boosts to all our followers
|
||||
[ ] Write incoming activities to disk (do we have to?)
|
||||
[x] Write incoming activities to disk (do we have to?)
|
||||
[✔] Write all the announcements (boosts) to the database to
|
||||
their correct actors
|
||||
[✔] Check if we are already following users
|
||||
|
@ -22,12 +22,13 @@
|
|||
[✔] Make OS-independent (mosty directory separators)
|
||||
[✔] Create outbox.json programmatically
|
||||
[✔] Make storage configurable (search for "storage" in project)
|
||||
[ ] Check if we're boosting only stuff from actors we follow, not whatever comes
|
||||
[✔] Check if we're boosting only stuff from actors we follow, not whatever comes
|
||||
through in our inbox
|
||||
[✔] Boost not only articles but other things too
|
||||
[✔] Sanitize input, never allow slashes or dots
|
||||
[✔] Add summary to actors.json
|
||||
[ ] Check local actor names for characters illegal for filenames and ban them
|
||||
[✔] Check local actor names for characters illegal for filenames and ban them
|
||||
(Done in pherephone, not activityserve)
|
||||
[✔] Create debug flag
|
||||
[✔] Write to following only upon accept
|
||||
(waiting to actually get an accept so that I can test this)
|
||||
|
@ -41,16 +42,16 @@
|
|||
[ ] Implement nodeinfo and statistics
|
||||
[✔] Accept even if already follows us
|
||||
[✔] Handle paging
|
||||
[ ] Test paging
|
||||
[✔] Test paging
|
||||
[✔] Handle http signatures
|
||||
[ ] Verify http signatures
|
||||
[ ] Refactor, comment and clean up
|
||||
[ ] Split to pherephone and activityServe
|
||||
[✔] Refactor, comment and clean up
|
||||
[✔] Split to pherephone and activityServe
|
||||
[ ] Decide what's to be done with actors removed from `actors.json`.
|
||||
[ ] Remove them?
|
||||
[ ] Leave them read-only?
|
||||
[ ] Leave them as is?
|
||||
[✔] Leave them as is?
|
||||
[✔] Handle followers and following uri's
|
||||
[ ] Do I care about the inbox?
|
||||
[ ] Expose configuration to apps
|
||||
[ ] Do not boost replies (configurable)
|
||||
[✔] Expose configuration to apps
|
||||
[✔] Do not boost replies (configurable)
|
79
actor.go
79
actor.go
|
@ -54,8 +54,8 @@ type ActorToSave struct {
|
|||
Followers, Following, Rejected, Requested map[string]interface{}
|
||||
}
|
||||
|
||||
// MakeActor returns a new local actor we can act
|
||||
// on behalf of
|
||||
// MakeActor creates and returns a new local actor we can act
|
||||
// on behalf of. It also creates its files on disk
|
||||
func MakeActor(name, summary, actorType string) (Actor, error) {
|
||||
followers := make(map[string]interface{})
|
||||
following := make(map[string]interface{})
|
||||
|
@ -125,7 +125,7 @@ func MakeActor(name, summary, actorType string) (Actor, error) {
|
|||
return actor, nil
|
||||
}
|
||||
|
||||
// GetOutboxIRI returns the outbox iri in net/url
|
||||
// GetOutboxIRI returns the outbox iri in net/url format
|
||||
func (a *Actor) GetOutboxIRI() *url.URL {
|
||||
iri := a.iri + "/outbox"
|
||||
nuiri, _ := url.Parse(iri)
|
||||
|
@ -133,7 +133,8 @@ func (a *Actor) GetOutboxIRI() *url.URL {
|
|||
}
|
||||
|
||||
// LoadActor searches the filesystem and creates an Actor
|
||||
// from the data in name.json
|
||||
// from the data in <name>.json
|
||||
// This does not preserve events so use with caution
|
||||
func LoadActor(name string) (Actor, error) {
|
||||
// make sure our users can't read our hard drive
|
||||
if strings.ContainsAny(name, "./ ") {
|
||||
|
@ -161,9 +162,6 @@ func LoadActor(name string) (Actor, error) {
|
|||
return Actor{}, err
|
||||
}
|
||||
|
||||
// publicKeyNewLines := strings.ReplaceAll(jsonData["PublicKey"].(string), "\\n", "\n")
|
||||
// privateKeyNewLines := strings.ReplaceAll(jsonData["PrivateKey"].(string), "\\n", "\n")
|
||||
|
||||
publicKeyDecoded, rest := pem.Decode([]byte(jsonData["PublicKey"].(string)))
|
||||
if publicKeyDecoded == nil {
|
||||
log.Info(rest)
|
||||
|
@ -245,7 +243,7 @@ func GetActor(name, summary, actorType string) (Actor, error) {
|
|||
}
|
||||
|
||||
// func LoadActorFromIRI(iri string) a Actor{
|
||||
|
||||
// TODO, this should parse the iri and load the right actor
|
||||
// }
|
||||
|
||||
// save the actor to file
|
||||
|
@ -445,6 +443,9 @@ func (a *Actor) GetFollowing(page int) (response []byte, err error) {
|
|||
return a.getPeers(page, "following")
|
||||
}
|
||||
|
||||
// signedHTTPPost performs an HTTP post on behalf of Actor with the
|
||||
// request-target, date, host and digest headers signed
|
||||
// with the actor's private key.
|
||||
func (a *Actor) signedHTTPPost(content map[string]interface{}, to string) (err error) {
|
||||
b, err := json.Marshal(content)
|
||||
if err != nil {
|
||||
|
@ -498,7 +499,7 @@ func (a *Actor) signedHTTPPost(content map[string]interface{}, to string) (err e
|
|||
return
|
||||
}
|
||||
responseData, _ := ioutil.ReadAll(resp.Body)
|
||||
fmt.Printf("POST request to %s succeeded (%d): %s \nResponse: %s \nRequest: %s \nHeaders: %s", to, resp.StatusCode, resp.Status, FormatJSON(responseData), FormatJSON(byteCopy), FormatHeaders(req.Header))
|
||||
log.Errorf("POST request to %s succeeded (%d): %s \nResponse: %s \nRequest: %s \nHeaders: %s", to, resp.StatusCode, resp.Status, FormatJSON(responseData), FormatJSON(byteCopy), FormatHeaders(req.Header))
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -556,6 +557,8 @@ func (a *Actor) NewFollower(iri string, inbox string) error {
|
|||
return a.save()
|
||||
}
|
||||
|
||||
// appendToOutbox adds a new line with the id of the activity
|
||||
// to outbox.txt
|
||||
func (a *Actor) appendToOutbox(iri string) (err error) {
|
||||
// create outbox file if it doesn't exist
|
||||
var outbox *os.File
|
||||
|
@ -574,6 +577,7 @@ func (a *Actor) appendToOutbox(iri string) (err error) {
|
|||
return nil
|
||||
}
|
||||
|
||||
// batchSend sends a batch of http posts to a list of recipients
|
||||
func (a *Actor) batchSend(activity map[string]interface{}, recipients []string) (err error) {
|
||||
for _, v := range recipients {
|
||||
err := a.signedHTTPPost(activity, v)
|
||||
|
@ -584,6 +588,7 @@ func (a *Actor) batchSend(activity map[string]interface{}, recipients []string)
|
|||
return
|
||||
}
|
||||
|
||||
// send to followers sends a batch of http posts to each one of the followers
|
||||
func (a *Actor) sendToFollowers(activity map[string]interface{}) (err error) {
|
||||
recipients := make([]string, len(a.followers))
|
||||
|
||||
|
@ -645,15 +650,34 @@ func (a *Actor) Follow(user string) (err error) {
|
|||
// was accepted when initially following that user
|
||||
// (this is read from the `actor.following` map
|
||||
func (a *Actor) Unfollow(user string) {
|
||||
// if we have a request to follow this user cancel it
|
||||
cancelRequest := false
|
||||
if _, ok := a.requested[user]; ok {
|
||||
log.Info("Cancelling follow request")
|
||||
cancelRequest = true
|
||||
// then continue to send the unfollow to the receipient
|
||||
// to inform them that the request is cancelled.
|
||||
} else if _, ok := a.following[user]; !ok {
|
||||
log.Info("We are not following this user, ignoring...")
|
||||
return
|
||||
}
|
||||
|
||||
log.Info("Unfollowing " + user)
|
||||
|
||||
var hash string
|
||||
// find the id of the original follow
|
||||
if cancelRequest {
|
||||
hash = a.requested[user].(string)
|
||||
} else {
|
||||
hash = a.following[user].(string)
|
||||
}
|
||||
|
||||
// create an undo activiy
|
||||
undo := make(map[string]interface{})
|
||||
undo["@context"] = context()
|
||||
undo["actor"] = a.iri
|
||||
|
||||
// find the id of the original follow
|
||||
hash := a.following[user].(string)
|
||||
undo["id"] = baseURL + "/item/" + hash + "/undo"
|
||||
undo["type"] = "Undo"
|
||||
|
||||
follow := make(map[string]interface{})
|
||||
|
||||
|
@ -673,22 +697,23 @@ func (a *Actor) Unfollow(user string) {
|
|||
return
|
||||
}
|
||||
|
||||
// only if we're already following them
|
||||
if _, ok := a.following[user]; ok {
|
||||
PrettyPrint(undo)
|
||||
go func() {
|
||||
err := a.signedHTTPPost(undo, remoteUser.inbox)
|
||||
if err != nil {
|
||||
log.Info("Couldn't unfollow " + user)
|
||||
log.Info(err)
|
||||
return
|
||||
}
|
||||
// if there was no error then delete the follow
|
||||
// from the list
|
||||
PrettyPrint(undo)
|
||||
go func() {
|
||||
err := a.signedHTTPPost(undo, remoteUser.inbox)
|
||||
if err != nil {
|
||||
log.Info("Couldn't unfollow " + user)
|
||||
log.Info(err)
|
||||
return
|
||||
}
|
||||
// if there was no error then delete the follow
|
||||
// from the list
|
||||
if cancelRequest {
|
||||
delete(a.requested, user)
|
||||
} else {
|
||||
delete(a.following, user)
|
||||
a.save()
|
||||
}()
|
||||
}
|
||||
}
|
||||
a.save()
|
||||
}()
|
||||
}
|
||||
|
||||
// Announce this activity to our followers
|
||||
|
|
1
http.go
1
http.go
|
@ -251,6 +251,7 @@ func Serve(actors map[string]Actor) {
|
|||
// return
|
||||
// }
|
||||
actor.following[acceptor] = hash
|
||||
PrettyPrint(activity)
|
||||
delete(actor.requested, acceptor)
|
||||
actor.save()
|
||||
case "Reject":
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## A very light ActivityPub library in go
|
||||
|
||||
This library was built to support the very little functions that [pherephone](https://github.com/writeas/pherephone) requires. It might never be feature-complete but it's a very good point to start your activityPub journey. Take a look at [activityserve-example] for a simple main file that uses **activityserve** to post a "Hello, world" message.
|
||||
This library was built to support the very little functions that [pherephone](https://github.com/writeas/pherephone) requires. It might never be feature-complete but it's a very good point to start your activityPub journey. Take a look at [activityserve-example](https://github.com/writeas/activityserve-example) for a simple main file that uses **activityserve** to post a "Hello, world" message.
|
||||
|
||||
For now it supports following and unfollowing users, accepting follows, announcing (boosting) other posts and this is pretty much it.
|
||||
|
||||
|
|
Loading…
Reference in a new issue