Auto-generate self-signed certs
This commit is contained in:
parent
05f700bc93
commit
04dd93c71d
4
Makefile
4
Makefile
@ -6,6 +6,10 @@ DIST_TARGETS = $(addprefix dist/$(OUTPUT)-,$(DIST_ARCH))
|
|||||||
.PHONY: default
|
.PHONY: default
|
||||||
default: slack-status
|
default: slack-status
|
||||||
|
|
||||||
|
.PHONY: run
|
||||||
|
run: slack-status
|
||||||
|
./slack-status
|
||||||
|
|
||||||
.PHONY: all
|
.PHONY: all
|
||||||
all: dist
|
all: dist
|
||||||
|
|
||||||
|
@ -2,6 +2,14 @@
|
|||||||
|
|
||||||
Set your Slack status via the command line
|
Set your Slack status via the command line
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
Rather than host a web server that you would need to trust, this command runs one on your local machine to retrieve the OAuth code. This page is hosted with an auto generated, self-signed certificate.
|
||||||
|
|
||||||
|
This requires you to have `openssl` installed on your machine and, when the page loads for the first time, it will require you to trust the certificate or ignore the warning.
|
||||||
|
|
||||||
|
Here's how to do that on [Firefox](https://support.mozilla.org/en-US/kb/error-codes-secure-websites?as=u&utm_source=inproduct#w_self-signed-certificate). On Chrome, you may have to enable `chrome://flags/#allow-insecure-localhost`.
|
||||||
|
|
||||||
## Example usage
|
## Example usage
|
||||||
|
|
||||||
Set auth token (it will store it in `~/.config/slack-status-cli` or your `$XDG_CONFIG_HOME` dir
|
Set auth token (it will store it in `~/.config/slack-status-cli` or your `$XDG_CONFIG_HOME` dir
|
||||||
|
52
auth.go
52
auth.go
@ -7,7 +7,9 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/slack-go/slack"
|
"github.com/slack-go/slack"
|
||||||
)
|
)
|
||||||
@ -51,7 +53,12 @@ func (app slackApp) listenForCode() (string, error) {
|
|||||||
var code string
|
var code string
|
||||||
|
|
||||||
// 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{Addr: app.listenHost}
|
server := http.Server{
|
||||||
|
Addr: app.listenHost,
|
||||||
|
ReadTimeout: 5 * time.Second,
|
||||||
|
WriteTimeout: 10 * time.Second,
|
||||||
|
IdleTimeout: 120 * time.Second,
|
||||||
|
}
|
||||||
|
|
||||||
http.HandleFunc(app.listenPath, func(w http.ResponseWriter, r *http.Request) {
|
http.HandleFunc(app.listenPath, func(w http.ResponseWriter, r *http.Request) {
|
||||||
codes := r.URL.Query()["code"]
|
codes := r.URL.Query()["code"]
|
||||||
@ -71,25 +78,64 @@ func (app slackApp) listenForCode() (string, error) {
|
|||||||
}()
|
}()
|
||||||
})
|
})
|
||||||
|
|
||||||
if err := server.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
|
certPath := getConfigFilePath("cert.pem")
|
||||||
|
keyPath := getConfigFilePath("key.pem")
|
||||||
|
|
||||||
|
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) {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
return code, nil
|
return code, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func fileExists(path string) bool {
|
||||||
|
if _, err := os.Stat(path); os.IsNotExist(err) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
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",
|
||||||
|
"-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"},
|
userScopes: []string{"dnd:write", "users.profile:write"},
|
||||||
scopes: []string{"dnd:write", "users.profile:write"},
|
scopes: []string{"dnd:write", "users.profile:write"},
|
||||||
clientID: getEnvOrDefault("CLIENT_ID", defaultClientID),
|
clientID: getEnvOrDefault("CLIENT_ID", defaultClientID),
|
||||||
clientSecret: getEnvOrDefault("CLIENT_SECRET", defaultClientSecret),
|
clientSecret: getEnvOrDefault("CLIENT_SECRET", defaultClientSecret),
|
||||||
redirectURI: "http://localhost:8888/auth",
|
redirectURI: "https://localhost:8888/auth",
|
||||||
listenHost: "localhost:8888",
|
listenHost: "localhost:8888",
|
||||||
listenPath: "/auth",
|
listenPath: "/auth",
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("To authenticate, go to the following URL:")
|
fmt.Println("To authenticate, go to the following URL:")
|
||||||
|
fmt.Println("NOTE: After you authenticate with Slack, it will redirect you to a server running on your local computer. Your browser will present a security error because it cann't verify the server. You will need to manually add an exception or tell your browser to proceed anyway.")
|
||||||
fmt.Println(app.getAuthURL())
|
fmt.Println(app.getAuthURL())
|
||||||
|
|
||||||
code, err := app.listenForCode()
|
code, err := app.listenForCode()
|
||||||
|
Loading…
Reference in New Issue
Block a user