BAHAMAS
This commit is contained in:
@@ -1,18 +1,16 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"oc-auth/infrastructure"
|
||||
auth_connectors "oc-auth/infrastructure/auth_connector"
|
||||
"oc-auth/infrastructure/claims"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
oclib "cloud.o-forge.io/core/oc-lib"
|
||||
model "cloud.o-forge.io/core/oc-lib/models/peer"
|
||||
"cloud.o-forge.io/core/oc-lib/static"
|
||||
beego "github.com/beego/beego/v2/server/web"
|
||||
)
|
||||
|
||||
@@ -78,22 +76,6 @@ func (o *OAuthController) LoginLDAP() {
|
||||
o.ServeJSON()
|
||||
}
|
||||
|
||||
// @Title Claims
|
||||
// @Description enrich token with claims
|
||||
// @Param body body models.Token true "The token info"
|
||||
// @Success 200 {string}
|
||||
// @router /claims [post]
|
||||
func (o *OAuthController) Claims() {
|
||||
// enrich token with claims
|
||||
var res claims.Claims
|
||||
json.Unmarshal(o.Ctx.Input.CopyBody(100000), &res)
|
||||
claims := res.Session.IDToken["id_token_claims"].(map[string]interface{})
|
||||
userName := claims["sub"].(string)
|
||||
_, loc := static.GetMyLocalJsonPeer()
|
||||
o.Data["json"] = infrastructure.GetClaims().AddClaimsToToken(userName, loc["url"].(string))
|
||||
o.ServeJSON()
|
||||
}
|
||||
|
||||
// @Title Introspection
|
||||
// @Description introspect token
|
||||
// @Param body body models.Token true "The token info"
|
||||
@@ -126,6 +108,7 @@ func (o *OAuthController) Introspect() {
|
||||
} else {
|
||||
reqToken = splitToken[1]
|
||||
}
|
||||
|
||||
token, err := infrastructure.GetAuthConnector().Introspect(reqToken)
|
||||
if err != nil || !token {
|
||||
o.Data["json"] = err
|
||||
@@ -134,37 +117,55 @@ func (o *OAuthController) Introspect() {
|
||||
o.ServeJSON()
|
||||
}
|
||||
|
||||
var whitelist = []string{
|
||||
"/login",
|
||||
"/refresh",
|
||||
"/introspect",
|
||||
}
|
||||
|
||||
// @Title AuthForward
|
||||
// @Description auth forward
|
||||
// @Param Authorization header string false "auth token"
|
||||
// @Param body body models.workflow true "The workflow content"
|
||||
// @Success 200 {string}
|
||||
// @router /forward [get]
|
||||
func (o *OAuthController) InternalAuthForward() {
|
||||
fmt.Println("InternalAuthForward")
|
||||
reqToken := o.Ctx.Request.Header.Get("Authorization")
|
||||
if reqToken == "" {
|
||||
for _, w := range whitelist {
|
||||
if strings.Contains(o.Ctx.Request.Header.Get("X-Forwarded-Uri"), w) {
|
||||
o.Ctx.ResponseWriter.WriteHeader(200)
|
||||
o.ServeJSON()
|
||||
return
|
||||
}
|
||||
}
|
||||
o.Ctx.ResponseWriter.WriteHeader(401)
|
||||
o.ServeJSON()
|
||||
return
|
||||
}
|
||||
splitToken := strings.Split(reqToken, "Bearer ")
|
||||
if len(splitToken) < 2 {
|
||||
reqToken = ""
|
||||
} else {
|
||||
reqToken = splitToken[1]
|
||||
}
|
||||
origin, publicKey, external := o.extractOrigin()
|
||||
if reqToken != "" && !o.checkAuthForward(reqToken, publicKey) && origin != "" {
|
||||
fmt.Println("Unauthorized", origin, reqToken)
|
||||
origin, publicKey, _ := o.extractOrigin()
|
||||
if !infrastructure.GetAuthConnector().CheckAuthForward( //reqToken != "" &&
|
||||
reqToken, publicKey, origin,
|
||||
o.Ctx.Request.Header.Get("X-Forwarded-Method"),
|
||||
o.Ctx.Request.Header.Get("X-Forwarded-Uri")) && origin != "" && publicKey != "" {
|
||||
o.Ctx.ResponseWriter.WriteHeader(401)
|
||||
o.ServeJSON()
|
||||
return
|
||||
}
|
||||
token, err := infrastructure.GetAuthConnector().Introspect(reqToken, &http.Cookie{
|
||||
isToken, err := infrastructure.GetAuthConnector().Introspect(reqToken, &http.Cookie{
|
||||
Name: "csrf_token",
|
||||
Value: o.XSRFToken(),
|
||||
}) // may be a problem... we should check if token is valid on our side
|
||||
// prefers a refresh token call
|
||||
if err != nil || external {
|
||||
fmt.Println("Unauthorized 2", err, external) // error
|
||||
fmt.Println("InternalAuthForward", isToken, err)
|
||||
if err != nil || !isToken {
|
||||
o.Ctx.ResponseWriter.WriteHeader(401)
|
||||
} else if token && !external { // redirect to login
|
||||
o.Data["json"] = token
|
||||
}
|
||||
o.ServeJSON()
|
||||
}
|
||||
@@ -176,50 +177,25 @@ func (o *OAuthController) extractOrigin() (string, string, bool) {
|
||||
if origin == "" {
|
||||
origin = o.Ctx.Request.Header.Get("Origin")
|
||||
}
|
||||
idLoc, loc := static.GetMyLocalJsonPeer()
|
||||
searchStr := origin
|
||||
r := regexp.MustCompile("(:[0-9]+)")
|
||||
t := r.FindString(searchStr)
|
||||
if t != "" {
|
||||
searchStr = strings.Replace(searchStr, t, "", -1)
|
||||
}
|
||||
peer := oclib.Search(nil, searchStr, oclib.LibDataEnum(oclib.PEER))
|
||||
if peer.Code != 200 || len(peer.Data) == 0 { // TODO: add state of partnership
|
||||
return "", "", external
|
||||
}
|
||||
p := peer.Data[0].(*model.Peer)
|
||||
publicKey = p.PublicKey
|
||||
origin = p.Url
|
||||
if origin != "" { // is external
|
||||
peer := oclib.Search(nil, origin, oclib.LibDataEnum(oclib.PEER))
|
||||
if peer.Code != 200 {
|
||||
return "", "", external
|
||||
}
|
||||
p := peer.Data[0]
|
||||
if strings.Contains(origin, "localhost") || strings.Contains(origin, "127.0.0.1") || idLoc == p.GetID() {
|
||||
if strings.Contains(origin, "localhost") || strings.Contains(origin, "127.0.0.1") || p.State == model.SELF {
|
||||
external = false
|
||||
}
|
||||
publicKey = p.(*model.Peer).PublicKey
|
||||
} else {
|
||||
external = false
|
||||
publicKey = loc["public_key"].(string)
|
||||
}
|
||||
return origin, publicKey, external
|
||||
}
|
||||
|
||||
func (o *OAuthController) checkAuthForward(reqToken string, publicKey string) bool {
|
||||
bytes, err := base64.StdEncoding.DecodeString(reqToken) // Converting data
|
||||
if err != nil {
|
||||
fmt.Println("Failed to Decode secret", err)
|
||||
return false
|
||||
}
|
||||
var decodedToken map[string]interface{}
|
||||
err = json.Unmarshal(bytes, &decodedToken)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to parse secret", err)
|
||||
return false
|
||||
} else if decodedToken["session"] != nil {
|
||||
host := o.Ctx.Request.Header.Get("X-Forwarded-Host")
|
||||
method := o.Ctx.Request.Header.Get("X-Forwarded-Method")
|
||||
forward := o.Ctx.Request.Header.Get("X-Forwarded-Uri")
|
||||
if forward == "" || method == "" {
|
||||
fmt.Println("Forwarded headers are missing")
|
||||
return false
|
||||
}
|
||||
// ask keto for permission is in claims
|
||||
ok, err := infrastructure.GetClaims().DecodeClaimsInToken(
|
||||
host, method, forward, decodedToken["session"].(map[string]interface{}), publicKey)
|
||||
if err != nil {
|
||||
fmt.Println("Failed to decode claims", err)
|
||||
}
|
||||
return ok
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user