Clients go nemergent

Merge request reports

Loading
+468 −0
Changes for cmd/go_capif_admin_client/admin_client.go: 468 added lines, 0 removed lines.
Original line number Diff line number Diff line
/*
*  Copyright (C) 2024, Nemergent Solutions SL
 */

package main

import (
	"GolangCapifApis/internal/CapifApiInvokerManagement"
	"GolangCapifApis/internal/CapifApiProviderManagement"
	"bufio"
	"bytes"
	"crypto/tls"
	"crypto/x509"
	"encoding/json"
	"flag"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strings"
	"syscall"

	"github.com/turret-io/go-menu/menu"
	"golang.org/x/term"
	"gopkg.in/yaml.v2"
)

type Config struct {
	CAPIF struct {
		CapifUserUsername string `yaml:"capif_user_username"`
		CapifUserPassword string `yaml:"capif_user_password"`
		RegisterHostname  string `yaml:"register_hostname"`
		RegisterPort      string `yaml:"register_port"`
		CapifcoreHostname string `yaml:"capifcore_hostname"`
		CapifcorePort     string `yaml:"capifcore_port"`
	} `yaml:"capif"`
}

type getAuthDetails struct {
	AcessToken          *string `json:"access_token"`
	CaRoot              *string `json:"ca_root"`
	CcfApiOnboardingURL *string `json:"ccf_api_onboarding_url"`
	CcfDiscoverURL      *string `json:"ccf_discover_url"`
	CcfOnboardingURL    *string `json:"ccf_onboarding_url"`
	CcfPublishURL       *string `json:"ccf_publish_url"`
	CcfSecurityURL      *string `json:"ccf_security_url"`
	Message             *string `json:"message"`
}

type loginDetails struct {
	AccessToken  *string `json:"access_token"`
	RefreshToken *string `json:"refresh_token"`
}

type createUserDetails struct {
	Username    string `json:"username"`
	Password    string `json:"password"`
	Enterprise  string `json:"enterprise"`
	Country     string `json:"country"`
	Email       string `json:"email"`
	Purpose     string `json:"purpose"`
	Phone       string `json:"phone_number,omitempty"`
	Web         string `json:"company_web,omitempty"`
	Description string `json:"description,omitempty"`
}

var accessToken string = ""
var refreshToken string = ""
var providerIds []string
var invokerIds []string
var getAuthDet *getAuthDetails
var apiProvEnDet *CapifApiProviderManagement.APIProviderEnrolmentDetails
var apiProvFuncAEFDet CapifApiProviderManagement.APIProviderFunctionDetails
var apiProvFuncAMFDet CapifApiProviderManagement.APIProviderFunctionDetails
var apiProvFuncAPFDet CapifApiProviderManagement.APIProviderFunctionDetails
var apiInvEnDet *CapifApiInvokerManagement.APIInvokerEnrolmentDetails

var cfg Config

func main() {

	var configFilePath string
	flag.StringVar(&configFilePath, "f", "config.yaml", "Config file path")
	flag.Parse()
	readConfigFile(&cfg, configFilePath)

	commandOptions := []menu.CommandOption{
		menu.CommandOption{"login", "Login as administrator in CAPIF and obtain the tokens required for admin operations", login},
		menu.CommandOption{"refreshAdminToken", "Refresh the tokend of the administrator user", refreshAdminToken},
		menu.CommandOption{"createUser", "Register a new user into CAPIF", createUser},
		menu.CommandOption{"getUsers", "List information of all te users registered in CAPIF", getUsers},
		menu.CommandOption{"deleteUser", "Remove a previously registered user from CAPIF", deleteUser},
		//menu.CommandOption{"getProviders", "Runs getProviders - WIP", getProviders},
		//menu.CommandOption{"getInvokers", "Runs getInvokers - WIP", getInvokers},
	}
	menuOptions := menu.NewMenuOptions("'menu' for help > ", 0)

	menu := menu.NewMenu(commandOptions, menuOptions)
	menu.Start()

}

