From bb86214d7b5433da3fbed8fb22c357606b82f17f Mon Sep 17 00:00:00 2001
From: Claudio Scafuri <claudio.scafuri@elettra.eu>
Date: Thu, 1 Oct 2020 16:10:35 +0200
Subject: [PATCH] cleaner handling of host privileges

---
 src/TwinApuId.cpp | 119 ++++++++++++++++++----------------------------
 src/TwinApuId.h   |   4 +-
 2 files changed, 48 insertions(+), 75 deletions(-)

diff --git a/src/TwinApuId.cpp b/src/TwinApuId.cpp
index 794a357..819af3b 100644
--- a/src/TwinApuId.cpp
+++ b/src/TwinApuId.cpp
@@ -690,18 +690,12 @@ void TwinApuId::write_UserPositionLow(Tango::WAttribute &attr)
 	/*----- PROTECTED REGION ID(TwinApuId::write_UserPositionLow) ENABLED START -----*/
 
 	//check privileges
-	int priv=caller_privileges();
-	if (priv < AUTHORIZED){
-		INFO_STREAM << "UserPositionLow from "<< clientAddress <<" REJECTED"<<endl;
-		TangoSys_OMemStream o;
-		o << " UserPositionLow from "<< clientAddress <<" REJECTED"<<ends;
-		Tango::Except::throw_exception((const char *)"Host not allowed",o.str(),(const char *)"TwinApuId::UserPositionLow()");
-	}
+	int priv = check_privileges(AUTHORIZED, "UserPositionLow");
     //check enabled for remote useres
 	if(priv == AUTHORIZED && *attr_Enabled_read == false){
 		INFO_STREAM << "UserPositionLow from "<< clientAddress <<" NOT ENABLED"<<endl;
 		TangoSys_OMemStream o;
-		o << " UserPositionLow from "<< clientAddress <<" NOT ENBLED"<<ends;
+		o << " UserPositionLow from "<< clientAddress <<" NOT ENABLED"<<ends;
 		Tango::Except::throw_exception((const char *)"not enabled",o.str(),(const char *)"TwinApuId::UserPositionLow()");
 	}
 
@@ -771,13 +765,7 @@ void TwinApuId::write_UserPositionHigh(Tango::WAttribute &attr)
 	attr.get_write_value(w_val);
 	/*----- PROTECTED REGION ID(TwinApuId::write_UserPositionHigh) ENABLED START -----*/
 	//check privileges
