Skip to content

Commit

Permalink
[Sec] Add method to iterate over attribute key-value pairs.
Browse files Browse the repository at this point in the history
[Sec] Further encapsulate he SecEntity implementation.
  • Loading branch information
abh3 authored and simonmichal committed Oct 16, 2019
1 parent 8123c4f commit d1e5401
Show file tree
Hide file tree
Showing 2 changed files with 118 additions and 69 deletions.
123 changes: 63 additions & 60 deletions src/XrdSec/XrdSecEntity.cc
Expand Up @@ -33,29 +33,24 @@

#include "XrdSec/XrdSecAttr.hh"
#include "XrdSec/XrdSecEntity.hh"
#include "XrdSys/XrdSysPthread.hh"

/******************************************************************************/
/* L o c a l C l a s s e s */
/******************************************************************************/

class XrdSecEntityAttrs
class XrdSecEntityXtra
{
public:

XrdSysMutex xMutex;

std::vector<XrdSecAttr *> attrVec;

std::map<std::string, std::string> attrMap;

XrdSecEntityAttrs() {}
~XrdSecEntityAttrs() {}
};

class XrdSecEntityXtend
{
public:

XrdSecEntityXtend() {}
~XrdSecEntityXtend() {}
XrdSecEntityXtra() {}
~XrdSecEntityXtra() {}
};

/******************************************************************************/
Expand All @@ -64,20 +59,17 @@ class XrdSecEntityXtend

bool XrdSecEntity::Add(XrdSecAttr &attr)
{
XrdSysMutexHelper mHelp(eMutex);
XrdSysMutexHelper mHelp(entXtra->xMutex);
std::vector<XrdSecAttr*>::iterator it;

// Check if this attribute already exists
//
if (!entAttrs) entAttrs = new XrdSecEntityAttrs;
else {std::vector<XrdSecAttr*>::iterator it;
for (it = entAttrs->attrVec.begin();
it != entAttrs->attrVec.end(); it++)
{if ((*it)->Signature == attr.Signature) return false;}
}
for (it = entXtra->attrVec.begin(); it != entXtra->attrVec.end(); it++)
if ((*it)->Signature == attr.Signature) return false;

// Add the attribute object to our list of objects
//
entAttrs->attrVec.push_back(&attr);
entXtra->attrVec.push_back(&attr);
return true;
}

Expand All @@ -86,23 +78,22 @@ bool XrdSecEntity::Add(XrdSecAttr &attr)
bool XrdSecEntity::Add(const std::string &key,
const std::string &val, bool replace)
{
XrdSysMutexHelper mHelp(eMutex);
XrdSysMutexHelper mHelp(entXtra->xMutex);
std::map<std::string, std::string>::iterator it;
bool found = false;

// Check if this attribute already exists
//
if (!entAttrs) entAttrs = new XrdSecEntityAttrs;
else {it = entAttrs->attrMap.find(key);
if (it != entAttrs->attrMap.end())
{if (!replace) return false;
found = true;
} }
it = entXtra->attrMap.find(key);
if (it != entXtra->attrMap.end())
{if (!replace) return false;
found = true;
}

// Add or replace the value
//
if (found) it->second = val;
else entAttrs->attrMap.insert(std::make_pair(key, val));
else entXtra->attrMap.insert(std::make_pair(key, val));
return true;
}

