initial commit
continuous-integration/drone Build is passing
Details
continuous-integration/drone Build is passing
Details
This commit is contained in:
commit
0c75f9fd36
|
|
@ -0,0 +1,21 @@
|
|||
kind: pipeline
|
||||
type: docker
|
||||
name: default
|
||||
|
||||
steps:
|
||||
- name: build and test
|
||||
image: golang
|
||||
commands:
|
||||
- make all
|
||||
- go test
|
||||
- name: gitea_release
|
||||
image: plugins/gitea-release
|
||||
settings:
|
||||
api_key:
|
||||
from_secret: gitea_token
|
||||
base_url: https://git.kwolek.io
|
||||
files:
|
||||
- dist/messagessh*
|
||||
when:
|
||||
event:
|
||||
- tag
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
|
||||
.PHONY: all linux darwin freebsd clean
|
||||
all: linux darwin freebsd
|
||||
|
||||
linux: $(addprefix dist/messagessh.linux.,amd64 arm64)
|
||||
darwin: $(addprefix dist/messagessh.darwin.,arm64 amd64)
|
||||
freebsd: $(addprefix dist/messagessh.freebsd.,amd64 arm)
|
||||
|
||||
clean:
|
||||
rm -rf dist
|
||||
|
||||
dist/messagessh.%: *.go go.mod go.sum
|
||||
$(eval platform := $(subst ., ,$@))
|
||||
$(eval os := $(word 2,$(platform)))
|
||||
$(eval arch := $(word 3,$(platform)))
|
||||
GOOS=$(os) GOARCH=$(arch) go build -o $@
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
module git.kwolek.io/wojciech/messages.sh
|
||||
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/gliderlabs/ssh v0.3.3
|
||||
github.com/stretchr/testify v1.7.0
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect
|
||||
github.com/davecgh/go-spew v1.1.0 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
|
||||
)
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
|
||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gliderlabs/ssh v0.3.3 h1:mBQ8NiOgDkINJrZtoizkC3nDNYgSaWtxyem6S2XHBtA=
|
||||
github.com/gliderlabs/ssh v0.3.3/go.mod h1:ZSS+CUoKHDrqVakTfTWUlKSr9MtMFkC4UvtQKD7O914=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e h1:gsTQYXdTw2Gq7RBsWvlQ91b+aEQ6bXFUngBGuR8sPpI=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 h1:RqytpXGR1iVNX7psjB3ff8y7sNFinVFvkx1c8SjBkio=
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gliderlabs/ssh"
|
||||
terminal "golang.org/x/term"
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
Content string
|
||||
Username string
|
||||
PK ssh.PublicKey
|
||||
PKShort string
|
||||
Timestamp time.Time
|
||||
}
|
||||
|
||||
type MessageList struct {
|
||||
list []Message
|
||||
size int
|
||||
}
|
||||
|
||||
func NewMessageList(size int) *MessageList {
|
||||
ml := &MessageList{size: size}
|
||||
return ml
|
||||
}
|
||||
|
||||
func (ml *MessageList) Add(m Message) {
|
||||
if len(ml.list) == ml.size {
|
||||
ml.list = ml.list[1:]
|
||||
}
|
||||
ml.list = append(ml.list, m)
|
||||
}
|
||||
|
||||
func (ml *MessageList) List() []Message {
|
||||
return ml.list
|
||||
}
|
||||
|
||||
func CheckString(s string) bool {
|
||||
for i := 0; i < len(s); i++ {
|
||||
if s[i] < 32 || s[i] > 126 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func main() {
|
||||
m := NewMessageList(10)
|
||||
pkAuth := ssh.PublicKeyAuth(func(ctx ssh.Context, key ssh.PublicKey) bool {
|
||||
return true
|
||||
})
|
||||
ssh.Handle(func(s ssh.Session) {
|
||||
term := terminal.NewTerminal(s, "> ")
|
||||
user := s.User()
|
||||
term.Write(term.Escape.Red)
|
||||
defer term.Write(term.Escape.Reset)
|
||||
if !CheckString(user) {
|
||||
io.WriteString(term, "Sorry, your username needs to be ASCII (without funky characters).\n")
|
||||
return
|
||||
}
|
||||
pk := s.PublicKey()
|
||||
if pk == nil {
|
||||
io.WriteString(s, "Hi! Please come back with a public key :)\n")
|
||||
return
|
||||
}
|
||||
term.Write(term.Escape.Reset)
|
||||
|
||||
pkMarshalled := pk.Marshal()
|
||||
pkHex := hex.EncodeToString(pkMarshalled)
|
||||
pkHexShort := pkHex[len(pkHex)-7:]
|
||||
|
||||
fmt.Fprintf(s,
|
||||
"%sHello, %s%s%s (%s)%s\n",
|
||||
term.Escape.Blue,
|
||||
term.Escape.Cyan, user,
|
||||
term.Escape.Blue, pkHexShort,
|
||||
term.Escape.Reset)
|
||||
|
||||
fmt.Fprintf(s, "%sRun %s`w`%s to write a message, %s`p`%s to print existing messages and %s`q`%s to quit.%s\n\n",
|
||||
term.Escape.Blue,
|
||||
term.Escape.Cyan, term.Escape.Blue,
|
||||
term.Escape.Cyan, term.Escape.Blue,
|
||||
term.Escape.Cyan, term.Escape.Blue,
|
||||
term.Escape.Reset)
|
||||
|
||||
for {
|
||||
term.SetPrompt(fmt.Sprintf("%s>%s ", term.Escape.Blue, term.Escape.Reset))
|
||||
cmd, err := term.ReadLine()
|
||||
if err == io.EOF {
|
||||
cmd = "q"
|
||||
err = nil
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
switch strings.TrimSpace(cmd) {
|
||||
case "w":
|
||||
term.SetPrompt(fmt.Sprintf("%sMessage:%s ", term.Escape.Blue, term.Escape.Reset))
|
||||
msg, err := term.ReadLine()
|
||||
if err == io.EOF {
|
||||
continue
|
||||
}
|
||||
fmt.Fprintf(term, "%sYour message:%s %s%s\n", term.Escape.Blue, term.Escape.White, msg, term.Escape.Reset)
|
||||
if !CheckString(msg) {
|
||||
fmt.Fprintf(term, "Sorry, your message contains non-ASCII or control characters.\n")
|
||||
continue
|
||||
}
|
||||
term.SetPrompt(fmt.Sprintf(
|
||||
"%sPublish? (%syes%s/%sno%s):%s ",
|
||||
term.Escape.Blue,
|
||||
term.Escape.Green, term.Escape.Blue,
|
||||
term.Escape.Green, term.Escape.Blue,
|
||||
term.Escape.Reset,
|
||||
))
|
||||
cmd, _ := term.ReadLine()
|
||||
if strings.ToLower(strings.TrimSpace(cmd)) == "yes" {
|
||||
m.Add(Message{
|
||||
Content: msg,
|
||||
Username: user,
|
||||
PK: pk,
|
||||
PKShort: pkHexShort,
|
||||
Timestamp: time.Now(),
|
||||
})
|
||||
fmt.Fprintf(term, "%sPublished!%s\n", term.Escape.Green, term.Escape.Reset)
|
||||
} else {
|
||||
fmt.Fprintf(term, "%sOkay, not publishing.%s\n", term.Escape.Blue, term.Escape.Reset)
|
||||
}
|
||||
case "p":
|
||||
for _, msg := range m.List() {
|
||||
fmt.Fprintf(term,
|
||||
"%s%s <%s%s%s (%s)%s> %s%s%s\n",
|
||||
term.Escape.Blue,
|
||||
msg.Timestamp.Format("2006-01-02 15:04:05 MST"),
|
||||
term.Escape.Cyan, msg.Username, term.Escape.Blue,
|
||||
msg.PKShort, term.Escape.Blue,
|
||||
term.Escape.White, msg.Content, term.Escape.Reset)
|
||||
}
|
||||
case "q":
|
||||
fmt.Fprintf(term, "Bye!\n")
|
||||
return
|
||||
default:
|
||||
fmt.Fprintln(term, "Unknown command.")
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
log.Fatal(ssh.ListenAndServe(":2222", nil, pkAuth))
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestAdd(t *testing.T) {
|
||||
ml := NewMessageList(3)
|
||||
ml.Add(Message{Content: "1"})
|
||||
assert.Len(t, ml.list, 1)
|
||||
assert.Equal(t, ml.list[0].Content, "1")
|
||||
ml.Add(Message{Content: "2"})
|
||||
assert.Len(t, ml.list, 2)
|
||||
assert.Equal(t, ml.list[0].Content, "1")
|
||||
assert.Equal(t, ml.list[1].Content, "2")
|
||||
ml.Add(Message{Content: "3"})
|
||||
assert.Len(t, ml.list, 3)
|
||||
assert.Equal(t, ml.list[0].Content, "1")
|
||||
assert.Equal(t, ml.list[1].Content, "2")
|
||||
assert.Equal(t, ml.list[2].Content, "3")
|
||||
ml.Add(Message{Content: "4"})
|
||||
assert.Len(t, ml.list, 3)
|
||||
assert.Equal(t, ml.list[0].Content, "2")
|
||||
assert.Equal(t, ml.list[1].Content, "3")
|
||||
assert.Equal(t, ml.list[2].Content, "4")
|
||||
ml.Add(Message{Content: "5"})
|
||||
assert.Len(t, ml.list, 3)
|
||||
assert.Equal(t, ml.list[0].Content, "3")
|
||||
assert.Equal(t, ml.list[1].Content, "4")
|
||||
assert.Equal(t, ml.list[2].Content, "5")
|
||||
ml.Add(Message{Content: "6"})
|
||||
assert.Len(t, ml.list, 3)
|
||||
assert.Equal(t, ml.list[0].Content, "4")
|
||||
assert.Equal(t, ml.list[1].Content, "5")
|
||||
assert.Equal(t, ml.list[2].Content, "6")
|
||||
}
|
||||
Loading…
Reference in New Issue