package main import ( "crypto/tls" "encoding/json" "fmt" "io/ioutil" "net/http" "net/url" "strings" "github.com/dgrijalva/jwt-go" "github.com/labstack/echo" ) type handler struct{} type userInfo struct { Result struct { Result struct { Sshpubkeyfp []string `json:"sshpubkeyfp"` HasKeytab bool `json:"has_keytab"` Ipasshpubkey []string `json:"ipasshpubkey"` Cn []string `json:"cn"` Krbcanonicalname []string `json:"krbcanonicalname"` Krbticketflags []string `json:"krbticketflags"` MemberofGroup []string `json:"memberof_group"` HasPassword bool `json:"has_password"` Homedirectory []string `json:"homedirectory"` Nsaccountlock bool `json:"nsaccountlock"` UID []string `json:"uid"` Title []string `json:"title"` Loginshell []string `json:"loginshell"` Uidnumber []string `json:"uidnumber"` Preserved bool `json:"preserved"` Krbextradata []struct { Base64 string `json:"__base64__"` } `json:"krbextradata"` Mail []string `json:"mail"` MemberofindirectHbacrule []string `json:"memberofindirect_hbacrule"` Dn string `json:"dn"` Displayname []string `json:"displayname"` Mepmanagedentry []string `json:"mepmanagedentry"` Ipauniqueid []string `json:"ipauniqueid"` Krbloginfailedcount []string `json:"krbloginfailedcount"` Krbpwdpolicyreference []string `json:"krbpwdpolicyreference"` Krbprincipalname []string `json:"krbprincipalname"` Givenname []string `json:"givenname"` Krblastadminunlock []struct { Datetime string `json:"__datetime__"` } `json:"krblastadminunlock"` Krbpasswordexpiration []struct { Datetime string `json:"__datetime__"` } `json:"krbpasswordexpiration"` Krblastfailedauth []struct { Datetime string `json:"__datetime__"` } `json:"krblastfailedauth"` Objectclass []string `json:"objectclass"` Gidnumber []string `json:"gidnumber"` Gecos []string `json:"gecos"` Sn []string `json:"sn"` MemberofSudorule []string `json:"memberof_sudorule"` Krblastpwdchange []struct { Datetime string `json:"__datetime__"` } `json:"krblastpwdchange"` Initials []string `json:"initials"` } `json:"result"` Value string `json:"value"` Summary interface{} `json:"summary"` } `json:"result"` Version string `json:"version"` Error interface{} `json:"error"` ID int `json:"id"` Principal string `json:"principal"` } // Most of the code is taken from the echo guide // https://echo.labstack.com/cookbook/jwt func (h *handler) login(c echo.Context) error { username := c.FormValue("username") password := c.FormValue("password") _url := "https://ipa.sf.faraborddi.dc/ipa/session/login_password" method := "POST" params := url.Values{} params.Add("user", username) params.Add("password", password) payload := strings.NewReader(params.Encode()) tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } client := &http.Client{Transport: tr} req, err := http.NewRequest(method, _url, payload) audit("Recieved Login request from: " + RealIP) if err != nil { fmt.Println(err) } req.Header.Add("Referer", "https://ipa.sf.faraborddi.dc/ipa") req.Header.Add("Content-Type", "application/x-www-form-urlencoded") req.Header.Add("Accept", "text/plain") res, err := client.Do(req) cockie := res.Cookies() defer res.Body.Close() //fmt.Println(res.StatusCode) if res.StatusCode == 200 { user := getUserInfo(cockie, username) //fmt.Println(user.Result.Value) tokens, err := generateTokenPair(user) if err != nil { return err } return c.JSON(http.StatusOK, tokens) } return echo.ErrUnauthorized } func getUserInfo(cockie []*http.Cookie, username string) userInfo { url := "https://ipa.sf.faraborddi.dc/ipa/session/json" method := "POST" _json := fmt.Sprintf(` { "method": "user_show", "params": [ [ "%s" ], { "all": true, "version": "2.215" } ], "id": 0 } `, username) payload := strings.NewReader(_json) tr := &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, } client := &http.Client{Transport: tr} req, err := http.NewRequest(method, url, payload) if err != nil { fmt.Println(err) } req.Header.Add("Referer", "https://ipa.sf.faraborddi.dc/ipa") req.Header.Add("Content-Type", "application/json") req.Header.Add("Accept", "text/plain") req.Header.Add("Cookie", cockie[0].Raw) res, err := client.Do(req) defer res.Body.Close() body, err := ioutil.ReadAll(res.Body) user := userInfo{} json.Unmarshal(body, &user) //fmt.Println(user.Result.Value) //fmt.Println(user.Result.Result.MemberofGroup) return user } // This is the api to refresh tokens // Most of the code is taken from the jwt-go package's sample codes // https://godoc.org/github.com/dgrijalva/jwt-go#example-Parse--Hmac //func (h *handler) token(c echo.Context) error { // type tokenReqBody struct { // RefreshToken string `json:"refresh_token"` // } // tokenReq := tokenReqBody{} // c.Bind(&tokenReq) // // // Parse takes the token string and a function for looking up the key. // // The latter is especially useful if you use multiple keys for your application. // // The standard is to use 'kid' in the head of the token to identify // // which key to use, but the parsed token (head and claims) is provided // // to the callback, providing flexibility. // token, err := jwt.Parse(tokenReq.RefreshToken, func(token *jwt.Token) (interface{}, error) { // // Don't forget to validate the alg is what you expect: // if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok { // return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"]) // } // // // hmacSampleSecret is a []byte containing your secret, e.g. []byte("my_secret_key") // return []byte("secret"), nil // }) // // if claims, ok := token.Claims.(jwt.MapClaims); ok && token.Valid { // // Get the user record from database or // // run through your business logic to verify if the user can log in // if int(claims["sub"].(float64)) == 1 { // // newTokenPair, err := generateTokenPair() // if err != nil { // return err // } // // return c.JSON(http.StatusOK, newTokenPair) // } // // return echo.ErrUnauthorized // } // // return err //} // Most of the code is taken from the echo guide // https://echo.labstack.com/cookbook/jwt func (h *handler) private(c echo.Context) error { user := c.Get("user").(*jwt.Token) claims := user.Claims.(jwt.MapClaims) name := claims["name"].(string) return c.String(http.StatusOK, "Welcome "+name+"!") } func (h *handler) findMAC(c echo.Context) error { user := c.Get("user").(*jwt.Token) claims := user.Claims.(jwt.MapClaims) name := claims["name"].(string) return c.String(http.StatusOK, "Welcome "+name+"!") }