Skip to content

Instantly share code, notes, and snippets.

@mytrile
Forked from minikomi/persona.go
Created January 18, 2013 12:08
Show Gist options
  • Save mytrile/4564187 to your computer and use it in GitHub Desktop.
Save mytrile/4564187 to your computer and use it in GitHub Desktop.
package main
import (
"encoding/json"
"fmt"
"github.com/gorilla/sessions"
"io/ioutil"
"log"
"net/http"
"net/url"
)
type PersonaResponse struct {
Status string `json: "status"`
Email string `json: "email"`
Audience string `json: "audience"`
Expires int64 `json: "expires"`
Issuer string `json: "issuer"`
}
var template = `
<html>
<head>
<title>Mozilla Persona Test</title>
<script src="https://login.persona.org/include.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script>
$("document").ready(function(){
$("#logout").hide();
function loggedIn(email){
$("#title").text("Welcome, " + email);
$("#login").hide();
$("#logout").show();
}
function loggedOut(){
$("#title").text("Please Log In using Mozilla Persona.");
$("#logout").hide();
$("#login").show();
}
$("#login").on("click", function(e) {
e.preventDefault();
navigator.id.get(mailVerified);
});
$("#logout").on("click", function(e) {
e.preventDefault();
$.get('/auth/logout', loggedOut);
});
function mailVerified(assertion){
console.log(assertion);
$.ajax({
type: 'POST',
url: '/auth/login',
data: {assertion: assertion},
success: function(res, status, xhr) {
loggedIn(JSON.parse(res).email);
},
error: function(xhr, status, err) { alert("Login failure: " + err); }
});
}
$.get('/auth/check', function (res) {
if (res === "") loggedOut();
else loggedIn(res);
});
});
</script>
</head>
<body>
<h1 id="title">Please Log In using Mozilla Persona.</h1>
<a href="#" id="login">login</a>
<a href="#" id="logout">logout</a>
</body>
</html>
`
var store = sessions.NewCookieStore([]byte("secret banana for you."))
func indexHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, template)
}
func loginCheckHandler(w http.ResponseWriter, r *http.Request) {
session, _ := store.Get(r, "persona-session")
email := session.Values["email"]
if email != nil {
w.Write([]byte(email).(string))
} else {
w.Write("")
}
}
func logoutHandler(w http.ResponseWriter, r *http.Request) {
session, _ := store.Get(r, "persona-session")
session.Values["email"] = nil
session.Save(r, w)
w.Write([]byte("OK"))
}
func loginHandler(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
if err != nil {
w.WriteHeader(400)
w.Write([]byte("Bad Request."))
}
assertion := r.FormValue("assertion")
if assertion == "" {
log.Println(err)
w.WriteHeader(400)
w.Write([]byte("Bad Request."))
}
log.Println(assertion)
data := url.Values{"assertion": {assertion}, "audience": {"http://poyo.co:8080"}}
resp, err := http.PostForm("https://verifier.login.persona.org/verify", data)
if err != nil {
log.Println(err)
w.WriteHeader(400)
w.Write([]byte("Bad Request."))
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Println(err)
w.WriteHeader(400)
w.Write([]byte("Bad Request."))
}
pr := &PersonaResponse{}
err = json.Unmarshal(body, pr)
if err != nil {
log.Println(err)
w.WriteHeader(400)
w.Write([]byte("Bad Request."))
}
session, _ := store.Get(r, "persona-session")
session.Values["email"] = pr.Email
session.Save(r, w)
w.Write(body)
}
func main() {
http.HandleFunc("/", indexHandler)
http.HandleFunc("/auth/check", loginCheckHandler)
http.HandleFunc("/auth/login", loginHandler)
http.HandleFunc("/auth/logout", logoutHandler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment