1
0
mirror of https://github.com/vwxyzjn/portwarden synced 2025-12-22 18:43:13 +00:00

API-6 # Add middleware to verify token

This commit is contained in:
Costa Huang
2018-12-01 01:45:35 -05:00
parent ad3cb2a185
commit 094966f20e
5 changed files with 61 additions and 55 deletions

View File

@@ -10,7 +10,11 @@ import (
) )
const ( const (
ErrRetrievingOauthCode = "error retrieving oauth login credentials; try again" ErrRetrievingOauthCode = "error retrieving oauth login credentials; try again"
ErrCreatingPortwardenUser = "error creating a portwarden user"
FrontEndBaseAddressTest = "http://localhost:8000/"
FrontEndBaseAddressProd = ""
) )
func EncryptBackupHandler(c *gin.Context) { func EncryptBackupHandler(c *gin.Context) {
@@ -51,14 +55,15 @@ func (ps *PortwardenServer) GetGoogleDriveLoginHandler(c *gin.Context) {
c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error(), "message": "Login failure"}) c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error(), "message": "Login failure"})
return return
} }
// pu := &PortwardenUser{GoogleToken: tok} pu := &PortwardenUser{GoogleToken: tok}
body, err := GetUserInfo(tok) err = pu.CreateWithGoogle()
if err != nil { if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error(), "message": ""}) c.JSON(http.StatusBadRequest, gin.H{"error": err.Error(), "message": ErrCreatingPortwardenUser})
return return
} }
spew.Dump(string(body))
c.JSON(200, "Login Successful") spew.Dump(pu)
c.Redirect(http.StatusMovedPermanently, FrontEndBaseAddressTest+"?access_token="+pu.GoogleToken.AccessToken)
return return
} }

View File

@@ -182,39 +182,6 @@ func UploadFile(fileBytes []byte, client *http.Client, token *oauth2.Token) erro
return nil return nil
} }
func GetUserInfo(token *oauth2.Token) ([]byte, error) {
postURL := "https://www.googleapis.com/oauth2/v2/userinfo"
// Extract auth or access token from Token file
// See https://godoc.org/gnolang.org/x/oauth2#Token
// authToken := token.AccessToken
// Post to Drive with RESTful method
request, err := http.NewRequest("GET", postURL, nil)
if err != nil {
return nil, err
}
request.Header.Add("Host", "www.googleapis.com")
request.Header.Add("Authorization", "Bearer "+"authToken")
request.Header.Add("Content-Length", strconv.FormatInt(request.ContentLength, 10))
// For debugging
//fmt.Println(request)
GoogleDriveClient := GoogleDriveAppConfig.Client(oauth2.NoContext, token)
response, err := GoogleDriveClient.Do(request)
if err != nil {
return nil, err
}
defer response.Body.Close()
body, err := ioutil.ReadAll(response.Body)
if err != nil {
return nil, err
}
return body, nil
}
/* /*
func main() { func main() {

View File

@@ -1,11 +1,11 @@
package server package server
import ( import (
"fmt"
"net/http" "net/http"
"strconv"
"strings"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"golang.org/x/oauth2"
) )
const ( const (
@@ -14,23 +14,19 @@ const (
func TokenAuthMiddleware() gin.HandlerFunc { func TokenAuthMiddleware() gin.HandlerFunc {
return func(c *gin.Context) { return func(c *gin.Context) {
fmt.Println("middleware called") var token string
code := c.Query("code") HeaderAuthorization, ok := c.Request.Header["Authorization"]
if ok && len(HeaderAuthorization) >= 1 {
token = HeaderAuthorization[0]
token = strings.TrimPrefix(token, "Bearer ")
}
tok, err := GoogleDriveAppConfig.Exchange(oauth2.NoContext, code) verified, err := VerifyGoogleAccessToekn(token)
if err != nil { if err != nil || !verified {
c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error(), "message": "Login failure"}) c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error(), "message": "Verification status is " + strconv.FormatBool(verified)})
c.Abort() c.Abort()
return return
} }
_, err = GetUserInfo(tok)
if err != nil {
c.JSON(http.StatusUnauthorized, gin.H{"error": err.Error(), "message": "Login failure"})
c.Abort()
return
}
c.Set(GoogleOauth2TokenContextVariableName, tok)
fmt.Println("middleware passed")
c.Next() c.Next()
} }
} }

View File

@@ -2,6 +2,7 @@ package server
import ( import (
"encoding/json" "encoding/json"
"errors"
"io/ioutil" "io/ioutil"
"mime/multipart" "mime/multipart"
"net/http" "net/http"
@@ -26,6 +27,17 @@ type DecryptBackupInfo struct {
Passphrase string `form:"passphrase"` Passphrase string `form:"passphrase"`
} }
type GoogleTokenVerifyResponse struct {
IssuedTo string `json:"issued_to"`
Audience string `json:"audience"`
UserID string `json:"user_id"`
Scope string `json:"scope"`
ExpiresIn int64 `json:"expires_in"`
Email string `json:"email"`
VerifiedEmail bool `json:"verified_email"`
AccessType string `json:"access_type"`
}
type GoogleDriveCredentials struct { type GoogleDriveCredentials struct {
State string `form:"state"` State string `form:"state"`
Code string `form:"code"` Code string `form:"code"`
@@ -80,3 +92,24 @@ func (pu *PortwardenUser) CreateWithGoogle() error {
pu.Email = pu.GoogleUserInfo.Email pu.Email = pu.GoogleUserInfo.Email
return nil return nil
} }
func VerifyGoogleAccessToekn(access_token string) (bool, error) {
url := "https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=" + access_token
response, err := http.Get(url)
defer response.Body.Close()
if err != nil {
return false, err
}
body, err := ioutil.ReadAll(response.Body)
if err != nil {
return false, err
}
var gtvr GoogleTokenVerifyResponse
if err := json.Unmarshal(body, &gtvr); err != nil {
return false, err
}
if !gtvr.VerifiedEmail {
return false, errors.New(string(body))
}
return true, nil
}

View File

@@ -57,11 +57,16 @@ func (ps *PortwardenServer) Run() {
http.ServeFile(c.Writer, c.Request, "index.html") http.ServeFile(c.Writer, c.Request, "index.html")
}) })
ps.Router.POST("/encrypt", EncryptBackupHandler)
ps.Router.POST("/decrypt", DecryptBackupHandler) ps.Router.POST("/decrypt", DecryptBackupHandler)
ps.Router.GET("/gdrive/loginUrl", ps.GetGoogleDriveLoginURLHandler) ps.Router.GET("/gdrive/loginUrl", ps.GetGoogleDriveLoginURLHandler)
ps.Router.GET("/gdrive/login", ps.GetGoogleDriveLoginHandler) ps.Router.GET("/gdrive/login", ps.GetGoogleDriveLoginHandler)
ps.Router.Use(TokenAuthMiddleware())
ps.Router.GET("/test/TokenAuthMiddleware", func(c *gin.Context) {
c.JSON(200, "success")
})
ps.Router.POST("/encrypt", EncryptBackupHandler)
ps.Router.Run(":" + strconv.Itoa(ps.Port)) ps.Router.Run(":" + strconv.Itoa(ps.Port))
} }