<commit_before>package graylog

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

var grayLogStreams Streams

const streamNotPresentMsg = "Stream not present in Graylog!"

/*
	AUTHN & AUTHZ RELATED
*/

func createRuleForNamespace(namespaceName, streamId string){
	newRule := Rule{
		Field: "kubernetes",
		Description: "Filter Rule for this Namespace",
		Type: 6,
		Inverted: false,
		Value: fmt.Sprint("\"namespace_name\":\"%s\"", namespaceName),
	}

	if !isGrayLogActive() || isRuleAlreadyPresent(namespaceName, streamId, newRule) {
		log.Println(fmt.Sprintf("Rule for namespace %s is already present, skipping.", namespaceName))
		return
	}

	client := http.DefaultClient


	body, err := json.Marshal(newRule)

	if err != nil {
		log.Fatal(err.Error())
	}

	req, err := http.NewRequest(http.MethodPost, getGraylogBaseUrl()+"/api/streams/"+streamId+"/rules", bytes.NewBuffer(body))
	if err != nil {
		log.Fatal(err.Error())
	}

	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("Accept", "application/json")
	req.SetBasicAuth(getGraylogSessionToken(), "session")

	resp, err := client.Do(req)
	if err != nil {
		log.Println(fmt.Sprintf("Error occured while calling Graylog for RuleCreation. Error was: %s", err.Error()))
	}
	content, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err.Error())
	}

	switch resp.StatusCode {
	case 201:

	case 403:
		log.Println("Graylog communication for Rule Creation on Stream failed due to permission denied for user.")
	default:
		log.Println(fmt.Sprintf("Graylog returned a not-OK status code when creating a Rule for a stream. Code was: %d , message was: %s", resp.StatusCode, content))
	}
}

func createRoleForStreamReaders(namespaceName, streamId string) {
	if !isGrayLogActive() || isRoleAlreadyPresent(namespaceName) {
		log.Println(fmt.Sprintf("Readers role for namespace %s is already present, skipping.", namespaceName))
		return
	}

	client := http.DefaultClient

	newRole := Role{
		Name:        getRoleNameForNamespace(namespaceName),
		Description: fmt.Sprintf("Role to allow users to read from stream %s", namespaceName),
		Permissions: []string{fmt.Sprintf("streams:read:%s", streamId)},
		ReadOnly:    false,
	}

	body, err := json.Marshal(newRole)

	if err != nil {
		log.Fatal(err.Error())
	}

	req, err := http.NewRequest(http.MethodPost, getGraylogBaseUrl()+"/api/roles", bytes.NewBuffer(body))
	if err != nil {
		log.Fatal(err.Error())
	}

	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("Accept", "application/json")
	req.SetBasicAuth(getGraylogSessionToken(), "session")

	resp, err := client.Do(req)
	if err != nil {
		log.Println(fmt.Sprintf("Error occured while calling Graylog for RoleCreation. Error was: %s", err.Error()))
	}
	content, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err.Error())
	}

	switch resp.StatusCode {
	case 201:

	case 403:
		log.Println("Graylog communication for PermissionGrant on Stream failed due to permission denied for user.")
	default:
		log.Println(fmt.Sprintf("Graylog returned a not-OK status code when creating a role for a stream. Code was: %d , message was: %s", resp.StatusCode, content))
	}

}

func deleteRoleForStreamReaders(namespaceName string) {
	if !isGrayLogActive() || !isRoleAlreadyPresent(namespaceName) {
		log.Println(fmt.Sprintf("Readers role for namespace %s is already deleted, skipping.", namespaceName))
		return
	}

	client := http.DefaultClient


	req, err := http.NewRequest(http.MethodDelete, getGraylogBaseUrl()+"/api/roles/"+getRoleNameForNamespace(namespaceName), nil)
	if err != nil {
		log.Fatal(err.Error())
	}

	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("Accept", "application/json")
	req.SetBasicAuth(getGraylogSessionToken(), "session")

	resp, err := client.Do(req)
	if err != nil {
		log.Println(fmt.Sprintf("Error occured while calling Graylog for RoleCreation. Error was: %s", err.Error()))
	}
	content, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err.Error())
	}

	switch resp.StatusCode {
	case 204:
		// success
	case 403:
		log.Println("Graylog communication for PermissionGrant on Stream failed due to permission denied for user.")
	default:
		log.Println(fmt.Sprintf("Graylog returned a not-OK status code when creating a role for a stream. Code was: %d , message was: %s", resp.StatusCode, content))
	}

}