func login(args ...string) error {

	reader := bufio.NewReader(os.Stdin)
	//Ask for username
	var username string = "username"
	fmt.Println("Insert username for login: ")
	username, _ = reader.ReadString('\n')
	username = strings.Replace(username, "\n", "", -1)
	//Ask for password
	var passwd string = "password"
	fmt.Println("Insert password for login: ")
	bytePasswd, _ := term.ReadPassword(int(syscall.Stdin))
	passwd = string(bytePasswd)
	fmt.Println("Username inserted for login is: ", username)
	fmt.Println("Password inserted for login is: ", passwd)

	//Send request to /login endpoint with authorization header using username and password
	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
		},
	}
	var registerUrl string = "https://" + cfg.CAPIF.RegisterHostname + ":" + cfg.CAPIF.RegisterPort + "/login"
	fmt.Println("registerUrl: ", registerUrl)
	//req, err := http.NewRequest("POST", "https://register:8084/login", nil)
	req, err := http.NewRequest("POST", registerUrl, nil)
	req.SetBasicAuth(username, passwd)
	resp, err := client.Do(req)
	fmt.Println("Status code: ", resp.StatusCode)
	if err != nil {
		fmt.Println(err)
		return nil
	}

	//Decode response and save all parameters
	body, error := io.ReadAll(resp.Body)
	if error != nil {
		fmt.Println(error)
	}
	fmt.Println(string(body))
	defer resp.Body.Close()

	var loginDet loginDetails
	if err := json.Unmarshal(body, &loginDet); err != nil {
		fmt.Println("Can not unmarshal JSON")
	} else {
		accessToken = *loginDet.AccessToken
		refreshToken = *loginDet.RefreshToken
	}

	return nil
}

func refreshAdminToken(args ...string) error {

	//Send request to /refresh endpoint with authorization header using refreshToken
	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
		},
	}
	var registerUrl string = "https://" + cfg.CAPIF.RegisterHostname + ":" + cfg.CAPIF.RegisterPort + "/refresh"
	fmt.Println("registerUrl: ", registerUrl)
	//req, err := http.NewRequest("POST", "https://register:8084/login", nil)
	req, err := http.NewRequest("POST", registerUrl, nil)
	var bearer string = "Bearer " + refreshToken
	req.Header.Add("Authorization", bearer)

	resp, err := client.Do(req)
	fmt.Println("Status code: ", resp.StatusCode)
	if err != nil {
		fmt.Println(err)
		return nil
	}

	//Decode response and save all parameters
	body, error := io.ReadAll(resp.Body)
	if error != nil {
		fmt.Println(error)
	}
	fmt.Println(string(body))
	defer resp.Body.Close()

	if resp.StatusCode == 200 {
		var loginDet loginDetails
		if err := json.Unmarshal(body, &loginDet); err != nil {
			fmt.Println("Can not unmarshal JSON")
		} else {
			accessToken = *loginDet.AccessToken
		}
	}

	return nil
}

func createUser(args ...string) error {

	createUserDet := getCreateUserDetails()
	body, error := json.Marshal(createUserDet)
	if error != nil {
		panic(error)
	}
	//Send request to /createUser endpoint with Bearer indicating the access token of the admin user
	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
		},
	}
	var registerUrl string = "https://" + cfg.CAPIF.RegisterHostname + ":" + cfg.CAPIF.RegisterPort + "/createUser"
	//req, err := http.NewRequest("POST", "https://register:8084/createUser", bytes.NewBuffer(body))
	req, err := http.NewRequest("POST", registerUrl, bytes.NewBuffer(body))
	var bearer string = "Bearer " + accessToken
	req.Header.Add("Authorization", bearer)
	req.Header.Add("Content-type", "application/json")
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}

	body, error = io.ReadAll(resp.Body)
	if error != nil {
		fmt.Println(error)
	}
	fmt.Println(string(body))
	defer resp.Body.Close()

	fmt.Println("Output of createUser")
	return nil
}

func getUsers(args ...string) error {

	//Send request to /getUsers endpoint with authorization header set to admin access token
	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
		},
	}
	var registerUrl string = "https://" + cfg.CAPIF.RegisterHostname + ":" + cfg.CAPIF.RegisterPort + "/getUsers"
	req, err := http.NewRequest("GET", registerUrl, nil)
	var bearer string = "Bearer " + accessToken
	req.Header.Add("Authorization", bearer)
	req.Header.Add("Content-type", "application/json")
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}

	//Decode response and save all parameters
	body, error := io.ReadAll(resp.Body)
	if error != nil {
		fmt.Println(error)
	}
	fmt.Println(string(body))
	defer resp.Body.Close()

	fmt.Println("Output of getUsers")
	return nil
}

