mirror of
https://github.com/juanfont/headscale.git
synced 2024-11-29 18:33:05 +00:00
commit
fb933b7d41
4 changed files with 93 additions and 39 deletions
56
api.go
56
api.go
|
@ -1,10 +1,12 @@
|
|||
package headscale
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
@ -38,6 +40,28 @@ func (h *Headscale) KeyHandler(ctx *gin.Context) {
|
|||
)
|
||||
}
|
||||
|
||||
type registerWebAPITemplateConfig struct {
|
||||
Key string
|
||||
}
|
||||
|
||||
var registerWebAPITemplate = template.Must(
|
||||
template.New("registerweb").Parse(`<html>
|
||||
<body>
|
||||
<h1>headscale</h1>
|
||||
<p>
|
||||
Run the command below in the headscale server to add this machine to your network:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<code>
|
||||
<b>headscale -n NAMESPACE nodes register --key {{.Key}}</b>
|
||||
</code>
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>`),
|
||||
)
|
||||
|
||||
// RegisterWebAPI shows a simple message in the browser to point to the CLI
|
||||
// Listens in /register.
|
||||
func (h *Headscale) RegisterWebAPI(ctx *gin.Context) {
|
||||
|
@ -48,24 +72,22 @@ func (h *Headscale) RegisterWebAPI(ctx *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
ctx.Data(http.StatusOK, "text/html; charset=utf-8", []byte(fmt.Sprintf(`
|
||||
<html>
|
||||
<body>
|
||||
<h1>headscale</h1>
|
||||
<p>
|
||||
Run the command below in the headscale server to add this machine to your network:
|
||||
</p>
|
||||
var content bytes.Buffer
|
||||
if err := registerWebAPITemplate.Execute(&content, registerWebAPITemplateConfig{
|
||||
Key: machineKeyStr,
|
||||
}); err != nil {
|
||||
log.Error().
|
||||
Str("func", "RegisterWebAPI").
|
||||
Err(err).
|
||||
Msg("Could not render register web API template")
|
||||
ctx.Data(
|
||||
http.StatusInternalServerError,
|
||||
"text/html; charset=utf-8",
|
||||
[]byte("Could not render register web API template"),
|
||||
)
|
||||
}
|
||||
|
||||
<p>
|
||||
<code>
|
||||
<b>headscale -n NAMESPACE nodes register --key %s</b>
|
||||
</code>
|
||||
</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
||||
`, machineKeyStr)))
|
||||
ctx.Data(http.StatusOK, "text/html; charset=utf-8", content.Bytes())
|
||||
}
|
||||
|
||||
// RegistrationHandler handles the actual registration process of a machine
|
||||
|
|
|
@ -2,8 +2,8 @@ package headscale
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"text/template"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/gofrs/uuid"
|
||||
|
|
72
oidc.go
72
oidc.go
|
@ -1,11 +1,13 @@
|
|||
package headscale
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
@ -108,6 +110,22 @@ func (h *Headscale) RegisterOIDC(ctx *gin.Context) {
|
|||
ctx.Redirect(http.StatusFound, authURL)
|
||||
}
|
||||
|
||||
type oidcCallbackTemplateConfig struct {
|
||||
User string
|
||||
Verb string
|
||||
}
|
||||
|
||||
var oidcCallbackTemplate = template.Must(
|
||||
template.New("oidccallback").Parse(`<html>
|
||||
<body>
|
||||
<h1>headscale</h1>
|
||||
<p>
|
||||
{{.Verb}} as {{.User}}, you can now close this window.
|
||||
</p>
|
||||
</body>
|
||||
</html>`),
|
||||
)
|
||||
|
||||
// OIDCCallback handles the callback from the OIDC endpoint
|
||||
// Retrieves the mkey from the state cache and adds the machine to the users email namespace
|
||||
// TODO: A confirmation page for new machines should be added to avoid phishing vulnerabilities
|
||||
|
@ -239,17 +257,24 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) {
|
|||
|
||||
h.RefreshMachine(machine, requestedTime)
|
||||
|
||||
ctx.Data(http.StatusOK, "text/html; charset=utf-8", []byte(fmt.Sprintf(`
|
||||
<html>
|
||||
<body>
|
||||
<h1>headscale</h1>
|
||||
<p>
|
||||
Reuthenticated as %s, you can now close this window.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
var content bytes.Buffer
|
||||
if err := oidcCallbackTemplate.Execute(&content, oidcCallbackTemplateConfig{
|
||||
User: claims.Email,
|
||||
Verb: "Reauthenticated",
|
||||
}); err != nil {
|
||||
log.Error().
|
||||
Str("func", "OIDCCallback").
|
||||
Str("type", "reauthenticate").
|
||||
Err(err).
|
||||
Msg("Could not render OIDC callback template")
|
||||
ctx.Data(
|
||||
http.StatusInternalServerError,
|
||||
"text/html; charset=utf-8",
|
||||
[]byte("Could not render OIDC callback template"),
|
||||
)
|
||||
}
|
||||
|
||||
`, claims.Email)))
|
||||
ctx.Data(http.StatusOK, "text/html; charset=utf-8", content.Bytes())
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -314,17 +339,24 @@ func (h *Headscale) OIDCCallback(ctx *gin.Context) {
|
|||
h.db.Save(&machine)
|
||||
}
|
||||
|
||||
ctx.Data(http.StatusOK, "text/html; charset=utf-8", []byte(fmt.Sprintf(`
|
||||
<html>
|
||||
<body>
|
||||
<h1>headscale</h1>
|
||||
<p>
|
||||
Authenticated as %s, you can now close this window.
|
||||
</p>
|
||||
</body>
|
||||
</html>
|
||||
var content bytes.Buffer
|
||||
if err := oidcCallbackTemplate.Execute(&content, oidcCallbackTemplateConfig{
|
||||
User: claims.Email,
|
||||
Verb: "Authenticated",
|
||||
}); err != nil {
|
||||
log.Error().
|
||||
Str("func", "OIDCCallback").
|
||||
Str("type", "authenticate").
|
||||
Err(err).
|
||||
Msg("Could not render OIDC callback template")
|
||||
ctx.Data(
|
||||
http.StatusInternalServerError,
|
||||
"text/html; charset=utf-8",
|
||||
[]byte("Could not render OIDC callback template"),
|
||||
)
|
||||
}
|
||||
|
||||
`, claims.Email)))
|
||||
ctx.Data(http.StatusOK, "text/html; charset=utf-8", content.Bytes())
|
||||
|
||||
return
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@ package headscale
|
|||
import (
|
||||
"bytes"
|
||||
_ "embed"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"text/template"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/rs/zerolog/log"
|
||||
|
|
Loading…
Reference in a new issue