Start of logging in with Indieauth on Micropub
This commit is contained in:
parent
e491a61dae
commit
89201c0178
|
@ -37,6 +37,7 @@ type authResponse struct {
|
||||||
|
|
||||||
type indexPage struct {
|
type indexPage struct {
|
||||||
Session session
|
Session session
|
||||||
|
Baseurl string
|
||||||
}
|
}
|
||||||
type settingsPage struct {
|
type settingsPage struct {
|
||||||
Session session
|
Session session
|
||||||
|
@ -50,6 +51,15 @@ type logsPage struct {
|
||||||
Session session
|
Session session
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type authPage struct {
|
||||||
|
Session session
|
||||||
|
Me string
|
||||||
|
ClientID string
|
||||||
|
Scope []string
|
||||||
|
RedirectURI string
|
||||||
|
Channels []microsub.Channel
|
||||||
|
}
|
||||||
|
|
||||||
func newMainHandler(backend *memoryBackend) (*mainHandler, error) {
|
func newMainHandler(backend *memoryBackend) (*mainHandler, error) {
|
||||||
h := &mainHandler{Backend: backend}
|
h := &mainHandler{Backend: backend}
|
||||||
|
|
||||||
|
@ -178,6 +188,7 @@ func (h *mainHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
var page indexPage
|
var page indexPage
|
||||||
page.Session = sess
|
page.Session = sess
|
||||||
|
page.Baseurl = strings.TrimRight(os.Getenv("EKSTER_BASEURL"), "/")
|
||||||
|
|
||||||
err = h.Templates.ExecuteTemplate(w, "index.html", page)
|
err = h.Templates.ExecuteTemplate(w, "index.html", page)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -185,7 +196,7 @@ func (h *mainHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
} else if r.URL.Path == "/auth/callback" {
|
} else if r.URL.Path == "/session/callback" {
|
||||||
c, err := r.Cookie("session")
|
c, err := r.Cookie("session")
|
||||||
if err == http.ErrNoCookie {
|
if err == http.ErrNoCookie {
|
||||||
http.Redirect(w, r, "/", 302)
|
http.Redirect(w, r, "/", 302)
|
||||||
|
@ -300,9 +311,55 @@ func (h *mainHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
|
} else if r.URL.Path == "/auth" {
|
||||||
|
// check if we are logged in
|
||||||
|
// TODO: if not logged in, make sure we get back here
|
||||||
|
c, err := r.Cookie("session")
|
||||||
|
if err == http.ErrNoCookie {
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
sessionVar := c.Value
|
||||||
|
sess, err := loadSession(sessionVar, conn)
|
||||||
|
|
||||||
|
if !isLoggedIn(h.Backend, &sess) {
|
||||||
|
http.Redirect(w, r, "/", 302)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
query := r.URL.Query()
|
||||||
|
|
||||||
|
//responseType := query.Get("response_type")
|
||||||
|
me := query.Get("me")
|
||||||
|
clientID := query.Get("client_id")
|
||||||
|
redirectURI := query.Get("redirect_uri")
|
||||||
|
//state := query.Get("state")
|
||||||
|
scope := query.Get("scope")
|
||||||
|
if scope == "" {
|
||||||
|
scope = "create"
|
||||||
|
}
|
||||||
|
// Save this ^^ in Redis based on me,client_id,redirect_uri
|
||||||
|
|
||||||
|
var page authPage
|
||||||
|
page.Session = sess
|
||||||
|
page.Me = me
|
||||||
|
page.ClientID = clientID
|
||||||
|
page.RedirectURI = redirectURI
|
||||||
|
page.Scope = strings.Split(scope, " ")
|
||||||
|
page.Channels, err = h.Backend.ChannelsGetList()
|
||||||
|
|
||||||
|
err = h.Templates.ExecuteTemplate(w, "auth.html", page)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintf(w, "ERROR: %q\n", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
|
||||||
|
} else if r.URL.Path == "/auth/token" {
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if r.Method == http.MethodPost {
|
} else if r.Method == http.MethodPost {
|
||||||
if r.URL.Path == "/auth" {
|
if r.URL.Path == "/session" {
|
||||||
c, err := r.Cookie("session")
|
c, err := r.Cookie("session")
|
||||||
if err == http.ErrNoCookie {
|
if err == http.ErrNoCookie {
|
||||||
http.Redirect(w, r, "/", 302)
|
http.Redirect(w, r, "/", 302)
|
||||||
|
@ -334,7 +391,7 @@ func (h *mainHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
log.Println(authURL)
|
log.Println(authURL)
|
||||||
|
|
||||||
state := util.RandStringBytes(16)
|
state := util.RandStringBytes(16)
|
||||||
redirectURI := fmt.Sprintf("%s/auth/callback", os.Getenv("EKSTER_BASEURL"))
|
redirectURI := fmt.Sprintf("%s/session/callback", os.Getenv("EKSTER_BASEURL"))
|
||||||
|
|
||||||
sess := session{
|
sess := session{
|
||||||
AuthorizationEndpoint: endpoints.AuthorizationEndpoint,
|
AuthorizationEndpoint: endpoints.AuthorizationEndpoint,
|
||||||
|
@ -355,7 +412,7 @@ func (h *mainHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
http.Redirect(w, r, authURL.String(), 302)
|
http.Redirect(w, r, authURL.String(), 302)
|
||||||
return
|
return
|
||||||
} else if r.URL.Path == "/auth/logout" {
|
} else if r.URL.Path == "/session/logout" {
|
||||||
c, err := r.Cookie("session")
|
c, err := r.Cookie("session")
|
||||||
|
|
||||||
if err == http.ErrNoCookie {
|
if err == http.ErrNoCookie {
|
||||||
|
@ -367,6 +424,9 @@ func (h *mainHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
conn.Do("DEL", "session:"+sessionVar)
|
conn.Do("DEL", "session:"+sessionVar)
|
||||||
http.Redirect(w, r, "/", 302)
|
http.Redirect(w, r, "/", 302)
|
||||||
return
|
return
|
||||||
|
} else if r.URL.Path == "/auth/approve" {
|
||||||
|
// create a code
|
||||||
|
// and redirect
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,13 @@ type micropubHandler struct {
|
||||||
Backend *memoryBackend
|
Backend *memoryBackend
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* URLs needed:
|
||||||
|
* - / with endpoint urls
|
||||||
|
* - /micropub micropub endpoint
|
||||||
|
* - /auth auth endpoint
|
||||||
|
* - /token token endpoint
|
||||||
|
*/
|
||||||
func (h *micropubHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (h *micropubHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
defer r.Body.Close()
|
defer r.Body.Close()
|
||||||
|
|
||||||
|
@ -25,7 +32,10 @@ func (h *micropubHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
r.ParseForm()
|
r.ParseForm()
|
||||||
|
|
||||||
if r.Method == http.MethodPost {
|
if r.Method == http.MethodGet {
|
||||||
|
// show profile with endpoint urls
|
||||||
|
|
||||||
|
} else if r.Method == http.MethodPost {
|
||||||
sourceID := r.URL.Query().Get("source_id")
|
sourceID := r.URL.Query().Get("source_id")
|
||||||
|
|
||||||
authHeader := r.Header.Get("Authorization")
|
authHeader := r.Header.Get("Authorization")
|
||||||
|
|
95
templates/auth.html
Normal file
95
templates/auth.html
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<title>Ekster</title>
|
||||||
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<section class="section">
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
|
||||||
|
<nav class="navbar" role="navigation" aria-label="main navigation">
|
||||||
|
<div class="navbar-brand">
|
||||||
|
<a class="navbar-item" href="/">
|
||||||
|
Ekster
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="menu">
|
||||||
|
<span aria-hidden="true"></span>
|
||||||
|
<span aria-hidden="true"></span>
|
||||||
|
<span aria-hidden="true"></span>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{ if .Session.LoggedIn }}
|
||||||
|
<div id="menu" class="navbar-menu">
|
||||||
|
<a class="navbar-item" href="/settings">
|
||||||
|
Settings
|
||||||
|
</a>
|
||||||
|
<a class="navbar-item" href="/logs">
|
||||||
|
Logs
|
||||||
|
</a>
|
||||||
|
<a class="navbar-item" href="{{ .Session.Me }}">
|
||||||
|
Profile
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<h1 class="title">Ekster - Microsub server</h1>
|
||||||
|
|
||||||
|
<div class="box">
|
||||||
|
<form action="/auth/approve" method="post">
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Client ID</label>
|
||||||
|
<div class="control">
|
||||||
|
<p>{{ .ClientID }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">RedirectURI</label>
|
||||||
|
<div class="control">
|
||||||
|
<p>{{ .RedirectURI }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Scope</label>
|
||||||
|
<div class="control">
|
||||||
|
{{ range .Scope }}
|
||||||
|
<p>{{ . }}</p>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Select a channel</label>
|
||||||
|
<div class="control">
|
||||||
|
<div class="select">
|
||||||
|
<select name="channel">
|
||||||
|
{{ range .Channels }}
|
||||||
|
<option value="{{ .UID }}">{{ .Name }}</option>
|
||||||
|
{{ end }}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<button type="submit" name="accept" value="approve" class="button is-primary">
|
||||||
|
Approve
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -5,6 +5,9 @@
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<title>Ekster</title>
|
<title>Ekster</title>
|
||||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css">
|
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.1/css/bulma.min.css">
|
||||||
|
<link rel="micropub" href="{{ .Baseurl }}/micropub" />
|
||||||
|
<link rel="authorization_endpoint" href="{{ .Baseurl }}/auth" />
|
||||||
|
<link rel="token_endpoint" href="{{ .Baseurl }}/auth/token" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<section class="section">
|
<section class="section">
|
||||||
|
@ -43,12 +46,12 @@
|
||||||
|
|
||||||
{{ if .Session.LoggedIn }}
|
{{ if .Session.LoggedIn }}
|
||||||
<h2 class="title">Logout</h2>
|
<h2 class="title">Logout</h2>
|
||||||
<form action="/auth/logout" method="post">
|
<form action="/session/logout" method="post">
|
||||||
<button type="submit" class="button is-info">Logout</button>
|
<button type="submit" class="button is-info">Logout</button>
|
||||||
</form>
|
</form>
|
||||||
{{ else }}
|
{{ else }}
|
||||||
<h2 class="title">Sign in to Ekster</h2>
|
<h2 class="title">Sign in to Ekster</h2>
|
||||||
<form action="/auth" method="post">
|
<form action="/session" method="post">
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label class="label" for="url"></label>
|
<label class="label" for="url"></label>
|
||||||
<div class="control">
|
<div class="control">
|
||||||
|
|
Loading…
Reference in New Issue
Block a user