commit eb911e2224a00bdc15be137f0418fc11906d0689 Author: Martin/Geno Date: Fri May 31 10:07:40 2019 +0200 Initial commit diff --git a/.ci/check-gofmt b/.ci/check-gofmt new file mode 100755 index 0000000..4a1c0b2 --- /dev/null +++ b/.ci/check-gofmt @@ -0,0 +1,8 @@ +#!/bin/bash + +result="$(gofmt -s -l . | grep -v '^vendor/' )" +if [ -n "$result" ]; then + echo "Go code is not formatted, run 'gofmt -s -w .'" >&2 + echo "$result" + exit 1 +fi diff --git a/.ci/check-testfiles b/.ci/check-testfiles new file mode 100755 index 0000000..132ff73 --- /dev/null +++ b/.ci/check-testfiles @@ -0,0 +1,25 @@ +#!/usr/bin/env python +# checks if every desired package has test files + +import os +import re +import sys + +source_re = re.compile(".*\.go") +test_re = re.compile(".*_test\.go") +missing = False + +for root, dirs, files in os.walk("."): + # ignore some paths + if root == "." or root.startswith("./vendor") or root.startswith("./."): + continue + + # source files but not test files? + if len(filter(source_re.match, files)) > 0 and len(filter(test_re.match, files)) == 0: + print("no test files for {}".format(root)) + missing = True + +if missing: + sys.exit(1) +else: + print("every package has test files") diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..a71c6c8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +thrempp.db +config.toml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..b6bd91b --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,33 @@ +image: golang:latest +stages: + - build + - test + +before_script: + - mkdir -p /go/src/dev.sum7.eu/$CI_PROJECT_NAMESPACE/ + - cp -R $CI_PROJECT_DIR /go/src/dev.sum7.eu/$CI_PROJECT_NAMESPACE + - cd /go/src/dev.sum7.eu/$CI_PROJECT_PATH + - go get -v dev.sum7.eu/$CI_PROJECT_PATH + +build-my-project: + stage: build + script: + - mkdir $CI_PROJECT_DIR/bin/ + - cp /go/bin/$CI_PROJECT_NAME $CI_PROJECT_DIR/bin/$CI_PROJECT_NAME + artifacts: + paths: + - bin/thrempp + - config_example.toml + +test-my-project: + stage: test + script: + - ./.ci/check-gofmt + - ./.ci/check-testfiles + - go test $(go list ./... | grep -v /vendor/) -v -coverprofile .testCoverage.txt + - go tool cover -func=.testCoverage.txt + +test-race-my-project: + stage: test + script: + - go test -race ./... diff --git a/README.md b/README.md new file mode 100644 index 0000000..5bd3cab --- /dev/null +++ b/README.md @@ -0,0 +1,7 @@ +# Threempp [![pipeline status](https://dev.sum7.eu/genofire/thrempp/badges/master/pipeline.svg)](https://dev.sum7.eu/genofire/thrempp/pipelines) [![coverage report](https://dev.sum7.eu/genofire/thrempp/badges/master/coverage.svg)](https://dev.sum7.eu/genofire/thrempp/pipelines) +XMPP - Transport + +ATM planned support for Threema only + + + diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 0000000..ec76178 --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,26 @@ +package cmd + +import ( + "os" + + "github.com/bdlm/log" + "github.com/spf13/cobra" +) + +var ( + timestamps bool +) + +// RootCmd represents the base command when called without any subcommands +var RootCmd = &cobra.Command{ + Use: "thrempp", +} + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + if err := RootCmd.Execute(); err != nil { + log.Fatal(err) + os.Exit(1) + } +} diff --git a/cmd/root_test.go b/cmd/root_test.go new file mode 100644 index 0000000..1d619dd --- /dev/null +++ b/cmd/root_test.go @@ -0,0 +1 @@ +package cmd diff --git a/cmd/serve.go b/cmd/serve.go new file mode 100644 index 0000000..7903fac --- /dev/null +++ b/cmd/serve.go @@ -0,0 +1,107 @@ +package cmd + +import ( + "os" + "os/signal" + "syscall" + + "github.com/bdlm/log" + "github.com/bdlm/std/logger" + "github.com/spf13/cobra" + + "dev.sum7.eu/genofire/golang-lib/database" + "dev.sum7.eu/genofire/golang-lib/file" + + "dev.sum7.eu/genofire/thrempp/component" + // need for database init + _ "dev.sum7.eu/genofire/thrempp/component/all" + _ "dev.sum7.eu/genofire/thrempp/models" +) + +type Config struct { + LogLevel logger.Level `toml:"log_level"` + Database database.Config `toml:"database"` + Components []component.Config `toml:"component"` +} + +var configPath string + +// serveCmd represents the serve command +var serveCmd = &cobra.Command{ + Use: "serve", + Short: "Run xmpp transport", + Example: "yanic serve --config /etc/thrempp.toml", + Run: func(cmd *cobra.Command, args []string) { + config := &Config{} + if err := file.ReadTOML(configPath, config); err != nil { + log.Panicf("open config file: %s", err) + } + + log.SetLevel(config.LogLevel) + + if err := database.Open(config.Database); err != nil { + log.Panicf("no database connection: %s", err) + } + defer database.Close() + component.Load(config.Components) + + // Wait for INT/TERM + sigs := make(chan os.Signal, 1) + signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) + sig := <-sigs + log.Infof("received %s", sig) + + /* + server := o3.ThreemaRest{} + + var thrAccount models.AccountThreema + if err := database.Read.First(&thrAccount).Error; err != nil { + id, _ := server.CreateIdentity() + thrAccount.TID = make([]byte, len(id.ID)) + thrAccount.LSK = make([]byte, len(id.LSK)) + copy(thrAccount.TID, id.ID[:]) + copy(thrAccount.LSK, id.LSK[:]) + database.Write.Create(&thrAccount) + } + + log.Warnf("%s", thrAccount.TID) + var lsk [32]byte + copy(lsk[:], thrAccount.LSK[:]) + tid, err := o3.NewThreemaID(string(thrAccount.TID), lsk, o3.AddressBook{}) + tid.Nick = o3.NewPubNick("xmpp:geno@fireorbit.de") + + ctx := o3.NewSessionContext(tid) + + // let the session begin + log.Info("Starting session") + sendMsgChan, receiveMsgChan, err := ctx.Run() + if err != nil { + log.Fatal(err) + } + // handle incoming messages + for receivedMessage := range receiveMsgChan { + if receivedMessage.Err != nil { + log.Errorf("Error Receiving Message: %s\n", receivedMessage.Err) + continue + } + switch msg := receivedMessage.Msg.(type) { + case o3.TextMessage: + if tid.String() == msg.Sender().String() { + continue + } + qoute := fmt.Sprintf("> %s: %s\n%s", msg.Sender(), msg.Text(), "Exactly!") + err = ctx.SendTextMessage(msg.Sender().String(), qoute, sendMsgChan) + if err != nil { + log.Fatal(err) + } + + } + } + */ + }, +} + +func init() { + RootCmd.AddCommand(serveCmd) + serveCmd.Flags().StringVarP(&configPath, "config", "c", "config.toml", "Path to configuration file") +} diff --git a/component/all/main.go b/component/all/main.go new file mode 100644 index 0000000..8f39aa4 --- /dev/null +++ b/component/all/main.go @@ -0,0 +1,6 @@ +package all + +import ( + // import all implementations + _ "dev.sum7.eu/genofire/thrempp/component/threema" +) diff --git a/component/all/main_test.go b/component/all/main_test.go new file mode 100644 index 0000000..1a6c647 --- /dev/null +++ b/component/all/main_test.go @@ -0,0 +1 @@ +package all diff --git a/component/main.go b/component/main.go new file mode 100644 index 0000000..0919671 --- /dev/null +++ b/component/main.go @@ -0,0 +1,36 @@ +package component + +import ( + "github.com/bdlm/log" + "gosrc.io/xmpp" +) + +type Component interface { + Connect() (chan xmpp.Packet, error) + Send(xmpp.Packet) +} + +// Connect function with config to get DB connection interface +type Connect func(config map[string]interface{}) (Component, error) + +var components = map[string]Connect{} + +func AddComponent(name string, c Connect) { + components[name] = c +} + +func Load(configs []Config) { + for _, config := range configs { + f, ok := components[config.Type] + if !ok { + log.Warnf("it was not possible to find a component with type '%s'", config.Type) + continue + } + comp, err := f(config.Special) + if err != nil { + log.WithField("type", config.Type).Panic(err) + } + config.comp = comp + log.WithField("type", config.Type).Infof("component for %s started", config.Host) + } +} diff --git a/component/main_test.go b/component/main_test.go new file mode 100644 index 0000000..cc264c9 --- /dev/null +++ b/component/main_test.go @@ -0,0 +1 @@ +package component diff --git a/component/threema/main.go b/component/threema/main.go new file mode 100644 index 0000000..0616aac --- /dev/null +++ b/component/threema/main.go @@ -0,0 +1,15 @@ +package threema + +import "dev.sum7.eu/genofire/thrempp/component" + +type Threema struct { + component.Component +} + +func NewThreema(config map[string]interface{}) (component.Component, error) { + return &Threema{}, nil +} + +func init() { + component.AddComponent("threema", NewThreema) +} diff --git a/component/threema/main_test.go b/component/threema/main_test.go new file mode 100644 index 0000000..a53b305 --- /dev/null +++ b/component/threema/main_test.go @@ -0,0 +1 @@ +package threema diff --git a/component/xmpp.go b/component/xmpp.go new file mode 100644 index 0000000..02a4ca6 --- /dev/null +++ b/component/xmpp.go @@ -0,0 +1,38 @@ +package component + +import ( + "gosrc.io/xmpp" +) + +type Config struct { + Type string + Host string + Connection string + Secret string + Special map[string]interface{} + + xmpp *xmpp.Component + comp Component +} + +func (c *Config) Start() error { + c.xmpp = &xmpp.Component{Host: c.Host, Secret: c.Secret} + err := c.xmpp.Connect(c.Connection) + if err != nil { + return err + } + out, err := c.comp.Connect() + if err != nil { + return err + } + + go c.recieve(out) + go c.sender() + + return nil +} + +func (c *Config) recieve(chan xmpp.Packet) { +} +func (c *Config) sender() { +} diff --git a/config_example.toml b/config_example.toml new file mode 100644 index 0000000..0e52875 --- /dev/null +++ b/config_example.toml @@ -0,0 +1,15 @@ +log_level = 50 + +[[component]] +type = "threema" +host = "threema.chat.sum7.eu" +connection = "localhost:10001" +secret = "change_me" + +[database] +type = "sqlite3" +logging = true +connection = "./thrempp.db" +# For Master-Slave cluster +# read_connection = "" + diff --git a/main.go b/main.go new file mode 100644 index 0000000..d54f0b9 --- /dev/null +++ b/main.go @@ -0,0 +1,7 @@ +package main + +import "dev.sum7.eu/genofire/thrempp/cmd" + +func main() { + cmd.Execute() +} diff --git a/models/account_threema.go b/models/account_threema.go new file mode 100644 index 0000000..82fcfba --- /dev/null +++ b/models/account_threema.go @@ -0,0 +1,19 @@ +package models + +import ( + "github.com/jinzhu/gorm" + + "dev.sum7.eu/genofire/golang-lib/database" +) + +type AccountThreema struct { + gorm.Model + XMPPID uint + XMPP JID + TID []byte + LSK []byte +} + +func init() { + database.AddModel(&AccountThreema{}) +} diff --git a/models/jid.go b/models/jid.go new file mode 100644 index 0000000..b42a2aa --- /dev/null +++ b/models/jid.go @@ -0,0 +1,21 @@ +package models + +import ( + "github.com/jinzhu/gorm" + + "dev.sum7.eu/genofire/golang-lib/database" +) + +type JID struct { + gorm.Model + Local string + Domain string +} + +func (j *JID) TableName() string { + return "jid" +} + +func init() { + database.AddModel(&JID{}) +} diff --git a/models/main_test.go b/models/main_test.go new file mode 100644 index 0000000..2640e7f --- /dev/null +++ b/models/main_test.go @@ -0,0 +1 @@ +package models