1
0
Fork 0
httpserver/modules/saml/account.go

120 Zeilen
2.9 KiB
Go

2021-01-09 20:39:05 +00:00
package saml
import (
"fmt"
"net/http"
"time"
"github.com/crewjam/saml"
"github.com/gin-gonic/gin"
2022-11-04 22:55:39 +00:00
"github.com/golang-jwt/jwt/v4"
2021-01-09 20:39:05 +00:00
"github.com/google/uuid"
"github.com/rs/zerolog/log"
2021-01-10 00:35:50 +00:00
"go.sebtobie.de/httpserver/auth"
"go.sebtobie.de/httpserver/constants"
2021-01-09 20:39:05 +00:00
)
var (
defaccount = &account{
data: map[constants.AccountConstant]any{
constants.AccountID: uuid.Nil,
constants.AccountAnon: true,
},
}
_ auth.AuthenticationHandler = &SAML{}
)
2021-01-09 20:39:05 +00:00
func maptoarray(m map[string]any) (output []any) {
2021-01-09 20:39:05 +00:00
for k, v := range m {
output = append(output, []any{k, v})
2021-01-09 20:39:05 +00:00
}
return
}
// Account returns the Account representation of the user
2021-01-10 00:35:50 +00:00
func (s *SAML) Account(c *gin.Context) auth.Account {
2021-01-09 20:39:05 +00:00
acc := &(*defaccount)
acc.s = s
cookie, err := c.Cookie(s.Cookiename)
if err != nil {
return acc
}
var (
claim *jwt.MapClaims
ok bool
)
token, err := jwt.ParseWithClaims(cookie, &jwt.MapClaims{}, s.signingkey)
if err != nil {
log.Debug().Err(err).Msg("Error while parsing token")
}
if claim, ok = token.Claims.(*jwt.MapClaims); ok && token.Valid {
2022-11-05 07:29:17 +00:00
log.Debug().Interface("claim", claim).Msg("Got valid token")
for key, value := range *claim {
acc.data[constants.AccountConstant(key)] = value
}
2021-01-09 20:39:05 +00:00
return acc
}
2022-11-05 07:29:17 +00:00
log.Debug().Bool("valid", token.Valid).Interface("claim", claim).Msg("problem vith token")
2021-01-09 20:39:05 +00:00
return acc
}
func (s *SAML) signingkey(token *jwt.Token) (key any, err error) {
2021-01-09 20:39:05 +00:00
if _, ok := token.Method.(*jwt.SigningMethodRSAPSS); !ok {
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
}
return &s.jwtprivatekey.PublicKey, nil
}
type account struct {
s *SAML
data map[constants.AccountConstant]any
2021-01-09 20:39:05 +00:00
}
func (a *account) Anonymous() bool {
return a.data[constants.AccountAnon].(bool)
2021-01-09 20:39:05 +00:00
}
func (a *account) Redirect(c *gin.Context) {
id := uuid.New().String()
tokenstring, err := jwttoken(jwt.MapClaims{
string(constants.AccountID): id,
string(constants.AccountAnon): true,
2021-01-09 20:39:05 +00:00
}, a.s.jwtprivatekey)
if err != nil {
log.Error().Err(err).Msg("Failed to generate the token")
c.AbortWithStatus(http.StatusInternalServerError)
return
}
c.SetCookie(a.s.Cookiename, tokenstring, int(time.Hour), "", "", true, true)
request, err := a.s.sp.MakeAuthenticationRequest(
a.s.sp.GetSSOBindingLocation(saml.HTTPRedirectBinding),
saml.HTTPRedirectBinding,
saml.HTTPRedirectBinding,
)
2021-01-09 20:39:05 +00:00
if err != nil {
c.AbortWithStatus(http.StatusInternalServerError)
}
request.ID = id
u, err := request.Redirect(c.Request.URL.String(), a.s.sp)
if err != nil {
log.Error().Err(err).Msg("Failed to create redirect")
c.AbortWithStatus(500)
return
}
log.Debug().Msgf("Leite weiter: %s", u.String())
c.Redirect(http.StatusSeeOther, u.String())
2021-01-09 20:39:05 +00:00
}
func (a *account) Get(key constants.AccountConstant) any {
2021-01-09 20:39:05 +00:00
return a.data[key]
}
func (a *account) List() []constants.AccountConstant {
var liste []constants.AccountConstant
2021-01-09 20:39:05 +00:00
for key := range a.data {
liste = append(liste, key)
}
return liste
}