-	int priv=caller_privileges();
-	if (priv < AUTHORIZED){
-		INFO_STREAM << "UserPositionHigh from "<< clientAddress <<" REJECTED"<<endl;
-		TangoSys_OMemStream o;
-		o << " UserPositionHig from "<< clientAddress <<" REJECTED"<<ends;
-		Tango::Except::throw_exception((const char *)"Host not allowed",o.str(),(const char *)"TwinApuId::UserPositionHig()");
-	}
+	int priv = check_privileges(AUTHORIZED, "UserPositionHigh");
     //check enabled for remote useres
 	if(priv == AUTHORIZED && *attr_Enabled_read == false){
 		INFO_STREAM << "UserPositionHig from "<< clientAddress <<" NOT ENABLED"<<endl;
@@ -1041,14 +1029,8 @@ void TwinApuId::high_energy()
 {
 	DEBUG_STREAM << "TwinApuId::HighEnergy()  - " << device_name << endl;
 	/*----- PROTECTED REGION ID(TwinApuId::high_energy) ENABLED START -----*/
-	int priv=caller_privileges();
-	if (priv < PRIVILEGED){
-		INFO_STREAM << "high_energy from "<< clientAddress <<" REJECTED"<<endl;
-		TangoSys_OMemStream o;
-		o << " high_energy from "<< clientAddress <<" REJECTED"<<ends;
-		Tango::Except::throw_exception((const char *)"Host not allowed",o.str(),(const char *)"TwinApuId::high_energy()");
-	}
 	//	Add your own code
+	check_privileges(PRIVILEGED,"high_energy");
 	if(*attr_HighEnergy_read) return;
 	switchenergy = new switchenergythread(this,true);
 	switchenergy->start();
@@ -1065,14 +1047,9 @@ void TwinApuId::low_energy()
 {
 	DEBUG_STREAM << "TwinApuId::LowEnergy()  - " << device_name << endl;
 	/*----- PROTECTED REGION ID(TwinApuId::low_energy) ENABLED START -----*/
-	int priv=caller_privileges();
-	if (priv < PRIVILEGED){
-		INFO_STREAM << "low_energy from "<< clientAddress <<" REJECTED"<<endl;
-		TangoSys_OMemStream o;
-		o << " low_energy from "<< clientAddress <<" REJECTED"<<ends;
-		Tango::Except::throw_exception((const char *)"Host not allowed",o.str(),(const char *)"TwinApuId::low_energy()");
-	}
+
 	//	Add your own code
+	check_privileges(PRIVILEGED,"low_energy");
 	if(*attr_LowEnergy_read) return;
 	switchenergy = new switchenergythread(this,false);
 	switchenergy->start();
@@ -1091,14 +1068,7 @@ void TwinApuId::injection_position()
 	/*----- PROTECTED REGION ID(TwinApuId::injection_position) ENABLED START -----*/
 	
     //	Add your own code
-	int priv=caller_privileges();
-	if (priv < PRIVILEGED){
-		INFO_STREAM << "InjectionPosition from "<< clientAddress <<" REJECTED"<<endl;
-		TangoSys_OMemStream o;
-		o << " InjectionPosition from "<< clientAddress <<" REJECTED"<<ends;
-		Tango::Except::throw_exception((const char *)"Host not allowed",o.str(),(const char *)"TwinApuId::InjectionPosition()");
-	}
-
+	check_privileges(PRIVILEGED, "InjectionPosition");
     try {
         double inj_pos_high = highEnergyPeriod/2.0;
         double inj_pos_low = lowEnergyPeriod/2.0;
@@ -1134,14 +1104,7 @@ void TwinApuId::axis_init_low_energy()
 	/*----- PROTECTED REGION ID(TwinApuId::axis_init_low_energy) ENABLED START -----*/
 	
 	//	Add your own code
-	int priv=caller_privileges();
-	if (priv < PRIVILEGED){
-		INFO_STREAM << "AxisInitLowEnergy from "<< clientAddress <<" REJECTED"<<endl;
-		TangoSys_OMemStream o;
-		o << "AxisInitLowEnergy from "<< clientAddress <<" REJECTED"<<ends;
-		Tango::Except::throw_exception((const char *)"Host not allowed",o.str(),(const char *)"TwinApuId::AxisInit()");
-	}
-	//	Add your own code
+	check_privileges(PRIVILEGED, "AxisIniLowEnergy");
 	try {
 		low_energy_device->command_inout("AxisInit");
 		*attr_Ready_read = false;
@@ -1170,27 +1133,20 @@ void TwinApuId::axis_init_high_energy()
 	/*----- PROTECTED REGION ID(TwinApuId::axis_init_high_energy) ENABLED START -----*/
 	
 	//	Add your own code
-	int priv=caller_privileges();
-			if (priv < PRIVILEGED){
-				INFO_STREAM << "AxisInitHighEnergy from "<< clientAddress <<" REJECTED"<<endl;
-				TangoSys_OMemStream o;
-				o << "AxisInitHighEnergy from "<< clientAddress <<" REJECTED"<<ends;
-				Tango::Except::throw_exception((const char *)"Host not allowed",o.str(),(const char *)"TwinApuId::AxisInit()");
-			}
-		//	Add your own code
-		try {
-			high_energy_device->command_inout("AxisInit");
-			*attr_Ready_read = false;
-			id_flags[0]=*attr_Ready_read;
-			set_status("AxisInit");
-		} catch (Tango::DevFailed &e) {
-			Tango::Except::print_exception(e);
-			Tango::Except::re_throw_exception(e,
-					(const char*) "Failed to AxisInitHighEnergy motor device",
-					(const char*) "DevFailed", (const char*) "TwinApuId::axis_init_high_energy",
-					Tango::ERR);
-			set_status("AxisInit HighEnergy failed");
-		}
+	check_privileges(PRIVILEGED, "AxisInitHighEnergy");
+	try {
+		high_energy_device->command_inout("AxisInit");
+		*attr_Ready_read = false;
+		id_flags[0]=*attr_Ready_read;
+		set_status("AxisInit");
+	} catch (Tango::DevFailed &e) {
+		Tango::Except::print_exception(e);
+		Tango::Except::re_throw_exception(e,
+				(const char*) "Failed to AxisInitHighEnergy motor device",
+				(const char*) "DevFailed", (const char*) "TwinApuId::axis_init_high_energy",
+				Tango::ERR);
+		set_status("AxisInit HighEnergy failed");
+	}
 	/*----- PROTECTED REGION END -----*/	//	TwinApuId::axis_init_high_energy
 }
 //--------------------------------------------------------
@@ -1204,14 +1160,9 @@ void TwinApuId::axis_init_energy_switch()
 {
 	DEBUG_STREAM << "TwinApuId::AxisInitEnergySwitch()  - " << device_name << endl;
 	/*----- PROTECTED REGION ID(TwinApuId::axis_init_energy_switch) ENABLED START -----*/
-	int priv=caller_privileges();
-		if (priv < PRIVILEGED){
-			INFO_STREAM << "AxisInitEnergySwitch from "<< clientAddress <<" REJECTED"<<endl;
-			TangoSys_OMemStream o;
-			o << "AxisInitEnergySwitch from "<< clientAddress <<" REJECTED"<<ends;
-			Tango::Except::throw_exception((const char *)"Host not allowed",o.str(),(const char *)"TwinApuId::AxisInitEnergySwitch()");
-		}
+
 	//	Add your own code
+	check_privileges(PRIVILEGED, "AxisInitEnergySwitch");
 	try {
 		energy_switch_device->command_inout("AxisInit");
 		*attr_Ready_read = false;
@@ -1261,7 +1212,6 @@ int TwinApuId::caller_privileges(void)
 	Tango::DevVarStringArray blackbox = black_box(1)[0];
 	string last_msg(blackbox[0].in());
 	string::size_type loc = last_msg.find( " requested from ", 0 );
-	INFO_STREAM << loc <<endl;
 	if( loc != string::npos )
 	{
 		clientAddress = last_msg.substr(loc + strlen(" requested from "));
@@ -1296,6 +1246,27 @@ int TwinApuId::caller_privileges(void)
 	}
 	return NORMAL; //do not grant special privilege - but we should NOT arrive at this line
 }
+//--------------------------------------------------------------------
+/**
+	 * check privileges level based on host name from which the call is generated
+	 * formats warning/  error messages and throw exception in case of vilotaions
+	 * privilege levels:
+	 * PRIVILEGED : can change the enable bit and set gap/tapering
+	 * AUTHORIZED : can set gap/tapering when enabled
+	 * NORMAL     : can only read;
+	 */
+
+int TwinApuId::check_privileges(int level, string msg)
+{
+	int priv=caller_privileges();
+	if (priv < level){
+		INFO_STREAM << msg << " from "<< clientAddress <<" REJECTED"<<endl;
+		TangoSys_OMemStream o;
+		o << msg << " from "<< clientAddress <<" REJECTED"<<ends;
+		Tango::Except::throw_exception((const char *)"Host not allowed",o.str(),msg);
+	}
+	return priv;
+}
 
 /*----- PROTECTED REGION END -----*/	//	TwinApuId::namespace_ending
 } //	namespace
diff --git a/src/TwinApuId.h b/src/TwinApuId.h
index dd5ac18..13be82c 100644
--- a/src/TwinApuId.h
+++ b/src/TwinApuId.h
@@ -81,9 +81,11 @@ public:
     
 protected:
     int caller_privileges(void);
-    bool is_privileged; //true is tha caller has all privileges - must be handled in alawys_executed
+    bool is_privileged; //true is the caller has all privileges - must be handled in alawys_executed
     string clientAddress;
     map<string,int> hostMap;
+    int check_privileges(int, string); //check privileges , emits diagnostics and throw exception, returns actual privileges
+
 
 /*----- PROTECTED REGION END -----*/	//	TwinApuId::Data Members
 
-- 
GitLab