func isRuleAlreadyPresent(namespaceName, streamId string, newRule Rule) bool {
	res := false

	req, err := http.NewRequest(http.MethodGet, getGraylogBaseUrl()+"/api/streams/"+streamId+"/rules", nil)
	if err != nil {
		log.Fatal(err.Error())
	}
	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("Accept", "application/json")
	req.SetBasicAuth(getGraylogSessionToken(), "session")
	client := http.DefaultClient
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err.Error())
	}

	content, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err.Error())
	}
	switch resp.StatusCode {
	case 200:
		var rules Rules
		err := json.Unmarshal(content, &rules)
		if err != nil {
			log.Fatal(err.Error())
		}
		if rules.Total > 0 {
			for _, elem := range rules.StreamRules {
				// type 6 is "contain"
				if elem.Type == 6 && elem.Field == "kubernetes" && elem.Value == fmt.Sprint("\"namespace_name\":\"%s\"", namespaceName) {
					res = true
				}
			}

		}

	case 404:
		res = false
	default:
		log.Fatal(fmt.Sprintf("Query for Role failed with error. Statuscode was %s, message was: %s", resp.StatusCode, content))
	}
	return res
}

func isRoleAlreadyPresent(namespaceName string) bool {
	res := false

	req, err := http.NewRequest(http.MethodGet, getGraylogBaseUrl()+"/api/roles/"+getRoleNameForNamespace(namespaceName), nil)
	if err != nil {
		log.Fatal(err.Error())
	}
	req.Header.Add("Content-Type", "application/json")<commit_msg>fixed bug in rule value creation<commit_after>package graylog

import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
)

var grayLogStreams Streams

const streamNotPresentMsg = "Stream not present in Graylog!"

/*
	AUTHN & AUTHZ RELATED
*/

func createRuleForNamespace(namespaceName, streamId string){
	newRule := Rule{
		Field: "kubernetes",
		Description: "Filter Rule for this Namespace",
		Type: 6,
		Inverted: false,
		Value: fmt.Sprintf("\"namespace_name\":\"%s\"", namespaceName),
	}

	if !isGrayLogActive() || isRuleAlreadyPresent(namespaceName, streamId, newRule) {
		log.Println(fmt.Sprintf("Rule for namespace %s is already present, skipping.", namespaceName))
		return
	}

	client := http.DefaultClient


	body, err := json.Marshal(newRule)

	if err != nil {
		log.Fatal(err.Error())
	}

	req, err := http.NewRequest(http.MethodPost, getGraylogBaseUrl()+"/api/streams/"+streamId+"/rules", bytes.NewBuffer(body))
	if err != nil {
		log.Fatal(err.Error())
	}

	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("Accept", "application/json")
	req.SetBasicAuth(getGraylogSessionToken(), "session")

	resp, err := client.Do(req)
	if err != nil {
		log.Println(fmt.Sprintf("Error occured while calling Graylog for RuleCreation. Error was: %s", err.Error()))
	}
	content, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err.Error())
	}

	switch resp.StatusCode {
	case 201:

	case 403:
		log.Println("Graylog communication for Rule Creation on Stream failed due to permission denied for user.")
	default:
		log.Println(fmt.Sprintf("Graylog returned a not-OK status code when creating a Rule for a stream. Code was: %d , message was: %s", resp.StatusCode, content))
	}
}

