Added x509 and jwt rapps
Change-Id: Ic384fcad11dcb63fe4265d3dbcff5ea17f933cfc
diff --git a/rapps/rapps-rapp-jwt-invoker.go b/rapps/rapps-rapp-jwt-invoker.go
new file mode 100644
index 0000000..de806ca
--- /dev/null
+++ b/rapps/rapps-rapp-jwt-invoker.go
@@ -0,0 +1,174 @@
+package main
+
+import (
+ "bytes"
+ "encoding/json"
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "net/http"
+ "net/url"
+ "strings"
+ "time"
+ "rapps/utils/generatejwt"
+)
+
+type Jwttoken struct {
+ Access_token string
+ Expires_in int
+ Refresh_expires_in int
+ Refresh_token string
+ Token_type string
+ Not_before_policy int
+ Session_state string
+ Scope string
+}
+
+var gatewayHost string
+var gatewayPort string
+var keycloakHost string
+var keycloakPort string
+var keycloakAlias string
+var securityEnabled string
+var useGateway string
+var role string
+var rapp string
+var methods string
+var realmName string
+var clientId string
+var healthy bool = true
+var ttime time.Time
+var jwt Jwttoken
+
+const (
+ namespace = "istio-nonrtric"
+ scope = "email"
+ client_assertion_type = "urn:ietf:params:oauth:client-assertion-type:jwt-bearer"
+)
+
+func getToken() string {
+ if ttime.Before(time.Now()) {
+ client_assertion := getClientAssertion()
+ keycloakUrl := "http://" + keycloakHost + ":" + keycloakPort + "/auth/realms/" + realmName + "/protocol/openid-connect/token"
+ resp, err := http.PostForm(keycloakUrl, url.Values{"client_assertion_type": {client_assertion_type},
+ "client_assertion": {client_assertion}, "grant_type": {"client_credentials"}, "client_id": {clientId},
+ "scope": {scope}})
+ if err != nil {
+ fmt.Println(err)
+ panic("Something wrong with the credentials or url ")
+ }
+ defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ json.Unmarshal([]byte(body), &jwt)
+ ttime = time.Now()
+ ttime = ttime.Add(time.Second * time.Duration(jwt.Expires_in))
+ }
+ return jwt.Access_token
+}
+
+func getClientAssertion() string {
+ realm := "http://" + keycloakHost + ":" + keycloakPort + "/auth/realms/" + realmName
+ clientAssertion := generatejwt.CreateJWT("/certs/client.key", "/certs/client_pub.key", "", clientId, realm)
+ return clientAssertion
+}
+
+func MakeRequest(client *http.Client, prefix string, method string, ch chan string) {
+ var service = strings.Split(prefix, "/")[1]
+ var gatewayUrl = "http://" + gatewayHost + ":" + gatewayPort
+ var token = ""
+ var jsonValue []byte = []byte{}
+ var restUrl string = ""
+
+ if securityEnabled == "true" {
+ token = getToken()
+ } else {
+ useGateway = "N"
+ }
+
+ if strings.ToUpper(useGateway) != "Y" {
+ gatewayUrl = "http://" + service + "." + namespace + ":80"
+ prefix = ""
+ }
+
+ restUrl = gatewayUrl + prefix
+
+ req, err := http.NewRequest(method, restUrl, bytes.NewBuffer(jsonValue))
+ if err != nil {
+ fmt.Printf("Got error %s", err.Error())
+ }
+ req.Header.Set("Content-type", "application/json")
+ req.Header.Set("Authorization", "Bearer "+token)
+
+ resp, err := client.Do(req)
+ if err != nil {
+ fmt.Printf("Got error %s", err.Error())
+ }
+ defer resp.Body.Close()
+ body, _ := ioutil.ReadAll(resp.Body)
+
+ respString := string(body[:])
+ if respString == "RBAC: access denied" {
+ respString += " for " + service + " " + strings.ToLower(method) + " request"
+ }
+ fmt.Printf("Received response for %s %s request - %s\n", service, strings.ToLower(method), respString)
+ ch <- prefix + "," + method
+}
+
+func health(res http.ResponseWriter, req *http.Request) {
+ if healthy {
+ res.WriteHeader(http.StatusOK)
+ res.Write([]byte("healthy"))
+ } else {
+ res.WriteHeader(http.StatusInternalServerError)
+ res.Write([]byte("unhealthy"))
+ }
+}
+
+func main() {
+ ttime = time.Now()
+ time.Sleep(1 * time.Second)
+ flag.StringVar(&gatewayHost, "gatewayHost", "istio-ingressgateway.istio-system", "Gateway Host")
+ flag.StringVar(&gatewayPort, "gatewayPort", "80", "Gateway Port")
+ flag.StringVar(&keycloakHost, "keycloakHost", "istio-ingressgateway.istio-system", "Keycloak Host")
+ flag.StringVar(&keycloakPort, "keycloakPort", "80", "Keycloak Port")
+ flag.StringVar(&useGateway, "useGateway", "Y", "Connect to services through API gateway")
+ flag.StringVar(&securityEnabled, "securityEnabled", "true", "Security is required to use this application")
+ flag.StringVar(&realmName, "realm", "jwt", "Keycloak realm")
+ flag.StringVar(&clientId, "client", "jwtprovider-cli", "Keycloak client")
+ flag.StringVar(&role, "role", "provider-viewer", "Role granted to application")
+ flag.StringVar(&rapp, "rapp", "rapp-jwt-provider", "Name of rapp to invoke")
+ flag.StringVar(&methods, "methods", "GET", "Methods to access application")
+ flag.Parse()
+
+ healthHandler := http.HandlerFunc(health)
+ http.Handle("/health", healthHandler)
+ go func() {
+ http.ListenAndServe(":9000", nil)
+ }()
+
+ client := &http.Client{
+ Timeout: time.Second * 10,
+ }
+
+ ch := make(chan string)
+ var prefixArray []string = []string{"/" + rapp}
+ var methodArray []string = []string{methods}
+ for _, prefix := range prefixArray {
+ for _, method := range methodArray {
+ go MakeRequest(client, prefix, method, ch)
+ }
+ }
+
+ ioutil.WriteFile("init.txt", []byte("Initialization done."), 0644)
+
+ for r := range ch {
+ go func(resp string) {
+ time.Sleep(10 * time.Second)
+ elements := strings.Split(resp, ",")
+ prefix := elements[0]
+ method := elements[1]
+ MakeRequest(client, prefix, method, ch)
+ }(r)
+ }
+
+}