Commit 1a7c3844 authored by Yakubov, Sergey's avatar Yakubov, Sergey
Browse files

cleanup go src

parent d2311b6d
Loading
Loading
Loading
Loading
+0 −29
Original line number Diff line number Diff line
package discovery

import (
	"io/ioutil"
	"net/http"
	"errors"
)

type DiscoveryAPI struct {
	client  *http.Client
	baseURL string
}

func (api *DiscoveryAPI) GetMongoDbAddress() (string, error) {
	resp, err := api.client.Get(api.baseURL + "/asapo-mongodb")
	if err != nil {
		return "", err
	}
	if resp.StatusCode!=http.StatusOK {
		return "", errors.New("cannot get mongodb server, status: "+resp.Status)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	return string(body), err
}

func CreateDiscoveryService(client *http.Client,uri string) DiscoveryAPI{
	return DiscoveryAPI{client, uri}
}
 No newline at end of file
+0 −10
Original line number Diff line number Diff line
module asapo_common

go 1.16

require (
	github.com/dgrijalva/jwt-go v3.2.0+incompatible
	github.com/gorilla/mux v1.8.0
	github.com/sirupsen/logrus v1.8.0
	github.com/stretchr/testify v1.7.0
)
+0 −24
Original line number Diff line number Diff line
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/magefile/mage v1.10.0 h1:3HiXzCUY12kh9bIuyXShaVe529fJfyqoVM42o/uom2g=
github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/sirupsen/logrus v1.8.0 h1:nfhvjKcUMhBMVqbKHJlk5RPrrfYr/NMo3692g0dwfWU=
github.com/sirupsen/logrus v1.8.0/go.mod h1:4GuYW9TZmE769R5STWrRakJc4UqQ3+QQ95fyz7ENv1A=
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+0 −38
Original line number Diff line number Diff line
package structs

type FolderTokenTokenExtraClaim struct {
	RootFolder   string
	SecondFolder string
}

type AccessTokenExtraClaim struct {
	AccessTypes []string
}

type IntrospectTokenRequest struct {
	Token string
}

type IntrospectTokenResponse struct {
	Sub         string
	AccessTypes []string
}

type IssueTokenRequest struct {
	Subject     map[string]string
	DaysValid   int
	AccessTypes []string
}

type IssueTokenResponse struct {
	Token       string
	Sub         string
	AccessTypes []string
	Expires     string
}

type FileMessage struct {
	Endpoint string
	Filename string
	Token    string
}
+0 −292
Original line number Diff line number Diff line
package utils

import (
	"context"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"errors"
	"github.com/dgrijalva/jwt-go"
	"net/http"
	"net/url"
	"strings"
	"time"
)

type Auth interface {
	GenerateToken(...interface{}) (string, error)
	ProcessAuth(http.HandlerFunc, string) http.HandlerFunc
	Name() string
	CheckAndGetContent(token string, extraClaims interface{}, payload ...interface{}) (*jwt.StandardClaims,error)
}

func SubjectFromBeamtime(bt string)string {
	return "bt_"+bt
}

func SubjectFromBeamline(bl string)string {
	return "bl_"+bl
}


func (a *JWTAuth) Name() string {
	return "Bearer"
}


func stripURL(u *url.URL) string {
	s := u.Path + u.RawQuery
	s = strings.Replace(s, "/", "", -1)
	s = strings.Replace(s, "?", "", -1)
	return s

}

func SplitAuthToken(s string) (authType, token string, err error) {
	keys := strings.Split(s, " ")

	if len(keys) != 2 {
		err = errors.New("authorization error - wrong token")
		return
	}

	authType = keys[0]
	token = keys[1]
	return
}

func ExtractAuthInfo(r *http.Request) (authType, token string, err error) {

	t := r.Header.Get("Authorization")

	if t != "" {
		return SplitAuthToken(t)
	}

	cookie, err := r.Cookie("Authorization")
	if err == nil {
		return SplitAuthToken(cookie.Value)
	}

	err = errors.New("no authorization info")
	return

}

type CustomClaims struct {
	jwt.StandardClaims
	ExtraClaims interface{}
}

func (claim *CustomClaims) SetExpiration(duration time.Duration){
	if duration > 0 {
		claim.ExpiresAt = time.Now().Add(duration).Unix()
	}
}

type JWTAuth struct {
	Key string
}

func NewJWTAuth(key string) *JWTAuth {
	a := JWTAuth{key}
	return &a
}

func (t JWTAuth) GenerateToken(val ...interface{}) (string, error) {
	if len(val) != 1 {
		return "", errors.New("No claims")
	}
	claims, ok := val[0].(*CustomClaims)
	if !ok {
		return "", errors.New("Wrong claims")
	}

	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
	tokenString, err := token.SignedString([]byte(t.Key))

	if err != nil {
		return "", err
	}

	return tokenString, nil
}

func (a *JWTAuth)ProcessAuth(fn http.HandlerFunc, payload string) http.HandlerFunc {
	// payload ignored
	return ProcessJWTAuth(fn,a.Key)
}

func ProcessJWTAuth(fn http.HandlerFunc, key string) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if (r.RequestURI == "/health-check") { // always allow /health-check request
			fn(w,r)
			return
		}
		authType, token, err := ExtractAuthInfo(r)

		if err != nil {
			http.Error(w, err.Error(), http.StatusUnauthorized)
			return
		}

		ctx := r.Context()

		if authType == "Bearer" {
			if claims, ok := CheckJWTToken(token, key); !ok {
				http.Error(w, "Authorization error - token does not match", http.StatusUnauthorized)
				return
			} else {
				ctx = context.WithValue(ctx, "TokenClaims", claims)
			}
		} else {
			http.Error(w, "Authorization error - wrong auth type", http.StatusUnauthorized)
			return
		}
		fn(w, r.WithContext(ctx))
	}
}

