Add embedded certificates
Some checks failed
continuous-integration/drone/push Build is failing

Removes runtime requirement on openssl

Fixes #1
This commit is contained in:
IamTheFij 2021-02-16 14:16:45 -08:00
parent c303bc055d
commit 0b0b7fe395
4 changed files with 50 additions and 43 deletions

1
.gitignore vendored
View File

@ -19,3 +19,4 @@ slack-status
slack-status-cli slack-status-cli
dist/ dist/
.env .env
certs/

View File

@ -19,23 +19,32 @@ test:
pre-commit run --all-files pre-commit run --all-files
go test go test
slack-status: $(GOFILES) slack-status: $(GOFILES) certs/key.pem
go build -o $(OUTPUT) go build -o $(OUTPUT)
.PHONY: dist .PHONY: dist
dist: $(DIST_TARGETS) dist: $(DIST_TARGETS)
$(DIST_TARGETS): $(GOFILES) $(DIST_TARGETS): $(GOFILES) certs/key.pem
@mkdir -p ./dist @mkdir -p ./dist
GOOS=$(word 3, $(subst -, ,$(@))) GOARCH=$(word 4, $(subst -, ,$(@))) \ GOOS=$(word 3, $(subst -, ,$(@))) GOARCH=$(word 4, $(subst -, ,$(@))) \
go build \ go build \
-ldflags '-X "main.version=${VERSION}" -X "main.defaultClientID=$(CLIENT_ID)" -X "main.defaultClientSecret=$(CLIENT_SECRET)"' \ -ldflags '-X "main.version=${VERSION}" -X "main.defaultClientID=$(CLIENT_ID)" -X "main.defaultClientSecret=$(CLIENT_SECRET)"' \
-o $@ -o $@
certs/cert.pem: certs/key.pem
certs/key.pem:
mkdir -p certs/
openssl req -x509 -subj "/C=US/O=Slack Status CLI/CN=localhost:8888" \
-nodes -days 365 -newkey "rsa:2048" \
-addext "subjectAltName=DNS:localhost:8888" \
-keyout certs/key.pem -out certs/cert.pem
.PHONY: clean .PHONY: clean
clean: clean:
rm -f ./slack-status rm -f ./slack-status
rm -fr ./dist rm -fr ./dist
rm -fr ./certs
.PHONY: install-hooks .PHONY: install-hooks
install-hooks: install-hooks:

77
auth.go
View File

@ -2,11 +2,12 @@ package main
import ( import (
"context" "context"
"crypto/tls"
_ "embed"
"errors" "errors"
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
"os/exec"
"strings" "strings"
"time" "time"
@ -17,6 +18,11 @@ var (
// These are set via build flags but can be overridden via environment variables. // These are set via build flags but can be overridden via environment variables.
defaultClientID = "" defaultClientID = ""
defaultClientSecret = "" defaultClientSecret = ""
//go:embed "certs/cert.pem"
certPem []byte
//go:embed "certs/key.pem"
keyPem []byte
) )
const ( const (
@ -48,12 +54,42 @@ func (app slackApp) listenForCode() (string, error) {
// start an http listener and listen for the redirect and return the code from params // start an http listener and listen for the redirect and return the code from params
var code string var code string
certPath, err := getConfigFilePath("cert.pem")
if err != nil {
return "", fmt.Errorf("failed checking config path for cert: %w", err)
}
keyPath, err := getConfigFilePath("key.pem")
if err != nil {
return "", fmt.Errorf("failed checking config path for key: %w", err)
}
tlsCfg := &tls.Config{
MinVersion: tls.VersionTLS12,
}
// If config files don't exist, use embedded
if !fileExists(certPath) && !fileExists(keyPath) {
cert, err := tls.X509KeyPair(certPem, keyPem)
if err != nil {
return "", fmt.Errorf("failed loading embedded key pair: %w", err)
}
tlsCfg.Certificates = make([]tls.Certificate, 1)
tlsCfg.Certificates[0] = cert
// Empty out paths since they don't exist so embeded certs will be used
certPath = ""
keyPath = ""
}
// Also, should generate TLS certificate to use since https is a required scheme // Also, should generate TLS certificate to use since https is a required scheme
server := http.Server{ server := http.Server{
Addr: app.listenHost, Addr: app.listenHost,
ReadTimeout: httpReadTimeout, ReadTimeout: httpReadTimeout,
WriteTimeout: httpWriteTimeout, WriteTimeout: httpWriteTimeout,
IdleTimeout: httpIdleTimeout, IdleTimeout: httpIdleTimeout,
TLSConfig: tlsCfg,
} }
http.HandleFunc(app.listenPath, func(w http.ResponseWriter, r *http.Request) { http.HandleFunc(app.listenPath, func(w http.ResponseWriter, r *http.Request) {
@ -74,22 +110,6 @@ func (app slackApp) listenForCode() (string, error) {
}() }()
}) })
certPath, err := getConfigFilePath("cert.pem")
if err != nil {
return "", err
}
keyPath, err := getConfigFilePath("key.pem")
if err != nil {
return "", err
}
if !fileExists(certPath) || !fileExists(keyPath) {
if err := generateSelfSignedCertificates(certPath, keyPath); err != nil {
return "", err
}
}
if err := server.ListenAndServeTLS(certPath, keyPath); err != nil && !errors.Is(err, http.ErrServerClosed) { if err := server.ListenAndServeTLS(certPath, keyPath); err != nil && !errors.Is(err, http.ErrServerClosed) {
return "", err return "", err
} }
@ -97,29 +117,6 @@ func (app slackApp) listenForCode() (string, error) {
return code, nil return code, nil
} }
func generateSelfSignedCertificates(certPath, keyPath string) error {
command := exec.Command(
"openssl",
"req",
"-x509",
"-subj",
"/C=US/O=Slack Status CLI/CN=localhost:8888",
"-nodes",
"-days",
"365",
"-newkey",
"rsa:2048",
"-addext",
"subjectAltName=DNS:localhost:8888",
"-keyout",
keyPath,
"-out",
certPath,
)
return command.Run()
}
func authenticate() (string, error) { func authenticate() (string, error) {
app := slackApp{ app := slackApp{
userScopes: []string{"dnd:write", "users.profile:write", "team:read"}, userScopes: []string{"dnd:write", "users.profile:write", "team:read"},

2
go.mod
View File

@ -1,5 +1,5 @@
module github.com/iamthefij/slack-status-cli module github.com/iamthefij/slack-status-cli
go 1.15 go 1.16
require github.com/slack-go/slack v0.7.4 require github.com/slack-go/slack v0.7.4