// TODO - Result as of 11/07/2024 - Unauthorized, User role must be superadmin
func getInvokers(args ...string) error {

	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
		},
	}
	var registerUrl string = "https://" + cfg.CAPIF.RegisterHostname + "/helper/getInvokers"
	req, err := http.NewRequest("GET", registerUrl, nil)
	var bearer string = "Bearer " + accessToken
	req.Header.Add("Authorization", bearer)
	req.Header.Add("Content-type", "application/json")
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}

	//Decode response and save all parameters
	body, error := io.ReadAll(resp.Body)
	if error != nil {
		fmt.Println(error)
	}
	fmt.Println(string(body))
	defer resp.Body.Close()

	fmt.Println("Output of getInvokers")
	return nil
}

func deleteUser(args ...string) error {

	//Send request to /deleteUser endpoint with Bearer indicating the access token of the admin user
	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
		},
	}

	//TODO - Request uuid or take it from somewhere - Save uuid and username when creating it?
	reader := bufio.NewReader(os.Stdin)
	//Ask for user uuid
	var userUuid string = "uuid"
	fmt.Println("Insert user uuid for user to delete: ")
	userUuid, _ = reader.ReadString('\n')
	userUuid = strings.Replace(userUuid, "\n", "", -1)

	var registerUrl string = "https://" + cfg.CAPIF.RegisterHostname + ":" + cfg.CAPIF.RegisterPort + "/deleteUser/" + userUuid
	//url := "https://register:8084/deleteUser/" + userUuid
	req, err := http.NewRequest("DELETE", registerUrl, nil)
	var bearer string = "Bearer " + accessToken
	req.Header.Add("Authorization", bearer)
	req.Header.Add("Content-type", "application/json")
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}

	body, error := io.ReadAll(resp.Body)
	if error != nil {
		fmt.Println(error)
	}
	fmt.Println(string(body))
	defer resp.Body.Close()

	fmt.Println("Output of deleteUser")

	return nil
}

func getCreateUserDetails() createUserDetails {
	reader := bufio.NewReader(os.Stdin)
	var createUserDet createUserDetails

	//Ask for username
	var username string = "username"
	fmt.Println("Insert username for new user: ")
	username, _ = reader.ReadString('\n')
	username = strings.Replace(username, "\n", "", -1)
	createUserDet.Username = username
	//Ask for username
	var password string = "password"
	fmt.Println("Insert password for new user: ")
	password, _ = reader.ReadString('\n')
	password = strings.Replace(password, "\n", "", -1)
	createUserDet.Password = password
	//Ask for username
	var enterprise string = "enterprise"
	fmt.Println("Insert enterprise for new user: ")
	enterprise, _ = reader.ReadString('\n')
	enterprise = strings.Replace(enterprise, "\n", "", -1)
	createUserDet.Enterprise = enterprise
	//Ask for username
	var country string = "country"
	fmt.Println("Insert country for new user: ")
	country, _ = reader.ReadString('\n')
	country = strings.Replace(country, "\n", "", -1)
	createUserDet.Country = country
	//Ask for username
	var email string = "email"
	fmt.Println("Insert email for new user: ")
	email, _ = reader.ReadString('\n')
	email = strings.Replace(email, "\n", "", -1)
	createUserDet.Email = email
	//Ask for username
	var purpose string = "purpose"
	fmt.Println("Insert purpose for new user: ")
	purpose, _ = reader.ReadString('\n')
	purpose = strings.Replace(purpose, "\n", "", -1)
	createUserDet.Purpose = purpose

	return createUserDet
}

// TODO - Result as of 11/07/2024 - Unauthorized, User role must be superadmin
func getProviders(args ...string) error {

	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				InsecureSkipVerify: true,
			},
		},
	}
	var registerUrl string = "https://" + cfg.CAPIF.RegisterHostname + "/helper/getProviders"
	//req, err := http.NewRequest("GET", "https://register/helper/getProviders", nil)
	req, err := http.NewRequest("GET", registerUrl, nil)
	var bearer string = "Bearer " + accessToken
	req.Header.Add("Authorization", bearer)
	req.Header.Add("Content-type", "application/json")
	resp, err := client.Do(req)
	if err != nil {
		log.Fatal(err)
	}

	//Decode response and save all parameters
	body, error := io.ReadAll(resp.Body)
	if error != nil {
		fmt.Println(error)
	}
	fmt.Println(string(body))
	defer resp.Body.Close()

	fmt.Println("Output of getProviders")
	return nil
}