func createRoleForStreamReaders(namespaceName, streamId string) {
	if !isGrayLogActive() || isRoleAlreadyPresent(namespaceName) {
		log.Println(fmt.Sprintf("Readers role for namespace %s is already present, skipping.", namespaceName))
		return
	}

	client := http.DefaultClient

	newRole := Role{
		Name:        getRoleNameForNamespace(namespaceName),
		Description: fmt.Sprintf("Role to allow users to read from stream %s", namespaceName),
		Permissions: []string{fmt.Sprintf("streams:read:%s", streamId)},
		ReadOnly:    false,
	}

	body, err := json.Marshal(newRole)

	if err != nil {
		log.Fatal(err.Error())
	}

	req, err := http.NewRequest(http.MethodPost, getGraylogBaseUrl()+"/api/roles", bytes.NewBuffer(body))
	if err != nil {
		log.Fatal(err.Error())
	}

	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("Accept", "application/json")
	req.SetBasicAuth(getGraylogSessionToken(), "session")

	resp, err := client.Do(req)
	if err != nil {
		log.Println(fmt.Sprintf("Error occured while calling Graylog for RoleCreation. Error was: %s", err.Error()))
	}
	content, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err.Error())
	}

	switch resp.StatusCode {
	case 201:

	case 403:
		log.Println("Graylog communication for PermissionGrant on Stream failed due to permission denied for user.")
	default:
		log.Println(fmt.Sprintf("Graylog returned a not-OK status code when creating a role for a stream. Code was: %d , message was: %s", resp.StatusCode, content))
	}

}

func deleteRoleForStreamReaders(namespaceName string) {
	if !isGrayLogActive() || !isRoleAlreadyPresent(namespaceName) {
		log.Println(fmt.Sprintf("Readers role for namespace %s is already deleted, skipping.", namespaceName))
		return
	}

	client := http.DefaultClient


	req, err := http.NewRequest(http.MethodDelete, getGraylogBaseUrl()+"/api/roles/"+getRoleNameForNamespace(namespaceName), nil)
	if err != nil {
		log.Fatal(err.Error())
	}

	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("Accept", "application/json")
	req.SetBasicAuth(getGraylogSessionToken(), "session")

	resp, err := client.Do(req)
	if err != nil {
		log.Println(fmt.Sprintf("Error occured while calling Graylog for RoleCreation. Error was: %s", err.Error()))
	}
	content, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err.Error())
	}

	switch resp.StatusCode {
	case 204:
		// success
	case 403:
		log.Println("Graylog communication for PermissionGrant on Stream failed due to permission denied for user.")
	default:
		log.Println(fmt.Sprintf("Graylog returned a not-OK status code when creating a role for a stream. Code was: %d , message was: %s", resp.StatusCode, content))
	}

}

func isRuleAlreadyPresent(namespaceName, streamId string, newRule Rule) bool {
	res := false

	req, err := http.NewRequest(http.MethodGet, getGraylogBaseUrl()+"/api/streams/"+streamId+"/rules", nil)
	if err != nil {
		log.Fatal(err.Error())
	}
	req.Header.Add("Content-Type", "application/json")
	req.Header.Add("Accept", "application/json")
	req.SetBasicAuth(getGraylogSessionToken(), "session")
	client := http.DefaultClient
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err.Error())
	}

	content, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Fatal(err.Error())
	}
	switch resp.StatusCode {
	case 200:
		var rules Rules
		err := json.Unmarshal(content, &rules)
		if err != nil {
			log.Fatal(err.Error())
		}
		if rules.Total > 0 {
			for _, elem := range rules.StreamRules {
				// type 6 is "contain"
				if elem.Type == newRule.Type && elem.Field == newRule.Field && elem.Value == newRule.Value {
					res = true
				}
			}

		}

	case 404:
		res = false
	default:
		log.Fatal(fmt.Sprintf("Query for Role failed with error. Statuscode was %s, message was: %s", resp.StatusCode, content))
	}
	return res
}

func isRoleAlreadyPresent(namespaceName string) bool {
	res := false

	req, err := http.NewRequest(http.MethodGet, getGraylogBaseUrl()+"/api/roles/"+getRoleNameForNamespace(namespaceName), nil)
	if err != nil {
		log.Fatal(err.Error())
	}
	req.Header.Add("Content-Type", "application/json")
{'fraction_non_alphanumeric': 0.14497570953720276, 'fraction_numerical': 0.004687633171396915, 'mean_word_length': 4.480616534329752, 'pattern_counts': {'":': 3, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7120510', 'n_tokens_mistral': 4189, 'n_tokens_neox': 3868, 'n_words': 981}