Mono-binarify for control.

This commit is contained in:
Naoki Kosaka 2021-06-19 10:48:43 +09:00
parent 2ef9029bf0
commit 9297540a1d
17 changed files with 315 additions and 230 deletions

View File

@ -13,7 +13,7 @@ jobs:
- name: Execute test and upload coverage
run: |
go version
go test -coverprofile=coverage.txt -covermode=atomic -p 1 ./api ./deliver ./cli ./models
go test -coverprofile=coverage.txt -covermode=atomic -p 1 ./api ./deliver ./control ./models
bash <(curl -s https://codecov.io/bash)
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@ -5,8 +5,7 @@ COPY . /Activity-Relay
RUN mkdir -p /rootfs/usr/bin && \
apk add -U --no-cache git && \
go build -o /rootfs/usr/bin/relay -ldflags "-X main.version=$(git describe --tags HEAD)" . && \
go build -o /rootfs/usr/bin/ar-cli -ldflags "-X main.version=$(git describe --tags HEAD)" ./cli
go build -o /rootfs/usr/bin/relay -ldflags "-X main.version=$(git describe --tags HEAD)" .
FROM alpine

View File

@ -1,21 +0,0 @@
package keyloader
import (
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"io/ioutil"
)
func ReadPrivateKeyRSAfromPath(path string) (*rsa.PrivateKey, error) {
file, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
decoded, _ := pem.Decode(file)
priv, err := x509.ParsePKCS1PrivateKey(decoded.Bytes)
if err != nil {
return nil, err
}
return priv, nil
}

View File

@ -1,87 +0,0 @@
package main
import (
"crypto/rsa"
"fmt"
"net/url"
"github.com/RichardKnop/machinery/v1"
"github.com/RichardKnop/machinery/v1/config"
"github.com/go-redis/redis"
"github.com/spf13/cobra"
"github.com/spf13/viper"
keyloader "github.com/yukimochi/Activity-Relay/KeyLoader"
"github.com/yukimochi/Activity-Relay/models"
)
var (
version string
// Actor : Relay's Actor
Actor models.Actor
hostname *url.URL
hostkey *rsa.PrivateKey
relayState models.RelayState
machineryServer *machinery.Server
)
func initConfig() {
viper.SetConfigName("config")
viper.AddConfigPath(".")
err := viper.ReadInConfig()
if err != nil {
fmt.Println("Config file is not exists. Use environment variables.")
viper.BindEnv("actor_pem")
viper.BindEnv("redis_url")
viper.BindEnv("relay_bind")
viper.BindEnv("relay_domain")
viper.BindEnv("relay_servicename")
} else {
Actor.Summary = viper.GetString("relay_summary")
Actor.Icon = &models.Image{URL: viper.GetString("relay_icon")}
Actor.Image = &models.Image{URL: viper.GetString("relay_image")}
}
Actor.Name = viper.GetString("relay_servicename")
hostname, err = url.Parse("https://" + viper.GetString("relay_domain"))
if err != nil {
panic(err)
}
hostkey, err := keyloader.ReadPrivateKeyRSAfromPath(viper.GetString("actor_pem"))
if err != nil {
panic(err)
}
redisOption, err := redis.ParseURL(viper.GetString("redis_url"))
if err != nil {
panic(err)
}
redisClient := redis.NewClient(redisOption)
relayState = models.NewState(redisClient, true)
var machineryConfig = &config.Config{
Broker: viper.GetString("redis_url"),
DefaultQueue: "relay",
ResultBackend: viper.GetString("redis_url"),
ResultsExpireIn: 5,
}
machineryServer, err = machinery.NewServer(machineryConfig)
if err != nil {
panic(err)
}
Actor.GenerateSelfKey(hostname, &hostkey.PublicKey)
}
func buildNewCmd() *cobra.Command {
var app = &cobra.Command{}
app.AddCommand(domainCmdInit())
app.AddCommand(followCmdInit())
app.AddCommand(configCmdInit())
return app
}
func main() {
initConfig()
var app = buildNewCmd()
app.Execute()
}

View File

@ -1,20 +0,0 @@
package main
import (
"os"
"testing"
"github.com/spf13/viper"
"github.com/yukimochi/Activity-Relay/models"
)
func TestMain(m *testing.M) {
viper.Set("actor_pem", "../misc/testKey.pem")
viper.Set("relay_domain", "relay.yukimochi.example.org")
initConfig()
relayState = models.NewState(relayState.RedisClient, false)
relayState.RedisClient.FlushAll().Result()
code := m.Run()
os.Exit(code)
}

View File

@ -1,4 +1,4 @@
package main
package control
import (
"encoding/json"
@ -27,7 +27,9 @@ func configCmdInit() *cobra.Command {
Use: "list",
Short: "List all relay configration",
Long: "List all relay configration.",
Run: listConfig,
Run: func(cmd *cobra.Command, args []string) {
initProxy(listConfig, cmd, args)
},
}
config.AddCommand(configList)
@ -35,7 +37,9 @@ func configCmdInit() *cobra.Command {
Use: "export",
Short: "Export all relay information",
Long: "Export all relay information by JSON format.",
Run: exportConfig,
Run: func(cmd *cobra.Command, args []string) {
initProxy(exportConfig, cmd, args)
},
}
config.AddCommand(configExport)
@ -43,7 +47,9 @@ func configCmdInit() *cobra.Command {
Use: "import [flags]",
Short: "Import all relay information",
Long: "Import all relay information from JSON file.",
Run: importConfig,
Run: func(cmd *cobra.Command, args []string) {
initProxy(importConfig, cmd, args)
},
}
configImport.Flags().String("json", "", "JSON file-path")
configImport.MarkFlagRequired("json")
@ -60,7 +66,9 @@ func configCmdInit() *cobra.Command {
- create-as-announce
Enable announce activity instead of relay create activity (not recommend)`,
Args: cobra.MinimumNArgs(1),
RunE: configEnable,
RunE: func(cmd *cobra.Command, args []string) error {
return initProxyE(configEnable, cmd, args)
},
}
configEnable.Flags().BoolP("disable", "d", false, "Disable configration instead of Enable")
config.AddCommand(configEnable)

View File

@ -1,4 +1,4 @@
package main
package control
import (
"bytes"
@ -11,16 +11,16 @@ import (
func TestServiceBlock(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := configCmdInit()
app.SetArgs([]string{"config", "enable", "service-block"})
app.SetArgs([]string{"enable", "service-block"})
app.Execute()
relayState.Load()
if !relayState.RelayConfig.BlockService {
t.Fatalf("Not Enabled Blocking feature for service-type actor")
}
app.SetArgs([]string{"config", "enable", "-d", "service-block"})
app.SetArgs([]string{"enable", "-d", "service-block"})
app.Execute()
relayState.Load()
if relayState.RelayConfig.BlockService {
@ -31,16 +31,16 @@ func TestServiceBlock(t *testing.T) {
func TestManuallyAccept(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := configCmdInit()
app.SetArgs([]string{"config", "enable", "manually-accept"})
app.SetArgs([]string{"enable", "manually-accept"})
app.Execute()
relayState.Load()
if !relayState.RelayConfig.ManuallyAccept {
t.Fatalf("Not Enabled Manually accept follow-request feature")
}
app.SetArgs([]string{"config", "enable", "-d", "manually-accept"})
app.SetArgs([]string{"enable", "-d", "manually-accept"})
app.Execute()
relayState.Load()
if relayState.RelayConfig.ManuallyAccept {
@ -51,16 +51,16 @@ func TestManuallyAccept(t *testing.T) {
func TestCreateAsAnnounce(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := configCmdInit()
app.SetArgs([]string{"config", "enable", "create-as-announce"})
app.SetArgs([]string{"enable", "create-as-announce"})
app.Execute()
relayState.Load()
if !relayState.RelayConfig.CreateAsAnnounce {
t.Fatalf("Enable announce activity instead of relay create activity")
}
app.SetArgs([]string{"config", "enable", "-d", "create-as-announce"})
app.SetArgs([]string{"enable", "-d", "create-as-announce"})
app.Execute()
relayState.Load()
if relayState.RelayConfig.CreateAsAnnounce {
@ -71,11 +71,11 @@ func TestCreateAsAnnounce(t *testing.T) {
func TestInvalidConfig(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := configCmdInit()
buffer := new(bytes.Buffer)
app.SetOutput(buffer)
app.SetArgs([]string{"config", "enable", "hoge"})
app.SetArgs([]string{"enable", "hoge"})
app.Execute()
output := buffer.String()
@ -87,11 +87,11 @@ func TestInvalidConfig(t *testing.T) {
func TestListConfig(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := configCmdInit()
buffer := new(bytes.Buffer)
app.SetOutput(buffer)
app.SetArgs([]string{"config", "list"})
app.SetArgs([]string{"list"})
app.Execute()
output := buffer.String()
@ -116,11 +116,11 @@ func TestListConfig(t *testing.T) {
func TestExportConfig(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := configCmdInit()
buffer := new(bytes.Buffer)
app.SetOutput(buffer)
app.SetArgs([]string{"config", "export"})
app.SetArgs([]string{"export"})
app.Execute()
file, err := os.Open("../misc/blankConfig.json")
@ -137,16 +137,16 @@ func TestExportConfig(t *testing.T) {
func TestImportConfig(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := configCmdInit()
app.SetArgs([]string{"config", "import", "--json", "../misc/exampleConfig.json"})
app.SetArgs([]string{"import", "--json", "../misc/exampleConfig.json"})
app.Execute()
relayState.Load()
buffer := new(bytes.Buffer)
app.SetOutput(buffer)
app.SetArgs([]string{"config", "export"})
app.SetArgs([]string{"export"})
app.Execute()
file, err := os.Open("../misc/exampleConfig.json")

90
control/control.go Normal file
View File

@ -0,0 +1,90 @@
package control
import (
"fmt"
"os"
"github.com/RichardKnop/machinery/v1"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/yukimochi/Activity-Relay/models"
)
var (
globalConfig *models.RelayConfig
initProxy = initializeProxy
initProxyE = initializeProxyE
// Actor : Relay's Actor
Actor models.Actor
relayState models.RelayState
machineryServer *machinery.Server
)
func BuildCommand(command *cobra.Command) {
command.AddCommand(configCmdInit())
command.AddCommand(domainCmdInit())
command.AddCommand(followCmdInit())
}
func initializeProxy(function func(cmd *cobra.Command, args []string), cmd *cobra.Command, args []string) {
initConfig(cmd)
function(cmd, args)
}
func initializeProxyE(function func(cmd *cobra.Command, args []string) error, cmd *cobra.Command, args []string) error {
initConfig(cmd)
return function(cmd, args)
}
func initConfig(cmd *cobra.Command) error {
var err error
configPath := cmd.Flag("config").Value.String()
file, err := os.Open(configPath)
defer file.Close()
if err == nil {
viper.SetConfigType("yaml")
viper.ReadConfig(file)
} else {
fmt.Fprintln(os.Stderr, "Config file not exist. Use environment variables.")
viper.BindEnv("ACTOR_PEM")
viper.BindEnv("REDIS_URL")
viper.BindEnv("RELAY_BIND")
viper.BindEnv("RELAY_DOMAIN")
viper.BindEnv("RELAY_SERVICENAME")
viper.BindEnv("JOB_CONCURRENCY")
viper.BindEnv("RELAY_SUMMARY")
viper.BindEnv("RELAY_ICON")
viper.BindEnv("RELAY_IMAGE")
}
globalConfig, err = models.NewRelayConfig()
if err != nil {
fmt.Fprintln(os.Stderr, err.Error())
os.Exit(1)
}
return nil
}
func initialize(globalconfig *models.RelayConfig) error {
var err error
redisClient := globalConfig.RedisClient()
relayState = models.NewState(redisClient, true)
relayState.ListenNotify(nil)
machineryServer, err = models.NewMachineryServer(globalConfig)
if err != nil {
return err
}
Actor = models.NewActivityPubActorFromSelfKey(globalConfig)
return nil
}

52
control/control_test.go Normal file
View File

@ -0,0 +1,52 @@
package control
import (
"fmt"
"os"
"testing"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/yukimochi/Activity-Relay/models"
)
func TestMain(m *testing.M) {
var err error
testConfigPath := "../misc/config.yml"
file, _ := os.Open(testConfigPath)
defer file.Close()
viper.SetConfigType("yaml")
viper.ReadConfig(file)
viper.Set("ACTOR_PEM", "../misc/testKey.pem")
viper.BindEnv("REDIS_URL")
globalConfig, err = models.NewRelayConfig()
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
err = initialize(globalConfig)
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
relayState = models.NewState(globalConfig.RedisClient(), false)
relayState.RedisClient.FlushAll().Result()
initProxy = emptyProxy
initProxyE = emptyProxyE
code := m.Run()
os.Exit(code)
}
func emptyProxy(function func(cmd *cobra.Command, args []string), cmd *cobra.Command, args []string) {
function(cmd, args)
}
func emptyProxyE(function func(cmd *cobra.Command, args []string) error, cmd *cobra.Command, args []string) error {
return function(cmd, args)
}

View File

@ -1,4 +1,4 @@
package main
package control
import (
"encoding/json"
@ -19,7 +19,9 @@ func domainCmdInit() *cobra.Command {
Use: "list [flags]",
Short: "List domain",
Long: "List domain which filtered given type.",
RunE: listDomains,
RunE: func(cmd *cobra.Command, args []string) error {
return initProxyE(listDomains, cmd, args)
},
}
domainList.Flags().StringP("type", "t", "subscriber", "domain type [subscriber,limited,blocked]")
domain.AddCommand(domainList)
@ -29,7 +31,9 @@ func domainCmdInit() *cobra.Command {
Short: "Set or unset domain as limited or blocked",
Long: "Set or unset domain as limited or blocked.",
Args: cobra.MinimumNArgs(1),
RunE: setDomainType,
RunE: func(cmd *cobra.Command, args []string) error {
return initProxyE(setDomainType, cmd, args)
},
}
domainSet.Flags().StringP("type", "t", "", "Apply domain type [limited,blocked]")
domainSet.MarkFlagRequired("type")
@ -40,7 +44,9 @@ func domainCmdInit() *cobra.Command {
Use: "unfollow [flags]",
Short: "Send Unfollow request for given domains",
Long: "Send unfollow request for given domains.",
RunE: unfollowDomains,
RunE: func(cmd *cobra.Command, args []string) error {
return initProxyE(unfollowDomains, cmd, args)
},
}
domain.AddCommand(domainUnfollow)
@ -56,7 +62,7 @@ func createUnfollowRequestResponse(subscription models.Subscription) error {
Object: "https://www.w3.org/ns/activitystreams#Public",
}
resp := activity.GenerateResponse(hostname, "Reject")
resp := activity.GenerateResponse(globalConfig.ServerHostname(), "Reject")
jsonData, _ := json.Marshal(&resp)
pushRegistorJob(subscription.InboxURL, jsonData)

View File

@ -1,4 +1,4 @@
package main
package control
import (
"bytes"
@ -9,15 +9,16 @@ import (
func TestListDomainSubscriber(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app.SetArgs([]string{"config", "import", "--json", "../misc/exampleConfig.json"})
app := configCmdInit()
app.SetArgs([]string{"import", "--json", "../misc/exampleConfig.json"})
app.Execute()
relayState.Load()
buffer := new(bytes.Buffer)
app.SetOutput(buffer)
app.SetArgs([]string{"domain", "list"})
app = domainCmdInit()
app.SetOutput(buffer)
app.SetArgs([]string{"list"})
app.Execute()
output := buffer.String()
@ -33,16 +34,17 @@ Total : 1
func TestListDomainLimited(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := configCmdInit()
app.SetArgs([]string{"config", "import", "--json", "../misc/exampleConfig.json"})
app.SetArgs([]string{"import", "--json", "../misc/exampleConfig.json"})
app.Execute()
relayState.Load()
buffer := new(bytes.Buffer)
app.SetOutput(buffer)
app.SetArgs([]string{"domain", "list", "-t", "limited"})
app = domainCmdInit()
app.SetOutput(buffer)
app.SetArgs([]string{"list", "-t", "limited"})
app.Execute()
output := buffer.String()
@ -58,16 +60,17 @@ Total : 1
func TestListDomainBlocked(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := configCmdInit()
app.SetArgs([]string{"config", "import", "--json", "../misc/exampleConfig.json"})
app.SetArgs([]string{"import", "--json", "../misc/exampleConfig.json"})
app.Execute()
relayState.Load()
buffer := new(bytes.Buffer)
app.SetOutput(buffer)
app.SetArgs([]string{"domain", "list", "-t", "blocked"})
app = domainCmdInit()
app.SetOutput(buffer)
app.SetArgs([]string{"list", "-t", "blocked"})
app.Execute()
output := buffer.String()
@ -83,9 +86,9 @@ Total : 1
func TestSetDomainBlocked(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := domainCmdInit()
app.SetArgs([]string{"domain", "set", "-t", "blocked", "testdomain.example.jp"})
app.SetArgs([]string{"set", "-t", "blocked", "testdomain.example.jp"})
app.Execute()
relayState.Load()
@ -104,9 +107,9 @@ func TestSetDomainBlocked(t *testing.T) {
func TestSetDomainLimited(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := domainCmdInit()
app.SetArgs([]string{"domain", "set", "-t", "limited", "testdomain.example.jp"})
app.SetArgs([]string{"set", "-t", "limited", "testdomain.example.jp"})
app.Execute()
relayState.Load()
@ -125,12 +128,13 @@ func TestSetDomainLimited(t *testing.T) {
func TestUnsetDomainBlocked(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := configCmdInit()
app.SetArgs([]string{"config", "import", "--json", "../misc/exampleConfig.json"})
app.SetArgs([]string{"import", "--json", "../misc/exampleConfig.json"})
app.Execute()
app.SetArgs([]string{"domain", "set", "-t", "blocked", "-u", "blockedDomain.example.jp"})
app = domainCmdInit()
app.SetArgs([]string{"set", "-t", "blocked", "-u", "blockedDomain.example.jp"})
app.Execute()
relayState.Load()
@ -149,12 +153,13 @@ func TestUnsetDomainBlocked(t *testing.T) {
func TestUnsetDomainLimited(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := configCmdInit()
app.SetArgs([]string{"config", "import", "--json", "../misc/exampleConfig.json"})
app.SetArgs([]string{"import", "--json", "../misc/exampleConfig.json"})
app.Execute()
app.SetArgs([]string{"domain", "set", "-t", "limited", "-u", "limitedDomain.example.jp"})
app = domainCmdInit()
app.SetArgs([]string{"set", "-t", "limited", "-u", "limitedDomain.example.jp"})
app.Execute()
relayState.Load()
@ -173,16 +178,17 @@ func TestUnsetDomainLimited(t *testing.T) {
func TestSetDomainInvalid(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := configCmdInit()
app.SetArgs([]string{"config", "import", "--json", "../misc/exampleConfig.json"})
app.SetArgs([]string{"import", "--json", "../misc/exampleConfig.json"})
app.Execute()
relayState.Load()
buffer := new(bytes.Buffer)
app.SetOutput(buffer)
app.SetArgs([]string{"domain", "set", "-t", "hoge", "hoge.example.jp"})
app = domainCmdInit()
app.SetOutput(buffer)
app.SetArgs([]string{"set", "-t", "hoge", "hoge.example.jp"})
app.Execute()
output := buffer.String()
@ -194,12 +200,13 @@ func TestSetDomainInvalid(t *testing.T) {
func TestUnfollowDomain(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := configCmdInit()
app.SetArgs([]string{"config", "import", "--json", "../misc/exampleConfig.json"})
app.SetArgs([]string{"import", "--json", "../misc/exampleConfig.json"})
app.Execute()
app.SetArgs([]string{"domain", "unfollow", "subscription.example.jp"})
app = domainCmdInit()
app.SetArgs([]string{"unfollow", "subscription.example.jp"})
app.Execute()
relayState.Load()
@ -218,16 +225,17 @@ func TestUnfollowDomain(t *testing.T) {
func TestInvalidUnfollowDomain(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := configCmdInit()
app.SetArgs([]string{"config", "import", "--json", "../misc/exampleConfig.json"})
app.SetArgs([]string{"import", "--json", "../misc/exampleConfig.json"})
app.Execute()
relayState.Load()
buffer := new(bytes.Buffer)
app.SetOutput(buffer)
app.SetArgs([]string{"domain", "unfollow", "unknown.tld"})
app = domainCmdInit()
app.SetOutput(buffer)
app.SetArgs([]string{"unfollow", "unknown.tld"})
app.Execute()
output := buffer.String()

View File

@ -1,4 +1,4 @@
package main
package control
import (
"encoding/json"
@ -23,7 +23,9 @@ func followCmdInit() *cobra.Command {
Use: "list",
Short: "List follow request",
Long: "List follow request.",
RunE: listFollows,
RunE: func(cmd *cobra.Command, args []string) error {
return initProxyE(listFollows, cmd, args)
},
}
follow.AddCommand(followList)
@ -32,7 +34,9 @@ func followCmdInit() *cobra.Command {
Short: "Accept follow request",
Long: "Accept follow request by domain.",
Args: cobra.MinimumNArgs(1),
RunE: acceptFollow,
RunE: func(cmd *cobra.Command, args []string) error {
return initProxyE(acceptFollow, cmd, args)
},
}
follow.AddCommand(followAccept)
@ -41,7 +45,9 @@ func followCmdInit() *cobra.Command {
Short: "Reject follow request",
Long: "Reject follow request by domain.",
Args: cobra.MinimumNArgs(1),
RunE: rejectFollow,
RunE: func(cmd *cobra.Command, args []string) error {
return initProxyE(rejectFollow, cmd, args)
},
}
follow.AddCommand(followReject)
@ -49,7 +55,9 @@ func followCmdInit() *cobra.Command {
Use: "update",
Short: "Update actor object",
Long: "Update actor object for whole subscribers.",
RunE: updateActor,
RunE: func(cmd *cobra.Command, args []string) error {
return initProxyE(updateActor, cmd, args)
},
}
follow.AddCommand(updateActor)
@ -92,7 +100,7 @@ func createFollowRequestResponse(domain string, response string) error {
Object: data["object"],
}
resp := activity.GenerateResponse(hostname, response)
resp := activity.GenerateResponse(globalConfig.ServerHostname(), response)
jsonData, err := json.Marshal(&resp)
if err != nil {
return err
@ -114,8 +122,8 @@ func createFollowRequestResponse(domain string, response string) error {
func createUpdateActorActivity(subscription models.Subscription) error {
activity := models.Activity{
Context: []string{"https://www.w3.org/ns/activitystreams"},
ID: hostname.String() + "/activities/" + uuid.NewV4().String(),
Actor: hostname.String() + "/actor",
ID: globalConfig.ServerHostname().String() + "/activities/" + uuid.NewV4().String(),
Actor: globalConfig.ServerHostname().String() + "/actor",
Type: "Update",
To: []string{"https://www.w3.org/ns/activitystreams#Public"},
Object: Actor,

View File

@ -1,4 +1,4 @@
package main
package control
import (
"bytes"
@ -9,7 +9,7 @@ import (
func TestListFollows(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := followCmdInit()
buffer := new(bytes.Buffer)
app.SetOutput(buffer)
@ -19,10 +19,10 @@ func TestListFollows(t *testing.T) {
"activity_id": "https://example.com/UUID",
"type": "Follow",
"actor": "https://example.com/user/example",
"object": "https://" + hostname.Host + "/actor",
"object": "https://" + globalConfig.ServerHostname().Host + "/actor",
})
app.SetArgs([]string{"follow", "list"})
app.SetArgs([]string{"list"})
app.Execute()
output := buffer.String()
@ -38,17 +38,17 @@ Total : 1
func TestAcceptFollow(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := followCmdInit()
relayState.RedisClient.HMSet("relay:pending:example.com", map[string]interface{}{
"inbox_url": "https://example.com/inbox",
"activity_id": "https://example.com/UUID",
"type": "Follow",
"actor": "https://example.com/user/example",
"object": "https://" + hostname.Host + "/actor",
"object": "https://" + globalConfig.ServerHostname().Host + "/actor",
})
app.SetArgs([]string{"follow", "accept", "example.com"})
app.SetArgs([]string{"accept", "example.com"})
app.Execute()
valid, _ := relayState.RedisClient.Exists("relay:pending:example.com").Result()
@ -65,17 +65,17 @@ func TestAcceptFollow(t *testing.T) {
func TestRejectFollow(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := followCmdInit()
relayState.RedisClient.HMSet("relay:pending:example.com", map[string]interface{}{
"inbox_url": "https://example.com/inbox",
"activity_id": "https://example.com/UUID",
"type": "Follow",
"actor": "https://example.com/user/example",
"object": "https://" + hostname.Host + "/actor",
"object": "https://" + globalConfig.ServerHostname().Host + "/actor",
})
app.SetArgs([]string{"follow", "reject", "example.com"})
app.SetArgs([]string{"reject", "example.com"})
app.Execute()
valid, _ := relayState.RedisClient.Exists("relay:pending:example.com").Result()
@ -92,12 +92,12 @@ func TestRejectFollow(t *testing.T) {
func TestInvalidFollow(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := followCmdInit()
buffer := new(bytes.Buffer)
app.SetOutput(buffer)
app.SetArgs([]string{"follow", "accept", "unknown.tld"})
app.SetArgs([]string{"accept", "unknown.tld"})
app.Execute()
output := buffer.String()
@ -109,12 +109,12 @@ func TestInvalidFollow(t *testing.T) {
func TestInvalidRejectFollow(t *testing.T) {
relayState.RedisClient.FlushAll().Result()
app := buildNewCmd()
app := followCmdInit()
buffer := new(bytes.Buffer)
app.SetOutput(buffer)
app.SetArgs([]string{"follow", "reject", "unknown.tld"})
app.SetArgs([]string{"reject", "unknown.tld"})
app.Execute()
output := buffer.String()
@ -124,11 +124,13 @@ func TestInvalidRejectFollow(t *testing.T) {
}
func TestCreateUpdateActorActivity(t *testing.T) {
app := buildNewCmd()
app := configCmdInit()
app.SetArgs([]string{"config", "import", "--json", "../misc/exampleConfig.json"})
app.SetArgs([]string{"import", "--json", "../misc/exampleConfig.json"})
app.Execute()
app.SetArgs([]string{"follow", "update"})
app = followCmdInit()
app.SetArgs([]string{"update"})
app.Execute()
}

View File

@ -1,4 +1,4 @@
package main
package control
import "github.com/yukimochi/Activity-Relay/models"

View File

@ -1,4 +1,4 @@
package main
package control
import "testing"

17
main.go
View File

@ -7,6 +7,8 @@ API Server
./Activity-Relay -c <Path of config file> server
Job Worker
./Activity-Relay -c <Path of config file> worker
CLI Management Utility
./Activity-Relay -c <Path of config file> control
Config
@ -44,6 +46,7 @@ import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/yukimochi/Activity-Relay/api"
"github.com/yukimochi/Activity-Relay/control"
"github.com/yukimochi/Activity-Relay/deliver"
"github.com/yukimochi/Activity-Relay/models"
)
@ -67,7 +70,7 @@ func buildCommand() *cobra.Command {
Short: "Activity-Relay API Server",
Long: "Activity-Relay API Server is providing WebFinger API, ActivityPub inbox",
RunE: func(cmd *cobra.Command, args []string) error {
initConfig(cmd, args)
initConfig(cmd)
fmt.Println(globalConfig.DumpWelcomeMessage("API Server", version))
err := api.Entrypoint(globalConfig, version)
if err != nil {
@ -83,7 +86,7 @@ func buildCommand() *cobra.Command {
Short: "Activity-Relay Job Worker",
Long: "Activity-Relay Job Worker is providing ActivityPub Activity deliverer",
RunE: func(cmd *cobra.Command, args []string) error {
initConfig(cmd, args)
initConfig(cmd)
fmt.Println(globalConfig.DumpWelcomeMessage("Job Worker", version))
err := deliver.Entrypoint(globalConfig, version)
if err != nil {
@ -94,17 +97,25 @@ func buildCommand() *cobra.Command {
},
}
var command = &cobra.Command{
Use: "control",
Short: "Activity-Relay CLI",
Long: "Activity-Relay CLI Management Utility",
}
control.BuildCommand(command)
var app = &cobra.Command{
Short: "YUKIMOCHI Activity-Relay",
Long: "YUKIMOCHI Activity-Relay - ActivityPub Relay Server",
}
app.AddCommand(server)
app.AddCommand(worker)
app.AddCommand(command)
return app
}
func initConfig(cmd *cobra.Command, args []string) {
func initConfig(cmd *cobra.Command) {
configPath := cmd.Flag("config").Value.String()
file, err := os.Open(configPath)
defer file.Close()

View File

@ -20,13 +20,29 @@
- [Redis](https://github.com/antirez/redis)
## Installation Manual
## Run
See [GitHub wiki](https://github.com/yukimochi/Activity-Relay/wiki)
### API Server
## Configration
```bash
relay -c <Path of config file> server
```
### `config.yml`
### Job Worker
```bash
relay -c <Path of config file> worker
```
### CLI Management Utility
```bash
relay -c <Path of config file> control
```
## Config
### YAML Format
```yaml config.yml
ACTOR_PEM: /actor.pem
@ -42,7 +58,7 @@ JOB_CONCURRENCY: 50
# RELAY_IMAGE: https://
```
### `Environment Variable`
### Environment Variable
This is **Optional** : When `config.yml` not exists, use environment variable.
@ -57,4 +73,17 @@ JOB_CONCURRENCY: 50
- RELAY_IMAGE
## License
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fyukimochi%2FActivity-Relay.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fyukimochi%2FActivity-Relay?ref=badge_large)
[![FOSSA Status](https://app.fossa.io/api/projects/git%2Bgithub.com%2Fyukimochi%2FActivity-Relay.svg?type=large)](https://app.fossa.io/projects/git%2Bgithub.com%2Fyukimochi%2FActivity-Relay?ref=badge_large)
## Project Sponsors
Thank you for your support.
### Monthly Donation
**[My Doner List](https://relay.toot.yukimochi.jp#patreon-list)**
#### Donation Platform
- [Patreon](https://www.patreon.com/yukimochi)
- [pixiv fanbox](https://yukimochi.fanbox.cc)
- [fantia](https://fantia.jp/fanclubs/11264)