func httpClientCACert() *http.Client {

	// Get the SystemCertPool, continue with an empty pool on error
	rootCAs, _ := x509.SystemCertPool()
	if rootCAs == nil {
		rootCAs = x509.NewCertPool()
	}

	// Read in the cert file
	certs, err := os.ReadFile("ca_root.crt")
	if err != nil {
		log.Fatalf("Failed to append ca_root.crt to RootCAs: %v", err)
	}

	// Append our cert to the system pool
	if ok := rootCAs.AppendCertsFromPEM(certs); !ok {
		log.Println("No certs appended, using system certs only")
	}
	client := &http.Client{
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{
				RootCAs: rootCAs,
			},
		},
	}

	return client
}

func readConfigFile(cfg *Config, configFilePath string) {

	f, err := os.Open(configFilePath)
	if err != nil {
		fmt.Printf("Unable to open configution file in path (%s): %v \n", configFilePath, err)
		os.Exit(2)
	}
	defer f.Close()

	decoder := yaml.NewDecoder(f)
	err = decoder.Decode(cfg)
	if err != nil {
		fmt.Printf("Unable to decode configution file \n")
		os.Exit(2)
	}

}
+815 −0

File added.

Preview size limit exceeded, changes collapsed.

+657 −0

File added.

Preview size limit exceeded, changes collapsed.

+98 −0
Changes for internal/CapifApiInvokerManagement/.openapi-generator/FILES: 98 added lines, 0 removed lines.
Original line number Diff line number Diff line
.gitignore
.openapi-generator-ignore
.travis.yml
README.md
api/openapi.yaml
api_default.go
api_individual_api_invoker_enrolment_details.go
client.go
configuration.go
docs/APIInvokerEnrolmentDetails.md
docs/APIInvokerEnrolmentDetailsPatch.md
docs/APIList.md
docs/AefLocation.md
docs/AefProfile.md
docs/CivicAddress.md
docs/CommunicationType.md
docs/CustomOperation.md
docs/DataFormat.md
docs/DefaultAPI.md
docs/EllipsoidArc.md
docs/GADShape.md
docs/GeographicArea.md
docs/GeographicalCoordinates.md
docs/IndividualAPIInvokerEnrolmentDetailsAPI.md
docs/InterfaceDescription.md
docs/InvalidParam.md
docs/Local2dPointUncertaintyEllipse.md
docs/Local3dPointUncertaintyEllipsoid.md
docs/LocalOrigin.md
docs/OnboardingInformation.md
docs/OnboardingNotification.md
docs/Operation.md
docs/Point.md
docs/PointAltitude.md
docs/PointAltitudeUncertainty.md
docs/PointUncertaintyCircle.md
docs/PointUncertaintyEllipse.md
docs/Polygon.md
docs/ProblemDetails.md
docs/Protocol.md
docs/PublishedApiPath.md
docs/RelativeCartesianLocation.md
docs/Resource.md
docs/SecurityMethod.md
docs/ServiceAPIDescription.md
docs/ShareableInformation.md
docs/SupportedGADShapes.md
docs/UncertaintyEllipse.md
docs/UncertaintyEllipsoid.md
docs/Version.md
docs/WebsockNotifConfig.md
git_push.sh
go.mod
go.sum
model_aef_location.go
model_aef_profile.go
model_api_invoker_enrolment_details.go
model_api_invoker_enrolment_details_patch.go
model_api_list.go
model_civic_address.go
model_communication_type.go
model_custom_operation.go
model_data_format.go
model_ellipsoid_arc.go
model_gad_shape.go
model_geographic_area.go
model_geographical_coordinates.go
model_interface_description.go
model_invalid_param.go
model_local2d_point_uncertainty_ellipse.go
model_local3d_point_uncertainty_ellipsoid.go
model_local_origin.go
model_onboarding_information.go
model_onboarding_notification.go
model_operation.go
model_point.go
model_point_altitude.go
model_point_altitude_uncertainty.go
model_point_uncertainty_circle.go
model_point_uncertainty_ellipse.go
model_polygon.go
model_problem_details.go
model_protocol.go
model_published_api_path.go
model_relative_cartesian_location.go
model_resource.go
model_security_method.go
model_service_api_description.go
model_shareable_information.go
model_supported_gad_shapes.go
model_uncertainty_ellipse.go
model_uncertainty_ellipsoid.go
model_version.go
model_websock_notif_config.go
response.go
test/api_default_test.go
test/api_individual_api_invoker_enrolment_details_test.go
utils.go
+1 −0
Changes for internal/CapifApiInvokerManagement/.openapi-generator/VERSION: 1 added line, 0 removed lines.
Original line number Diff line number Diff line
7.6.0
Loading
Loading