| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 | package mainimport (	"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/jwtfunc (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())	client := &http.Client{}	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/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()		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)	client := &http.Client{}	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)	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--Hmacfunc (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/jwtfunc (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+"!")}
 |