func (a *JWTAuth) CheckAndGetContent(token string, extraClaims interface{}, payload ...interface{}) (claims *jwt.StandardClaims, err error) {
	// payload ignored
	c, ok := CheckJWTToken(token,a.Key)
	if !ok {
		return nil,errors.New("wrong or expired JWT token")
	}
	claim,ok  := c.(*CustomClaims)
	if !ok {
		return nil,errors.New("cannot get CustomClaims")
	}

	if extraClaims!=nil {
		err = MapToStruct(claim.ExtraClaims.(map[string]interface{}), extraClaims)
	}
	return &claim.StandardClaims,err
}


func CheckJWTToken(token, key string) (jwt.Claims, bool) {

	if token == "" {
		return nil, false
	}

	t, err := jwt.ParseWithClaims(token, &CustomClaims{}, func(token *jwt.Token) (interface{}, error) {
		return []byte(key), nil
	})

	if err == nil && t.Valid {
		return t.Claims, true
	}

	return nil, false
}

func JobClaimFromContext(r *http.Request, customClaim **CustomClaims, val interface{}) error {
	c := r.Context().Value("TokenClaims")

	if c == nil {
		return errors.New("Empty context")
	}

	claim,ok  := c.(*CustomClaims)
	if !ok {
		return errors.New("cannot get CustomClaims")
	}

	if customClaim!=nil {
		*customClaim = claim
	}

	return MapToStruct(claim.ExtraClaims.(map[string]interface{}), val)
}

type HMACAuth struct {
	Key string
}

func NewHMACAuth(key string) *HMACAuth {
	a := HMACAuth{key}
	return &a
}

func (a *HMACAuth) Name() string {
	return "HMAC-SHA-256"
}


func generateHMACToken(value string, key string) string {
	mac := hmac.New(sha256.New, []byte(key))
	mac.Write([]byte(value))

	return base64.URLEncoding.EncodeToString(mac.Sum(nil))
	}

func (h HMACAuth) GenerateToken(val ...interface{}) (string, error) {
	if len(val) != 1 {
		return "", errors.New("Wrong claims")
	}
	value, ok := val[0].(*string)
	if !ok {
		return "", errors.New("Wrong claims")
	}

	sha := generateHMACToken(*value, h.Key)

	return sha, nil
}

func (a *HMACAuth)ProcessAuth(fn http.HandlerFunc, payload string) http.HandlerFunc {
	return ProcessHMACAuth(fn,payload,a.Key)
}

func ProcessHMACAuth(fn http.HandlerFunc, payload, key string) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {

		authType, token, err := ExtractAuthInfo(r)

		if err != nil {
			http.Error(w, err.Error(), http.StatusUnauthorized)
			return
		}
		if authType == "HMAC-SHA-256" {
			if !CheckHMACToken(payload, token, key) {
				http.Error(w, "Internal authorization error - token does not match", http.StatusUnauthorized)
				return
			}
		} else {
			http.Error(w, "Internal authorization error - wrong auth type", http.StatusUnauthorized)
			return
		}
		fn(w, r)
	}
}

func (a *HMACAuth) CheckAndGetContent(token string, _ interface{}, payload ...interface{}) (*jwt.StandardClaims,error) {
	if len(payload) != 1 {
		return nil,errors.New("wrong payload")
	}
	value, ok := payload[0].(string)
	if !ok {
		return nil,errors.New("wrong payload")
	}

	ok = CheckHMACToken(token,value,a.Key)
	if !ok {
		return nil,errors.New("wrong HMAC token")
	}
	claim := jwt.StandardClaims{}
	claim.Subject = value
	return &claim,nil

}

func CheckHMACToken(value string, token, key string) bool {

	if token == "" {
		return false
	}

	generated_token := generateHMACToken(value, key)
	return token == generated_token
}
Loading