📄 sdbms_datastruct.cpp
字号:
{
sprintf(g_strMsg, "表%s中没有列名%s", strTableName, strFieldName);
g_msg.ThrowErrorMsg(g_strMsg);
return FALSE;
}
bOnlyOneField = true;
ASSERT(pField);
}
//预处理权限的谓词条件
if (pCondition)
{
BOOL bValue=FALSE, bCanComp=FALSE;
//设置缺省表名
pCondition->SetDefaultTableName(strTableName);
if (pCondition->PreTreat(&bValue, &bCanComp)) //表达式是常量
{
if (bValue) //谓词条件永真
{
delete pCondition;
pCondition = NULL;
}
else
{
g_msg.ThrowErrorMsg("谓词条件永为假,GRANT失败");
return FALSE;
}
}
else //表达式含有列名
{
if (!bCanComp)
{
g_msg.ThrowErrorMsg("谓词条件表达式语法错误, GRANT失败");
return FALSE;
}
}
}
CSdbms_RoleUser *pRoleUser1=NULL, *pRoleUser2=NULL;
if (g_sdbms.IsOwnDbaRole(pUser->m_nUserID)) //授权用户属于DBA角色
pRoleUser1 = g_sdbms.FindRoleUser(pUser, g_sdbms.GetDbaRole());
// if (g_sdbms.IsOwnSystemRole(pUser->m_nUserID)) //授权用户属于SYSTEM角色
// pRoleUser2 = g_sdbms.FindRoleUser(pUser, g_sdbms.GetSystemRole());
bool bGrant = false;
int nCount = bOnlyOneField ? 1 : pTable->m_FieldArray.GetSize(); //判断只有一列还是要针对所有列
for (int i=0; i<nCount; i++)
{
bGrant = false;
if (bOnlyOneField) //只有一列
ASSERT(i == 0); //只会执行一次
else
pField = pTable->m_FieldArray[i];
//如果被授权角色的父角色没有此对象权限,授权失败
CSdbms_Role *pParent = pRole->m_pParentRole;
if (pParent != NULL)
{
if (pParent->FindObjectRight(pTable->m_nTableID, pField->m_nFieldID, nObjectRight, pCondition) == NULL)
{
sprintf(g_strMsg, "因为角色%s的父角色%s没有在%s.%s.%s上的%s权限,所以不能授权",
strRoleName, pParent->m_strRoleName, m_strDBName,
strTableName, pField->m_strFieldName, g_strObjectRight[nObjectRight]);
g_msg.ThrowErrorMsg(g_strMsg);
continue;
}
}
if (pRoleUser1) //用户属于DBA角色
{
if (pRole->InsertORList(nObjectRight, pTable->m_nTableID,
pField->m_nFieldID, pRoleUser1, bCanGrant, pCondition))
{
bGrant = true;
CSdbms_RoleObjectRight *pRight = pRoleUser1->m_pRole->m_ORList.GetHead();
ASSERT(pRight);
VERIFY(pRight->InsertToRoleArray(pRole)); //系统预定义角色都只有一个对象权限结点
sprintf(g_strMsg, "用户%s成功地以DBA身份把作用在%s.%s.%s上的%s权限授予给了角色%s",
pUser->m_strUserName, m_strDBName, strTableName,
pField->m_strFieldName, g_strObjectRight[nObjectRight], strRoleName);
g_msg.ThrowSuccessMsg(g_strMsg);
}
}
/* if (pRoleUser2) //用户属于SYSTEM角色
{
if (pRole->InsertORList(nObjectRight, pTable->m_nTableID,
pField->m_nFieldID, pRoleUser2, bCanGrant, pCondition))
{
bGrant = true;
CSdbms_RoleObjectRight *pRight = pRoleUser2->m_pRole->m_ORList.GetHead();
ASSERT(pRight);
VERIFY(pRight->InsertToRoleArray(pRole)); //系统预定义角色都只有一个对象权限结点
sprintf(g_strMsg, "用户%s成功地以SYSTEM身份把作用在%s.%s.%s上的%s权限授予给了角色%s",
pUser->m_strUserName, m_strDBName, strTableName,
pField->m_strFieldName, g_strObjectRight[nObjectRight], strRoleName);
g_msg.ThrowSuccessMsg(g_strMsg);
}
}
*/
//用户是不是数据库的创建者
if (IsDBCreator(pUser->m_nUserID))
{
if (pRole->InsertORList(nObjectRight, pTable->m_nTableID, pField->m_nFieldID, m_RoleUserList.GetHead(), bCanGrant, pCondition))
{
bGrant = TRUE;
CSdbms_RoleObjectRight *pRight = m_pCreatorRole->m_ORList.GetHead();
ASSERT(pRight);
VERIFY(pRight->InsertToRoleArray(pRole)); //系统预定义角色都只有一个对象权限结点
sprintf(g_strMsg, "用户%s成功地以数据库%s创建者的身份把作用在%s.%s.%s上的%s权限授予给了角色%s",
pUser->m_strUserName, m_strDBName, m_strDBName, strTableName,
pField->m_strFieldName, g_strObjectRight[nObjectRight], strRoleName);
g_msg.ThrowSuccessMsg(g_strMsg);
}
}
//用户是不是表的创建者
if (pTable->IsTableCreator(pUser->m_nUserID))
{
// CSdbms_Role *pTemp;
// VERIFY(GetTBCreatorRole(pTable->m_nTableID, &pTemp));
// POSITION pos = FindRoleUser(pTemp, pUser);
POSITION pos = FindRoleUser(pTable->m_pCreatorRole, pUser);
if (pRole->InsertORList(nObjectRight, pTable->m_nTableID, pField->m_nFieldID, m_RoleUserList.GetAt(pos), bCanGrant, pCondition))
{
bGrant = TRUE;
CSdbms_RoleObjectRight *pRight = pTable->m_pCreatorRole->m_ORList.GetHead();
ASSERT(pRight);
VERIFY(pRight->InsertToRoleArray(pRole)); //系统预定义角色都只有一个对象权限结点
sprintf(g_strMsg, "用户%s成功地以表%s创建者的身份把作用在%s.%s.%s上的%s权限授予给了角色%s",
pUser->m_strUserName, strTableName, m_strDBName,
strTableName, pField->m_strFieldName,
g_strObjectRight[nObjectRight], strRoleName);
g_msg.ThrowSuccessMsg(g_strMsg);
}
}
//遍历用户所属的所有角色
POSITION pos = pUser->m_pos;
while (pos != NULL)
{
CSdbms_RoleUser *pRoleUser = m_UserRoleList.GetNext(pos);
if (pRoleUser->m_pUser->m_nUserID == pUser->m_nUserID)
{
if (pRoleUser->m_pRole->m_nRoleID == pRole->m_nRoleID)
continue; //不能授权给自身
if (pRoleUser->m_pRole->m_strRoleName.CompareNoCase(SYSTEM_ROLE_OWNER) == 0)
continue; //如果是数据库创建者或表创建者,中止,遍历下一个结点
if (pRole->Grant(nObjectRight, pTable->m_nTableID, pField->m_nFieldID, pRoleUser, bCanGrant, pCondition))
{
bGrant = TRUE;
sprintf(g_strMsg, "用户%s成功地以%s身份把作用在%s.%s.%s上的%s权限授予给了角色%s",
pUser->m_strUserName, pRoleUser->m_pRole->m_strRoleName,
m_strDBName, strTableName,
pField->m_strFieldName, g_strObjectRight[nObjectRight], strRoleName);
g_msg.ThrowSuccessMsg(g_strMsg);
}
}
else
break;
}
if (bGrant)
{
sprintf(g_strMsg, "成功地把作用在%s.%s.%s上的%s权限授予给了角色%s",
m_strDBName, strTableName,
pField->m_strFieldName, g_strObjectRight[nObjectRight], strRoleName);
g_msg.ThrowSuccessMsg(g_strMsg);
}
else
{
sprintf(g_strMsg, "失败地把作用在%s.%s.%s上的%s权限授予给了角色%s",
m_strDBName, strTableName,
pField->m_strFieldName, g_strObjectRight[nObjectRight], strRoleName);
g_msg.ThrowErrorMsg(g_strMsg);
}
}
return bGrant;
}
/**********************************************************************
功能:取消角色的一个对象权限授权
参数: pUser -- 撤消授权的执行用户
nObjectRight -- 要撤消授权的对象权限
strTableName -- 权限作用的对象的表名
strFieldName -- 权限作用的对象的列名
strRoleName -- 被撤消授权的角色名
bRevokeGrant -- 是否只收回授予权限,而不收回权限本身
bRestrict -- 如果为真表示如果要收回的权限已经授权给其他用户,则该语句不能执行
pCondition -- 权限的谓词条件的语法树
算法: 先判断角色中是否含有该对象权限,若有则再查找权限授权者,
若授权人是该用户,则对其所有用户角色关系回收权限,
(既然存在,则用户所属的角色权限一定仍在,则一定会回收成功)
***********************************************************************/
BOOL CSdbms_Database::Revoke(CSdbms_User *pUser, ObjectRight nObjectRight, CString strTableName,
CString strFieldName, CString strRoleName,BOOL bRevokeGrant/*=FALSE*/,
BOOL bRestrict/*=FALSE*/, CSdbms_Condition *pCondition/*=NULL*/)
{
ASSERT(pUser);
//检查被收回授权的角色名是否已存在
CSdbms_Role *pRole = NULL;
if (!GetRole(strRoleName, &pRole))
{
sprintf(g_strMsg, "角色%s不存在", strRoleName);
g_msg.ThrowErrorMsg(g_strMsg);
return FALSE;
}
ASSERT(pRole);
//得到表内码
CSdbms_Table *pTable=NULL;
if (!GetTable(strTableName, &pTable))
{
sprintf(g_strMsg, "数据库%s中没有表名%s", m_strDBName, strTableName);
g_msg.ThrowErrorMsg(g_strMsg);
return FALSE;
}
ASSERT(pTable);
//得到列内码。若列名为空,表示针对表中的所有列
CSdbms_Field *pField=NULL;
bool bOnlyOneField = false;
if (!strFieldName.IsEmpty())
{
if (!pTable->GetField(strFieldName, &pField))
{
sprintf(g_strMsg, "表%s中没有列名%s", strTableName, strFieldName);
g_msg.ThrowErrorMsg(g_strMsg);
return FALSE;
}
bOnlyOneField = true;
ASSERT(pField);
}
//预处理权限的谓词条件
if (pCondition)
{
BOOL bValue=FALSE, bCanComp=FALSE;
//设置缺省表名
pCondition->SetDefaultTableName(strTableName);
if (pCondition->PreTreat(&bValue, &bCanComp)) //表达式是常量
{
if (bValue) //谓词条件永真
{
delete pCondition;
pCondition = NULL;
}
else
{
g_msg.ThrowErrorMsg("谓词条件永为假,GRANT失败");
return FALSE;
}
}
else //表达式含有列名
{
if (!bCanComp)
{
g_msg.ThrowErrorMsg("谓词条件表达式语法错误, GRANT失败");
return FALSE;
}
}
}
bool bSuccess = false;
int nCount = bOnlyOneField ? 1 : pTable->m_FieldArray.GetSize();//判断只有一列还是要针对所有列
for (int i=0; i<nCount; i++)
{
bSuccess = false;
if (bOnlyOneField) //只有一列
ASSERT(i == 0); //只会执行一次
else
pField = pTable->m_FieldArray[i];
UINT nTableID = pTable->m_nTableID;
UINT nFieldID = pField->m_nFieldID;
//判断角色是否有该权限
POSITION pos = pRole->FindObjectRight(nTableID, nFieldID, nObjectRight, pCondition);
if (pos == NULL)
{
sprintf(g_strMsg, "因为角色%s没有作用在%s.%s.%s上的%s权限,所以该回收语句执行失败!",
strRoleName, m_strDBName, strTableName,
pField->m_strFieldName, g_strObjectRight[nObjectRight]);
g_msg.ThrowErrorMsg(g_strMsg);
return FALSE;
}
CSdbms_RoleObjectRight *pObjectRight = pRole->m_ORList.GetAt(pos);
//如果bRstrict==TRUE,则判断是否该权限已经授予给其他用户了
if (bRestrict && (pObjectRight->m_ToRoleArray.GetSize() > 0))
{
sprintf(g_strMsg, "因为角色%s中的作用在%s.%s.%s上的%s权限已经授权给了其他用户,所以该回收语句不能执行!",
strRoleName, m_strDBName, strTableName,
pField->m_strFieldName, g_strObjectRight[nObjectRight]);
g_msg.ThrowErrorMsg(g_strMsg);
return FALSE;
}
//如果被收回授权的角色的某个子角色有此对象权限,收回授权失败
CSdbms_Role *pChild = pRole->m_pFirstChildRole;
while (pChild != NULL)
{
// if (pChild->m_pParentRole->HaveObjectRight(pTable->m_nTableID, pField->m_nFieldID, nObjectRight))
if (pChild->FindObjectRight(pTable->m_nTableID, pField->m_nFieldID, nObjectRight, pCondition))
{
sprintf(g_strMsg, "因为角色%s的子角色%s有在%s.%s.%s上的%s权限,所以不能收回授权",
strRoleName, pChild->m_strRoleName, m_strDBName, strTableName,
pField->m_strFieldName, g_strObjectRight[nObjectRight]);
g_msg.ThrowErrorMsg(g_strMsg);
break;
}
else
pChild = pChild->m_pNextBrotherRole;
}
if (pChild != NULL) //收回授权失败,进行下一个
return FALSE;
//遍历授权者数组
int i=0;
ASSERT(pObjectRight->m_FromUserRoleArray.GetSize() > 0);
while (i < pObjectRight->m_FromUserRoleArray.GetSize())
{
CSdbms_RoleUser *pRoleUser = pObjectRight->m_FromUserRoleArray[i];
CSdbms_User *pFromUser = pRoleUser->m_pUser;
CSdbms_Role *pFromRole = pRoleUser->m_pRole;
if (pFromUser != pUser) //是否是该用户授权的
i++;
else
{
ASSERT(pFromRole != g_sdbms.GetDbsaRole());
bSuccess = true; //只要授权者是该用户,则一定回收权限成功
CString strTemp1, strTemp2;
if ((pFromRole == g_sdbms.GetDbaRole()) || //DBA角色
(pFromRole == g_sdbms.GetSystemRole())) //SYSTEM角色
{
//用户应该仍属于DBA或SYSTEM角色
ASSERT(g_sdbms.FindRoleUser(pFromUser, pFromRole) == pRoleUser);
//收回该权限
VERIFY(pObjectRight->RemoveFromUserRoleArray(pRole, pRoleUser, bRevokeGrant));
if (!bRevokeGrant)
{
CSdbms_RoleObjectRight *pTemp = pFromRole->m_ORList.GetHead();
ASSERT(pTemp);
VERIFY(pTemp->RemoveToRoleArray(pRole)); //系统预定义角色都只有一个对象权限结点
}
strTemp1 = (pFromRole == g_sdbms.GetDbaRole()) ? "DBA身份" : "SYSTEM身份";
}
else //数据库创建者角色或表创建者角色或自定义角色
{
//用户角色关系仍然应该存在
ASSERT(FindRoleUser(pFromRole, pFromUser) != NULL);
//回收权限
VERIFY(pObjectRight->RemoveFromUserRoleArray(pRole, pRoleUser, bRevokeGrant));
CSdbms_Role *pTBCreatorRole = pTable->m_pCreatorRole;
// VERIFY(GetTBCreatorRole(pTable->m_nTableID, &pTBCreatorRole));
if (!bRevokeGrant)
{
CSdbms_RoleObjectRight *pTemp=NULL;
if ((pFromRole == m_pCreatorRole) || //DB创建者角色
(pFromRole == pTBCreatorRole)) //TB创建者角色
{
pTemp = pFromRole->m_ORList.GetHead();//系统预定义角色都只有一个对象权限结点
}
else //自定义角色
{
POSITION pos2 = pFromRole->FindObjectRight(nTableID, nFieldID, nObjectRight, pCondition);
ASSERT(pos2);
pTemp = pFromRole->m_ORList.GetAt(pos2);
}
ASSERT(pTemp);
VERIFY(pTemp->RemoveToRoleArray(pRole));
}
if (pFromRole == m_pCreatorRole) //数据库创建者角色
strTemp1.Format("数据库%s创建者", m_strDBName);
else if (pFromRole == pTBCreatorRole) //表创建者角色
strTemp1.Format("表%s创建者身份", strTableName);
else //自定义角色
strTemp1.Format("%s身份", pFromRole->m_strRoleName);
}
sprintf(g_strMsg, "用户%s成功地以", pUser->m_strUserName);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -