209 lines
5.0 KiB
Go
209 lines
5.0 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"strings"
|
|
|
|
"github.com/RichardKnop/machinery/v1/tasks"
|
|
uuid "github.com/satori/go.uuid"
|
|
"github.com/spf13/cobra"
|
|
activitypub "github.com/yukimochi/Activity-Relay/ActivityPub"
|
|
state "github.com/yukimochi/Activity-Relay/State"
|
|
)
|
|
|
|
func followCmdInit() *cobra.Command {
|
|
var follow = &cobra.Command{
|
|
Use: "follow",
|
|
Short: "Manage follow request for relay",
|
|
Long: "List all follow request and accept/reject follow requests.",
|
|
}
|
|
|
|
var followList = &cobra.Command{
|
|
Use: "list",
|
|
Short: "List follow request",
|
|
Long: "List follow request.",
|
|
RunE: listFollows,
|
|
}
|
|
follow.AddCommand(followList)
|
|
|
|
var followAccept = &cobra.Command{
|
|
Use: "accept",
|
|
Short: "Accept follow request",
|
|
Long: "Accept follow request by domain.",
|
|
Args: cobra.MinimumNArgs(1),
|
|
RunE: acceptFollow,
|
|
}
|
|
follow.AddCommand(followAccept)
|
|
|
|
var followReject = &cobra.Command{
|
|
Use: "reject",
|
|
Short: "Reject follow request",
|
|
Long: "Reject follow request by domain.",
|
|
Args: cobra.MinimumNArgs(1),
|
|
RunE: rejectFollow,
|
|
}
|
|
follow.AddCommand(followReject)
|
|
|
|
var updateActor = &cobra.Command{
|
|
Use: "update",
|
|
Short: "Update actor object",
|
|
Long: "Update actor object for whole subscribers.",
|
|
RunE: updateActor,
|
|
}
|
|
follow.AddCommand(updateActor)
|
|
|
|
return follow
|
|
}
|
|
|
|
func pushRegistorJob(inboxURL string, body []byte) {
|
|
job := &tasks.Signature{
|
|
Name: "registor",
|
|
RetryCount: 25,
|
|
Args: []tasks.Arg{
|
|
{
|
|
Name: "inboxURL",
|
|
Type: "string",
|
|
Value: inboxURL,
|
|
},
|
|
{
|
|
Name: "body",
|
|
Type: "string",
|
|
Value: string(body),
|
|
},
|
|
},
|
|
}
|
|
_, err := machineryServer.SendTask(job)
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
}
|
|
}
|
|
|
|
func createFollowRequestResponse(domain string, response string) error {
|
|
data, err := relayState.RedisClient.HGetAll("relay:pending:" + domain).Result()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
activity := activitypub.Activity{
|
|
Context: []string{"https://www.w3.org/ns/activitystreams", "https://w3id.org/security/v1"},
|
|
ID: data["activity_id"],
|
|
Actor: data["actor"],
|
|
Type: data["type"],
|
|
Object: data["object"],
|
|
}
|
|
|
|
resp := activity.GenerateResponse(hostname, response)
|
|
jsonData, err := json.Marshal(&resp)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
pushRegistorJob(data["inbox_url"], jsonData)
|
|
relayState.RedisClient.Del("relay:pending:" + domain)
|
|
if response == "Accept" {
|
|
relayState.AddSubscription(state.Subscription{
|
|
Domain: domain,
|
|
InboxURL: data["inbox_url"],
|
|
ActivityID: data["activity_id"],
|
|
ActorID: data["actor"],
|
|
})
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func createUpdateActorActivity(subscription state.Subscription) error {
|
|
activity := activitypub.Activity{
|
|
Context: []string{"https://www.w3.org/ns/activitystreams"},
|
|
ID: hostname.String() + "/activities/" + uuid.NewV4().String(),
|
|
Actor: hostname.String() + "/actor",
|
|
Type: "Update",
|
|
To: []string{"https://www.w3.org/ns/activitystreams#Public"},
|
|
Object: Actor,
|
|
}
|
|
|
|
jsonData, err := json.Marshal(&activity)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
pushRegistorJob(subscription.InboxURL, jsonData)
|
|
|
|
return nil
|
|
}
|
|
|
|
func listFollows(cmd *cobra.Command, args []string) error {
|
|
var domains []string
|
|
cmd.Println(" - Follow request :")
|
|
follows, err := relayState.RedisClient.Keys("relay:pending:*").Result()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, follow := range follows {
|
|
domains = append(domains, strings.Replace(follow, "relay:pending:", "", 1))
|
|
}
|
|
for _, domain := range domains {
|
|
cmd.Println(domain)
|
|
}
|
|
cmd.Println(fmt.Sprintf("Total : %d", len(domains)))
|
|
|
|
return nil
|
|
}
|
|
|
|
func acceptFollow(cmd *cobra.Command, args []string) error {
|
|
var err error
|
|
var domains []string
|
|
follows, err := relayState.RedisClient.Keys("relay:pending:*").Result()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, follow := range follows {
|
|
domains = append(domains, strings.Replace(follow, "relay:pending:", "", 1))
|
|
}
|
|
|
|
for _, domain := range args {
|
|
if contains(domains, domain) {
|
|
cmd.Println("Accept [" + domain + "] follow request")
|
|
createFollowRequestResponse(domain, "Accept")
|
|
} else {
|
|
cmd.Println("Invalid domain [" + domain + "] given")
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func rejectFollow(cmd *cobra.Command, args []string) error {
|
|
var err error
|
|
var domains []string
|
|
follows, err := relayState.RedisClient.Keys("relay:pending:*").Result()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, follow := range follows {
|
|
domains = append(domains, strings.Replace(follow, "relay:pending:", "", 1))
|
|
}
|
|
|
|
for _, domain := range args {
|
|
for _, request := range domains {
|
|
if domain == request {
|
|
cmd.Println("Reject [" + domain + "] follow request")
|
|
createFollowRequestResponse(domain, "Reject")
|
|
break
|
|
}
|
|
}
|
|
cmd.Println("Invalid domain [" + domain + "] given")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func updateActor(cmd *cobra.Command, args []string) error {
|
|
for _, subscription := range relayState.Subscriptions {
|
|
err := createUpdateActorActivity(subscription)
|
|
if err != nil {
|
|
cmd.Println("Failed Update Actor for " + subscription.Domain)
|
|
}
|
|
}
|
|
return nil
|
|
}
|