Skip to content

Commit

Permalink
add in basic oauthLogin method
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob Archibald committed Feb 7, 2017
1 parent 47a4fa9 commit 8d3f4cd
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 1 deletion.
77 changes: 77 additions & 0 deletions authStore.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"encoding/json"
"errors"
"fmt"
"github.com/dgrijalva/jwt-go"
"io"
"io/ioutil"
"net/http"
Expand Down Expand Up @@ -31,6 +32,7 @@ const passwordValidationMessage string = "Password must be between 7 and 20 char
type authStorer interface {
GetSession() (*loginSession, error)
GetBasicAuth() (*loginSession, error)
OAuthLogin() error
Login() error
Register() error
CreateProfile() error
Expand Down Expand Up @@ -198,6 +200,81 @@ func (s *authStore) login(email, password string, rememberMe bool) (*loginSessio
return s.createSession(email, login.UserID, login.FullName, rememberMe)
}

func (s *authStore) OAuthLogin() error {
email, fullname, err := getOAuthCredentials(s.r)
if err != nil {
return err
}
return s.oauthLogin(email, fullname)
}

func (s *authStore) oauthLogin(email, fullname string) error {
var userID int
user, err := s.backend.GetUser(email)
if user == nil || err != nil {
userID, err = s.backend.AddUser(email)
if err != nil {
return newLoggedError("Failed to create new user in database", err)
}

err = s.backend.UpdateUser(userID, fullname, "", "")
if err != nil {
return newLoggedError("Unable to update user", err)
}
} else {
userID = user.UserID
}

_, err = s.createLogin(userID, email, fullname, "", 0, 0)
if err != nil {
return newLoggedError("Unable to create login", err)
}

_, err = s.createSession(email, userID, fullname, false)
if err != nil {
return err
}
return nil
}

func getOAuthCredentials(r *http.Request) (string, string, error) {
var fullname, email, email2 string
authHeader := r.Header.Get("Authorization")
if authHeader == "" {
return "", "", fmt.Errorf("No authorization found")
}

authHeaderParts := strings.Split(authHeader, " ")
if len(authHeaderParts) != 2 || strings.ToLower(authHeaderParts[0]) != "bearer" {
return "", "", fmt.Errorf("Authorization header format must be Bearer {token}")
}

// need to actually parse here and handle error
token, _ := jwt.Parse(authHeaderParts[1], func(token *jwt.Token) (interface{}, error) {
//if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
// return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
//}
// supposed to validate the signature according to Microsoft. This is not trivial
// https://docs.microsoft.com/en-us/azure/active-directory/develop/active-directory-v2-tokens#validating-tokens

// hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key")
return []byte("my_secret_key"), nil
})

claims, ok := token.Claims.(jwt.MapClaims)
if ok {
fullname = fmt.Sprintf("%v", claims["name"])
email = fmt.Sprintf("%v", claims["unique_name"])
fmt.Println("unique_name:", email)
email2 = fmt.Sprintf("%v", claims["email"])
fmt.Println("email:", email2)
if email == "" || fullname == "" {
return "", "", fmt.Errorf("expected email and fullname")
}
}
return email, fullname, nil
}

func (s *authStore) createSession(email string, userID int, fullname string, rememberMe bool) (*loginSession, error) {
var err error
var selector, token, tokenHash string
Expand Down
7 changes: 6 additions & 1 deletion nginxauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ func (s *nginxauth) serve(port int) {
http.HandleFunc("/authBasic", s.method("GET", authBasic))
http.HandleFunc("/createProfile", s.method("POST", createProfile))
http.HandleFunc("/login", s.method("POST", login))
http.HandleFunc("/oauth", s.method("GET", oauthLogin))
http.HandleFunc("/register", s.method("POST", register))
http.HandleFunc("/verifyEmail", s.method("POST", verifyEmail))
http.HandleFunc("/updateEmail", s.method("POST", updateEmail))
Expand Down Expand Up @@ -230,6 +231,10 @@ func basicErr(w http.ResponseWriter, r *http.Request, err error) {
logError(err)
}

func oauthLogin(authStore authStorer, w http.ResponseWriter, r *http.Request) {
run("oauthLogin", authStore.OAuthLogin, w)
}

func login(authStore authStorer, w http.ResponseWriter, r *http.Request) {
run("login", authStore.Login, w)
}
Expand Down Expand Up @@ -260,11 +265,11 @@ func run(name string, method func() error, w http.ResponseWriter) {
}

func writeOutput(w http.ResponseWriter, message string, err error) {
w.Header().Add("Access-Control-Allow-Origin", "*")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
logError(err)
} else {
w.Header().Add("Access-Control-Allow-Origin", "*")
w.Header().Add("Content-Type", "application/javascript")
fmt.Fprint(w, "{ \"result\": \"Success\" }")
}
Expand Down
4 changes: 4 additions & 0 deletions nginxauth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ func (s *mockAuthStorer) GetBasicAuth() (*loginSession, error) {
s.LastRun = "GetBasicAuth"
return s.SessionReturn, s.ErrReturn
}
func (s *mockAuthStorer) OAuthLogin() error {
s.LastRun = "OAuthLogin"
return s.ErrReturn
}
func (s *mockAuthStorer) Login() error {
s.LastRun = "Login"
return s.ErrReturn
Expand Down

0 comments on commit 8d3f4cd

Please sign in to comment.