Expand All @@ -112,16 +103,13 @@ bool XrdSecEntity::Add(const std::string &key,

XrdSecAttr *XrdSecEntity::Get(const void *sigkey)
{
XrdSysMutexHelper mHelp(eMutex);
XrdSysMutexHelper mHelp(entXtra->xMutex);
std::vector<XrdSecAttr*>::iterator it;

// Return pointer to the attribute if it exists
//
if (entAttrs)
{std::vector<XrdSecAttr*>::iterator it;
for (it = entAttrs->attrVec.begin();
it != entAttrs->attrVec.end(); it++)
{if ((*it)->Signature == sigkey) return *it;}
}
for (it = entXtra->attrVec.begin(); it != entXtra->attrVec.end(); it++)
if ((*it)->Signature == sigkey) return *it;

// Attribute not found
//
Expand All @@ -132,24 +120,48 @@ XrdSecAttr *XrdSecEntity::Get(const void *sigkey)

bool XrdSecEntity::Get(const std::string &key, std::string &val)
{
XrdSysMutexHelper mHelp(eMutex);
XrdSysMutexHelper mHelp(entXtra->xMutex);
std::map<std::string, std::string>::iterator it;

// Return pointer to the attribute if it exists
//
if (entAttrs)
{std::map<std::string, std::string>::iterator it;
it = entAttrs->attrMap.find(key);
if (it != entAttrs->attrMap.end())
{val = it->second;
return true;
}
it = entXtra->attrMap.find(key);
if (it != entXtra->attrMap.end())
{val = it->second;
return true;
}

// The key does not exists
//
return false;
}

/******************************************************************************/
/* L i s t */
/******************************************************************************/

void XrdSecEntity::List(XrdSecEntityAttrCB &attrCB)
{
XrdSysMutexHelper mHelp(entXtra->xMutex);
std::map<std::string, std::string>::iterator itM;
std::vector<const char *> attrDel;
std::vector<const char *>::iterator itV;
XrdSecEntityAttrCB::Action rc;

for (itM = entXtra->attrMap.begin();
itM != entXtra->attrMap.end(); itM++)
{rc = attrCB.Attr(itM->first.c_str(), itM->second.c_str());
if (rc == XrdSecEntityAttrCB::Stop) break;
else if (rc == XrdSecEntityAttrCB::Delete)
attrDel.push_back(itM->first.c_str());
}

if (rc != XrdSecEntityAttrCB::Stop) attrCB.Attr(0, 0);

for (itV = attrDel.begin(); itV != attrDel.end(); itV++)
entXtra->attrMap.erase(std::string(*itV));
}

/******************************************************************************/
/* R e s e t */
/******************************************************************************/
Expand Down Expand Up @@ -178,42 +190,33 @@ void XrdSecEntity::Reset(bool isnew, const char *spV, const char *dpV)
gid = 0;
memset(future, 0, sizeof(future));

if (isnew)
{entAttrs = 0;
entXtend = 0;
} else {
if (entAttrs) ResetAttrs();
entXtend = 0; // No extension for now.
}
if (isnew) entXtra = new XrdSecEntityXtra;
else ResetXtra();
}

/******************************************************************************/
/* R e s e t A t t r s */
/* R e s e t X t r a */
/******************************************************************************/

void XrdSecEntity::ResetAttrs(bool dodel)
void XrdSecEntity::ResetXtra(bool dodel)
{
XrdSysMutexHelper mHelp(eMutex);

// If we have no attributes we are done
//
if (!entAttrs) return;
XrdSysMutexHelper mHelp(entXtra->xMutex);

// Cleanup the key-value map
//
entAttrs->attrMap.clear();
entXtra->attrMap.clear();

// Run through attribute objects, deleting each one
//
std::vector<XrdSecAttr*>::iterator it;
for (it = entAttrs->attrVec.begin(); it != entAttrs->attrVec.end(); it++)
for (it = entXtra->attrVec.begin(); it != entXtra->attrVec.end(); it++)
{(*it)->Delete();}

// Now clear the whole vector
//
entAttrs->attrVec.clear();
entXtra->attrVec.clear();

// Delete the extension if so wanted
//
if (dodel) {delete entAttrs; entAttrs = 0;}
if (dodel) {delete entXtra; entXtra = 0;}
}
64 changes: 55 additions & 9 deletions src/XrdSec/XrdSecEntity.hh
Expand Up @@ -44,14 +44,12 @@

#include <string>

#include "XrdSys/XrdSysPthread.hh"

#define XrdSecPROTOIDSIZE 8

class XrdNetAddrInfo;
class XrdSecAttr;
class XrdSecEntityAttrs;
class XrdSecEntityXtend;
class XrdSecEntityAttrCB;
class XrdSecEntityXtra;

/******************************************************************************/
/* X r d S e c E n t i t y */
Expand Down Expand Up @@ -136,6 +134,14 @@ XrdSecAttr *Get(const void *sigkey);

bool Get(const std::string &key, std::string &val);

//------------------------------------------------------------------------------
//! List key-value pairs via iterative callback on passed ovject.
//!
//! @param attrCB - Reference to the callback object to receive list entries.
//------------------------------------------------------------------------------

void List(XrdSecEntityAttrCB &attrCB);

//------------------------------------------------------------------------------
//! Reset object to it's pristine self.
//!
Expand All @@ -152,7 +158,7 @@ XrdSecAttr *Get(const void *sigkey);
//! @param doDel - When true, the attribute extension is deleted as well.
//------------------------------------------------------------------------------

void ResetAttrs(bool doDel=false);
void ResetXtra(bool doDel=false);

//------------------------------------------------------------------------------
//! Constructor.
Expand All @@ -164,14 +170,54 @@ XrdSecAttr *Get(const void *sigkey);
XrdSecEntity(const char *spName=0, const char *dpName=0)
{Reset(true, dpName, spName);}

~XrdSecEntity() {ResetAttrs(true);}
~XrdSecEntity() {ResetXtra(true);}

private:
XrdSysMutex eMutex;
XrdSecEntityAttrs *entAttrs;
XrdSecEntityXtend *entXtend;
XrdSecEntityXtra *entXtra;
};

#define XrdSecClientName XrdSecEntity
#define XrdSecServerName XrdSecEntity


/******************************************************************************/
/* X r d S e c E n t i t y A t t r C B */
/******************************************************************************/

// The XrdSecEntityAttrCB class defines the callback object passed to the
// XrdSecEntity::List() method to iteratively obtain the key-value attribute
// pairs associated with the entity. The XrdSecEntityAttrCB::Attr() method is
// called for each key-value pair. The end of the list is indicated by calling
// Attr() with nil key-value pointers. The Attr() method should not call
// the XrdSecEntity::Add() or XrdSecEntity::Get() methods; otherwise, a
// deadlock will occur.
//
class XrdSecEntityAttrCB
{
public:

//------------------------------------------------------------------------------
//! Acceppt a key-value attribute pair from the XrdSecEntity::List() method.
//!
//! @param key - The key, if nil this is the end of the list.
//! @param val - The associated value, if nil this is the end of the list.
//!
//! @return One of the Action enum values. The return value is ignored when
//! the end of the list indicator is returned.
//------------------------------------------------------------------------------

enum Action {Delete = -1, //!< Delete the key-value
Stop = 0, //!< Stop the iteration
Next = 1 //!< Proceed to the next key-value pair
};

virtual Action Attr(const char *key, const char *val) = 0;

//------------------------------------------------------------------------------
//! Constructor and Destructor.
//------------------------------------------------------------------------------

XrdSecEntityAttrCB() {}
virtual ~XrdSecEntityAttrCB() {}
};
#endif

0 comments on commit d1e5401

Please sign in to comment.