From 969b002936321b6c21e6c2ca561bf7256346d44f Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Fri, 20 Oct 2023 08:41:49 +0800 Subject: [PATCH] enh: support view privilege --- include/common/tmsg.h | 5 + include/libs/catalog/catalog.h | 10 +- include/libs/nodes/cmdnodes.h | 2 +- include/libs/parser/parser.h | 3 +- include/libs/qcom/query.h | 1 + source/client/inc/clientInt.h | 5 +- source/client/src/clientImpl.c | 4 +- source/client/src/clientMain.c | 1 + source/client/src/clientSml.c | 4 +- source/common/src/systable.c | 2 + source/common/src/tmsg.c | 136 +++++++++- source/dnode/mnode/impl/src/mndInfoSchema.c | 4 +- source/dnode/mnode/impl/src/mndPerfSchema.c | 4 +- source/dnode/mnode/impl/src/mndShow.c | 2 +- source/dnode/mnode/impl/src/mndUser.c | 253 +++++++++++++++++- source/libs/catalog/src/ctgAsync.c | 4 +- source/libs/catalog/src/ctgCache.c | 17 +- source/libs/catalog/src/ctgUtil.c | 147 ++++++++-- source/libs/catalog/test/catalogTests.cpp | 4 +- source/libs/command/src/command.c | 2 +- source/libs/parser/inc/parTranslater.h | 2 + source/libs/parser/src/parAstParser.c | 6 + source/libs/parser/src/parAuthenticator.c | 60 ++++- source/libs/parser/src/parInsertSql.c | 10 +- source/libs/parser/src/parTranslater.c | 49 +++- source/libs/parser/src/parUtil.c | 1 + source/libs/parser/test/mockCatalog.cpp | 4 +- .../libs/parser/test/mockCatalogService.cpp | 2 +- tests/script/tsim/view/insert_view.sim | 11 + tests/script/tsim/view/query_view.sim | 25 ++ 30 files changed, 703 insertions(+), 77 deletions(-) create mode 100644 tests/script/tsim/view/insert_view.sim diff --git a/include/common/tmsg.h b/include/common/tmsg.h index e43931b4bb..e5545b9ed8 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -937,6 +937,7 @@ typedef struct { int8_t superUser; int8_t sysInfo; int8_t enable; + int8_t isView; char user[TSDB_USER_LEN]; char pass[TSDB_USET_PASSWORD_LEN]; char objname[TSDB_DB_FNAME_LEN]; // db or topic @@ -975,6 +976,9 @@ typedef struct { SHashObj* readTbs; SHashObj* writeTbs; SHashObj* alterTbs; + SHashObj* readViews; + SHashObj* writeViews; + SHashObj* alterViews; SHashObj* useDbs; int64_t whiteListVer; } SGetUserAuthRsp; @@ -4000,6 +4004,7 @@ int32_t tDeserializeSViewMetaReq(void* buf, int32_t bufLen, SViewMetaReq* pReq); typedef struct { char name[TSDB_VIEW_NAME_LEN]; char dbFName[TSDB_DB_FNAME_LEN]; + char* user; uint64_t dbId; uint64_t viewId; char* querySql; diff --git a/include/libs/catalog/catalog.h b/include/libs/catalog/catalog.h index 418b6ee7dd..d1ec791c9d 100644 --- a/include/libs/catalog/catalog.h +++ b/include/libs/catalog/catalog.h @@ -57,9 +57,15 @@ typedef struct SUserAuthInfo { AUTH_TYPE type; } SUserAuthInfo; +typedef enum { + AUTH_RES_BASIC = 0, + AUTH_RES_VIEW, + AUTH_RES_MAX_VALUE +} AUTH_RES_TYPE; + typedef struct SUserAuthRes { - bool pass; - SNode* pCond; + bool pass[AUTH_RES_MAX_VALUE]; + SNode* pCond[AUTH_RES_MAX_VALUE]; } SUserAuthRes; typedef struct SDbInfo { diff --git a/include/libs/nodes/cmdnodes.h b/include/libs/nodes/cmdnodes.h index e903462a4d..ac4f5bea0e 100644 --- a/include/libs/nodes/cmdnodes.h +++ b/include/libs/nodes/cmdnodes.h @@ -26,7 +26,7 @@ extern "C" { #define DESCRIBE_RESULT_COLS 4 #define DESCRIBE_RESULT_FIELD_LEN (TSDB_COL_NAME_LEN - 1 + VARSTR_HEADER_SIZE) #define DESCRIBE_RESULT_TYPE_LEN (20 + VARSTR_HEADER_SIZE) -#define DESCRIBE_RESULT_NOTE_LEN (8 + VARSTR_HEADER_SIZE) +#define DESCRIBE_RESULT_NOTE_LEN (16 + VARSTR_HEADER_SIZE) #define SHOW_CREATE_DB_RESULT_COLS 2 #define SHOW_CREATE_DB_RESULT_FIELD1_LEN (TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE) diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h index 9de8fc8c62..34b2bfa569 100644 --- a/include/libs/parser/parser.h +++ b/include/libs/parser/parser.h @@ -56,7 +56,7 @@ typedef struct SParseSqlRes { }; } SParseSqlRes; -typedef int32_t (*parseSqlFn)(void*, const char*, bool, SParseSqlRes*); +typedef int32_t (*parseSqlFn)(void*, const char*, bool, const char*, SParseSqlRes*); typedef struct SParseCsvCxt { TdFilePtr fp; // last parsed file @@ -80,6 +80,7 @@ typedef struct SParseContext { struct SCatalog* pCatalog; SStmtCallback* pStmtCb; const char* pUser; + const char* pEffectiveUser; bool parseOnly; bool isSuperUser; bool enableSysInfo; diff --git a/include/libs/qcom/query.h b/include/libs/qcom/query.h index 2a7436f404..8b5bf1abb1 100644 --- a/include/libs/qcom/query.h +++ b/include/libs/qcom/query.h @@ -121,6 +121,7 @@ typedef struct STableMeta { typedef struct SViewMeta { uint64_t viewId; + char* user; char* querySql; int8_t precision; int8_t type; diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index 288c4ed18c..1331c8362a 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -281,6 +281,7 @@ typedef struct SRequestObj { SReqRelInfo relation; void* pWrapper; SMetaData parseMeta; + char* effectiveUser; } SRequestObj; typedef struct SSyncQueryParam { @@ -307,7 +308,7 @@ void taosAsyncQueryImpl(uint64_t connId, const char* sql, __taos_async_fn_t fp, void taosAsyncQueryImplWithReqid(uint64_t connId, const char* sql, __taos_async_fn_t fp, void* param, bool validateOnly, int64_t reqid); void taosAsyncFetchImpl(SRequestObj *pRequest, __taos_async_fn_t fp, void *param); -int32_t clientParseSql(void* param, const char* sql, bool parseOnly, SParseSqlRes* pRes); +int32_t clientParseSql(void* param, const char* sql, bool parseOnly, const char* effectiveUser, SParseSqlRes* pRes); void syncQueryFn(void* param, void* res, int32_t code); int32_t getVersion1BlockMetaSize(const char* p, int32_t numOfCols); @@ -422,7 +423,7 @@ void stopAllQueries(SRequestObj *pRequest); void freeQueryParam(SSyncQueryParam* param); #ifdef TD_ENTERPRISE -int32_t clientParseSqlImpl(void* param, const char* sql, bool parseOnly, SParseSqlRes* pRes); +int32_t clientParseSqlImpl(void* param, const char* sql, bool parseOnly, const char* effeciveUser, SParseSqlRes* pRes); #endif #ifdef __cplusplus diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index bc7e0c07de..58d6253fb7 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -2623,11 +2623,11 @@ void taosAsyncFetchImpl(SRequestObj* pRequest, __taos_async_fn_t fp, void* param schedulerFetchRows(pRequest->body.queryJob, &req); } -int32_t clientParseSql(void* param, const char* sql, bool parseOnly, SParseSqlRes* pRes) { +int32_t clientParseSql(void* param, const char* sql, bool parseOnly, const char* effectiveUser, SParseSqlRes* pRes) { #ifndef TD_ENTERPRISE return TSDB_CODE_SUCCESS; #else - return clientParseSqlImpl(param, sql, parseOnly, pRes); + return clientParseSqlImpl(param, sql, parseOnly, effectiveUser, pRes); #endif } diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index 4d64942e7c..cb107b2612 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -1173,6 +1173,7 @@ int32_t createParseContext(const SRequestObj *pRequest, SParseContext **pCxt, SS .pTransporter = pTscObj->pAppInfo->pTransporter, .pStmtCb = NULL, .pUser = pTscObj->user, + .pEffectiveUser = pRequest->effectiveUser, .isSuperUser = (0 == strcmp(pTscObj->user, TSDB_DEFAULT_USER)), .enableSysInfo = pTscObj->sysInfo, .async = true, diff --git a/source/client/src/clientSml.c b/source/client/src/clientSml.c index 91c21fe344..71561419d7 100644 --- a/source/client/src/clientSml.c +++ b/source/client/src/clientSml.c @@ -104,9 +104,9 @@ static int32_t smlCheckAuth(SSmlHandle *info, SRequestConnInfo* conn, const cha SUserAuthRes authRes = {0}; code = catalogChkAuth(info->pCatalog, conn, &pAuth, &authRes); - nodesDestroyNode(authRes.pCond); + nodesDestroyNode(authRes.pCond[AUTH_RES_BASIC]); - return (code == TSDB_CODE_SUCCESS) ? (authRes.pass ? TSDB_CODE_SUCCESS : TSDB_CODE_PAR_PERMISSION_DENIED) : code; + return (code == TSDB_CODE_SUCCESS) ? (authRes.pass[AUTH_RES_BASIC] ? TSDB_CODE_SUCCESS : TSDB_CODE_PAR_PERMISSION_DENIED) : code; } inline bool smlDoubleToInt64OverFlow(double num) { diff --git a/source/common/src/systable.c b/source/common/src/systable.c index 170c5dc588..51871ebfa5 100644 --- a/source/common/src/systable.c +++ b/source/common/src/systable.c @@ -316,11 +316,13 @@ static const SSysDbTableSchema userUserPrivilegesSchema[] = { {.name = "db_name", .bytes = TSDB_DB_NAME_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, {.name = "table_name", .bytes = TSDB_TABLE_NAME_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, {.name = "condition", .bytes = TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, + {.name = "notes", .bytes = 64 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, }; static const SSysDbTableSchema userViewsSchema[] = { {.name = "view_name", .bytes = SYSTABLE_SCH_VIEW_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, {.name = "db_name", .bytes = SYSTABLE_SCH_DB_NAME_LEN, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, + {.name = "effective_user", .bytes = TSDB_USER_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, {.name = "create_time", .bytes = 8, .type = TSDB_DATA_TYPE_TIMESTAMP, .sysInfo = false}, {.name = "type", .bytes = 128 + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, {.name = "query_sql", .bytes = TSDB_SHOW_SQL_LEN + VARSTR_HEADER_SIZE, .type = TSDB_DATA_TYPE_VARCHAR, .sysInfo = false}, diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index c7804ffc4c..80f9cfe9b7 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -1677,6 +1677,7 @@ int32_t tSerializeSAlterUserReq(void *buf, int32_t bufLen, SAlterUserReq *pReq) if (tEncodeI8(&encoder, pReq->superUser) < 0) return -1; if (tEncodeI8(&encoder, pReq->sysInfo) < 0) return -1; if (tEncodeI8(&encoder, pReq->enable) < 0) return -1; + if (tEncodeI8(&encoder, pReq->isView) < 0) return -1; if (tEncodeCStr(&encoder, pReq->user) < 0) return -1; if (tEncodeCStr(&encoder, pReq->pass) < 0) return -1; if (tEncodeCStr(&encoder, pReq->objname) < 0) return -1; @@ -1709,6 +1710,7 @@ int32_t tDeserializeSAlterUserReq(void *buf, int32_t bufLen, SAlterUserReq *pReq if (tDecodeI8(&decoder, &pReq->superUser) < 0) return -1; if (tDecodeI8(&decoder, &pReq->sysInfo) < 0) return -1; if (tDecodeI8(&decoder, &pReq->enable) < 0) return -1; + if (tDecodeI8(&decoder, &pReq->isView) < 0) return -1; if (tDecodeCStrTo(&decoder, pReq->user) < 0) return -1; if (tDecodeCStrTo(&decoder, pReq->pass) < 0) return -1; if (tDecodeCStrTo(&decoder, pReq->objname) < 0) return -1; @@ -1805,10 +1807,16 @@ int32_t tSerializeSGetUserAuthRspImpl(SEncoder *pEncoder, SGetUserAuthRsp *pRsp) int32_t numOfReadTbs = taosHashGetSize(pRsp->readTbs); int32_t numOfWriteTbs = taosHashGetSize(pRsp->writeTbs); int32_t numOfAlterTbs = taosHashGetSize(pRsp->alterTbs); + int32_t numOfReadViews = taosHashGetSize(pRsp->readViews); + int32_t numOfWriteViews = taosHashGetSize(pRsp->writeViews); + int32_t numOfAlterViews = taosHashGetSize(pRsp->alterViews); int32_t numOfUseDbs = taosHashGetSize(pRsp->useDbs); if (tEncodeI32(pEncoder, numOfReadTbs) < 0) return -1; if (tEncodeI32(pEncoder, numOfWriteTbs) < 0) return -1; if (tEncodeI32(pEncoder, numOfAlterTbs) < 0) return -1; + if (tEncodeI32(pEncoder, numOfReadViews) < 0) return -1; + if (tEncodeI32(pEncoder, numOfWriteViews) < 0) return -1; + if (tEncodeI32(pEncoder, numOfAlterViews) < 0) return -1; if (tEncodeI32(pEncoder, numOfUseDbs) < 0) return -1; char *tb = taosHashIterate(pRsp->readTbs, NULL); @@ -1856,6 +1864,51 @@ int32_t tSerializeSGetUserAuthRspImpl(SEncoder *pEncoder, SGetUserAuthRsp *pRsp) tb = taosHashIterate(pRsp->alterTbs, tb); } + tb = taosHashIterate(pRsp->readViews, NULL); + while (tb != NULL) { + size_t keyLen = 0; + void *key = taosHashGetKey(tb, &keyLen); + if (tEncodeI32(pEncoder, keyLen) < 0) return -1; + if (tEncodeCStr(pEncoder, key) < 0) return -1; + + size_t valueLen = 0; + valueLen = strlen(tb); + if (tEncodeI32(pEncoder, valueLen) < 0) return -1; + if (tEncodeCStr(pEncoder, tb) < 0) return -1; + + tb = taosHashIterate(pRsp->readViews, tb); + } + + tb = taosHashIterate(pRsp->writeViews, NULL); + while (tb != NULL) { + size_t keyLen = 0; + void *key = taosHashGetKey(tb, &keyLen); + if (tEncodeI32(pEncoder, keyLen) < 0) return -1; + if (tEncodeCStr(pEncoder, key) < 0) return -1; + + size_t valueLen = 0; + valueLen = strlen(tb); + if (tEncodeI32(pEncoder, valueLen) < 0) return -1; + if (tEncodeCStr(pEncoder, tb) < 0) return -1; + + tb = taosHashIterate(pRsp->writeViews, tb); + } + + tb = taosHashIterate(pRsp->alterViews, NULL); + while (tb != NULL) { + size_t keyLen = 0; + void *key = taosHashGetKey(tb, &keyLen); + if (tEncodeI32(pEncoder, keyLen) < 0) return -1; + if (tEncodeCStr(pEncoder, key) < 0) return -1; + + size_t valueLen = 0; + valueLen = strlen(tb); + if (tEncodeI32(pEncoder, valueLen) < 0) return -1; + if (tEncodeCStr(pEncoder, tb) < 0) return -1; + + tb = taosHashIterate(pRsp->alterViews, tb); + } + int32_t *useDb = taosHashIterate(pRsp->useDbs, NULL); while (useDb != NULL) { size_t keyLen = 0; @@ -1896,9 +1949,13 @@ int32_t tDeserializeSGetUserAuthRspImpl(SDecoder *pDecoder, SGetUserAuthRsp *pRs pRsp->readTbs = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); pRsp->writeTbs = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); pRsp->alterTbs = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); + pRsp->readViews = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); + pRsp->writeViews = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); + pRsp->alterViews = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); pRsp->useDbs = taosHashInit(4, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); if (pRsp->createdDbs == NULL || pRsp->readDbs == NULL || pRsp->writeDbs == NULL || pRsp->readTbs == NULL || - pRsp->writeTbs == NULL || pRsp->alterTbs == NULL || pRsp->useDbs == NULL) { + pRsp->writeTbs == NULL || pRsp->alterTbs == NULL || pRsp->readViews == NULL || + pRsp->writeViews == NULL || pRsp->alterViews == NULL ||pRsp->useDbs == NULL) { goto _err; } @@ -1941,10 +1998,16 @@ int32_t tDeserializeSGetUserAuthRspImpl(SDecoder *pDecoder, SGetUserAuthRsp *pRs int32_t numOfReadTbs = 0; int32_t numOfWriteTbs = 0; int32_t numOfAlterTbs = 0; + int32_t numOfReadViews = 0; + int32_t numOfWriteViews = 0; + int32_t numOfAlterViews = 0; int32_t numOfUseDbs = 0; if (tDecodeI32(pDecoder, &numOfReadTbs) < 0) goto _err; if (tDecodeI32(pDecoder, &numOfWriteTbs) < 0) goto _err; if (tDecodeI32(pDecoder, &numOfAlterTbs) < 0) goto _err; + if (tDecodeI32(pDecoder, &numOfReadViews) < 0) goto _err; + if (tDecodeI32(pDecoder, &numOfWriteViews) < 0) goto _err; + if (tDecodeI32(pDecoder, &numOfAlterViews) < 0) goto _err; if (tDecodeI32(pDecoder, &numOfUseDbs) < 0) goto _err; for (int32_t i = 0; i < numOfReadTbs; ++i) { @@ -2004,6 +2067,63 @@ int32_t tDeserializeSGetUserAuthRspImpl(SDecoder *pDecoder, SGetUserAuthRsp *pRs taosMemoryFreeClear(value); } + for (int32_t i = 0; i < numOfReadViews; ++i) { + int32_t keyLen = 0; + if (tDecodeI32(pDecoder, &keyLen) < 0) goto _err; + + key = taosMemoryCalloc(keyLen + 1, sizeof(char)); + if (tDecodeCStrTo(pDecoder, key) < 0) goto _err; + + int32_t valuelen = 0; + if (tDecodeI32(pDecoder, &valuelen) < 0) goto _err; + + value = taosMemoryCalloc(valuelen + 1, sizeof(char)); + if (tDecodeCStrTo(pDecoder, value) < 0) goto _err; + + taosHashPut(pRsp->readViews, key, strlen(key), value, valuelen + 1); + + taosMemoryFreeClear(key); + taosMemoryFreeClear(value); + } + + for (int32_t i = 0; i < numOfWriteViews; ++i) { + int32_t keyLen = 0; + if (tDecodeI32(pDecoder, &keyLen) < 0) goto _err; + + key = taosMemoryCalloc(keyLen + 1, sizeof(char)); + if (tDecodeCStrTo(pDecoder, key) < 0) goto _err; + + int32_t valuelen = 0; + if (tDecodeI32(pDecoder, &valuelen) < 0) goto _err; + + value = taosMemoryCalloc(valuelen + 1, sizeof(char)); + if (tDecodeCStrTo(pDecoder, value) < 0) goto _err; + + taosHashPut(pRsp->writeViews, key, strlen(key), value, valuelen + 1); + + taosMemoryFreeClear(key); + taosMemoryFreeClear(value); + } + + for (int32_t i = 0; i < numOfAlterViews; ++i) { + int32_t keyLen = 0; + if (tDecodeI32(pDecoder, &keyLen) < 0) goto _err; + + key = taosMemoryCalloc(keyLen + 1, sizeof(char)); + if (tDecodeCStrTo(pDecoder, key) < 0) goto _err; + + int32_t valuelen = 0; + if (tDecodeI32(pDecoder, &valuelen) < 0) goto _err; + + value = taosMemoryCalloc(valuelen + 1, sizeof(char)); + if (tDecodeCStrTo(pDecoder, value) < 0) goto _err; + + taosHashPut(pRsp->alterViews, key, strlen(key), value, valuelen + 1); + + taosMemoryFreeClear(key); + taosMemoryFreeClear(value); + } + for (int32_t i = 0; i < numOfUseDbs; ++i) { int32_t keyLen = 0; if (tDecodeI32(pDecoder, &keyLen) < 0) goto _err; @@ -2034,8 +2154,12 @@ _err: taosHashCleanup(pRsp->createdDbs); taosHashCleanup(pRsp->readDbs); taosHashCleanup(pRsp->writeDbs); - taosHashCleanup(pRsp->writeTbs); taosHashCleanup(pRsp->readTbs); + taosHashCleanup(pRsp->writeTbs); + taosHashCleanup(pRsp->alterTbs); + taosHashCleanup(pRsp->readViews); + taosHashCleanup(pRsp->writeViews); + taosHashCleanup(pRsp->alterViews); taosHashCleanup(pRsp->useDbs); taosMemoryFreeClear(key); @@ -2061,9 +2185,12 @@ void tFreeSGetUserAuthRsp(SGetUserAuthRsp *pRsp) { taosHashCleanup(pRsp->createdDbs); taosHashCleanup(pRsp->readDbs); taosHashCleanup(pRsp->writeDbs); - taosHashCleanup(pRsp->writeTbs); taosHashCleanup(pRsp->readTbs); + taosHashCleanup(pRsp->writeTbs); taosHashCleanup(pRsp->alterTbs); + taosHashCleanup(pRsp->readViews); + taosHashCleanup(pRsp->writeViews); + taosHashCleanup(pRsp->alterViews); taosHashCleanup(pRsp->useDbs); } @@ -8834,6 +8961,7 @@ int32_t tDeserializeSViewMetaReq(void* buf, int32_t bufLen, SViewMetaReq* pReq) static int32_t tEncodeSViewMetaRsp(SEncoder *pEncoder, const SViewMetaRsp *pRsp) { if (tEncodeCStr(pEncoder, pRsp->name) < 0) return -1; if (tEncodeCStr(pEncoder, pRsp->dbFName) < 0) return -1; + if (tEncodeCStr(pEncoder, pRsp->user) < 0) return -1; if (tEncodeU64(pEncoder, pRsp->dbId) < 0) return -1; if (tEncodeU64(pEncoder, pRsp->viewId) < 0) return -1; if (tEncodeCStr(pEncoder, pRsp->querySql) < 0) return -1; @@ -8867,6 +8995,7 @@ int32_t tSerializeSViewMetaRsp(void* buf, int32_t bufLen, const SViewMetaRsp* pR static int32_t tDecodeSViewMetaRsp(SDecoder *pDecoder, SViewMetaRsp *pRsp) { if (tDecodeCStrTo(pDecoder, pRsp->name) < 0) return -1; if (tDecodeCStrTo(pDecoder, pRsp->dbFName) < 0) return -1; + if (tDecodeCStrAlloc(pDecoder, &pRsp->user) < 0) return -1; if (tDecodeU64(pDecoder, &pRsp->dbId) < 0) return -1; if (tDecodeU64(pDecoder, &pRsp->viewId) < 0) return -1; if (tDecodeCStrAlloc(pDecoder, &pRsp->querySql) < 0) return -1; @@ -8908,6 +9037,7 @@ void tFreeSViewMetaRsp(SViewMetaRsp* pRsp) { return; } + taosMemoryFree(pRsp->user); taosMemoryFree(pRsp->querySql); taosMemoryFree(pRsp->pSchema); } diff --git a/source/dnode/mnode/impl/src/mndInfoSchema.c b/source/dnode/mnode/impl/src/mndInfoSchema.c index f17df28129..689da5a855 100644 --- a/source/dnode/mnode/impl/src/mndInfoSchema.c +++ b/source/dnode/mnode/impl/src/mndInfoSchema.c @@ -78,7 +78,7 @@ int32_t mndBuildInsTableSchema(SMnode *pMnode, const char *dbFName, const char * STableMetaRsp *pMeta = taosHashGet(pMnode->infosMeta, tbName, strlen(tbName)); if (NULL == pMeta) { mError("invalid information schema table name:%s", tbName); - terrno = TSDB_CODE_MND_INVALID_SYS_TABLENAME; + terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST; return -1; } @@ -111,7 +111,7 @@ int32_t mndBuildInsTableCfg(SMnode *pMnode, const char *dbFName, const char *tbN STableMetaRsp *pMeta = taosHashGet(pMnode->infosMeta, tbName, strlen(tbName)); if (NULL == pMeta) { mError("invalid information schema table name:%s", tbName); - terrno = TSDB_CODE_MND_INVALID_SYS_TABLENAME; + terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST; return -1; } diff --git a/source/dnode/mnode/impl/src/mndPerfSchema.c b/source/dnode/mnode/impl/src/mndPerfSchema.c index cf463304a1..33dc63bdf4 100644 --- a/source/dnode/mnode/impl/src/mndPerfSchema.c +++ b/source/dnode/mnode/impl/src/mndPerfSchema.c @@ -75,7 +75,7 @@ int32_t mndBuildPerfsTableSchema(SMnode *pMnode, const char *dbFName, const char STableMetaRsp *meta = (STableMetaRsp *)taosHashGet(pMnode->perfsMeta, tbName, strlen(tbName)); if (NULL == meta) { mError("invalid performance schema table name:%s", tbName); - terrno = TSDB_CODE_MND_INVALID_SYS_TABLENAME; + terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST; return -1; } @@ -101,7 +101,7 @@ int32_t mndBuildPerfsTableCfg(SMnode *pMnode, const char *dbFName, const char *t STableMetaRsp *pMeta = taosHashGet(pMnode->perfsMeta, tbName, strlen(tbName)); if (NULL == pMeta) { mError("invalid performance schema table name:%s", tbName); - terrno = TSDB_CODE_MND_INVALID_SYS_TABLENAME; + terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST; return -1; } diff --git a/source/dnode/mnode/impl/src/mndShow.c b/source/dnode/mnode/impl/src/mndShow.c index 5348cc17d0..bdf7df25e1 100644 --- a/source/dnode/mnode/impl/src/mndShow.c +++ b/source/dnode/mnode/impl/src/mndShow.c @@ -213,7 +213,7 @@ static int32_t mndProcessRetrieveSysTableReq(SRpcMsg *pReq) { if (pMeta == NULL) { pMeta = taosHashGet(pMnode->perfsMeta, retrieveReq.tb, strlen(retrieveReq.tb)); if (pMeta == NULL) { - terrno = TSDB_CODE_MND_INVALID_SYS_TABLENAME; + terrno = TSDB_CODE_PAR_TABLE_NOT_EXIST; mError("failed to process show-retrieve req:%p since %s", pShow, terrstr()); return -1; } diff --git a/source/dnode/mnode/impl/src/mndUser.c b/source/dnode/mnode/impl/src/mndUser.c index 5077820148..11d75934be 100644 --- a/source/dnode/mnode/impl/src/mndUser.c +++ b/source/dnode/mnode/impl/src/mndUser.c @@ -48,7 +48,7 @@ #define ALTER_USER_READ_PRIV(_priv) (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_READ) || BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALL)) #define ALTER_USER_WRITE_PRIV(_priv) (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_WRITE) || BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALL)) #define ALTER_USER_ALTER_PRIV(_priv) (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALTER) || BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALL)) -#define ALTER_USER_SUBSCRIBE_PRIV(_priv) (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_SUBSCRIBE) || BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_ALL)) +#define ALTER_USER_SUBSCRIBE_PRIV(_priv) (BIT_FLAG_TEST_MASK((_priv), PRIVILEGE_TYPE_SUBSCRIBE)) #define ALTER_USER_TARGET_DB(_tbname) (0 == (_tbname)[0]) #define ALTER_USER_TARGET_TB(_tbname) (0 != (_tbname)[0]) @@ -703,6 +703,9 @@ SSdbRaw *mndUserActionEncode(SUserObj *pUser) { int32_t numOfReadTbs = taosHashGetSize(pUser->readTbs); int32_t numOfWriteTbs = taosHashGetSize(pUser->writeTbs); int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs); + int32_t numOfReadViews = taosHashGetSize(pUser->readViews); + int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews); + int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews); int32_t numOfTopics = taosHashGetSize(pUser->topics); int32_t numOfUseDbs = taosHashGetSize(pUser->useDbs); int32_t size = sizeof(SUserObj) + USER_RESERVE_SIZE + @@ -751,6 +754,48 @@ SSdbRaw *mndUserActionEncode(SUserObj *pUser) { stb = taosHashIterate(pUser->alterTbs, stb); } + stb = taosHashIterate(pUser->readViews, NULL); + while (stb != NULL) { + size_t keyLen = 0; + void *key = taosHashGetKey(stb, &keyLen); + size += sizeof(int32_t); + size += keyLen; + + size_t valueLen = 0; + valueLen = strlen(stb); + size += sizeof(int32_t); + size += valueLen; + stb = taosHashIterate(pUser->readViews, stb); + } + + stb = taosHashIterate(pUser->writeViews, NULL); + while (stb != NULL) { + size_t keyLen = 0; + void *key = taosHashGetKey(stb, &keyLen); + size += sizeof(int32_t); + size += keyLen; + + size_t valueLen = 0; + valueLen = strlen(stb); + size += sizeof(int32_t); + size += valueLen; + stb = taosHashIterate(pUser->writeViews, stb); + } + + stb = taosHashIterate(pUser->alterViews, NULL); + while (stb != NULL) { + size_t keyLen = 0; + void *key = taosHashGetKey(stb, &keyLen); + size += sizeof(int32_t); + size += keyLen; + + size_t valueLen = 0; + valueLen = strlen(stb); + size += sizeof(int32_t); + size += valueLen; + stb = taosHashIterate(pUser->alterViews, stb); + } + SSdbRaw *pRaw = sdbAllocRaw(SDB_USER, USER_VER_NUMBER, size); if (pRaw == NULL) goto _OVER; @@ -791,6 +836,9 @@ SSdbRaw *mndUserActionEncode(SUserObj *pUser) { SDB_SET_INT32(pRaw, dataPos, numOfReadTbs, _OVER) SDB_SET_INT32(pRaw, dataPos, numOfWriteTbs, _OVER) SDB_SET_INT32(pRaw, dataPos, numOfAlterTbs, _OVER) + SDB_SET_INT32(pRaw, dataPos, numOfReadViews, _OVER) + SDB_SET_INT32(pRaw, dataPos, numOfWriteViews, _OVER) + SDB_SET_INT32(pRaw, dataPos, numOfAlterViews, _OVER) SDB_SET_INT32(pRaw, dataPos, numOfUseDbs, _OVER) stb = taosHashIterate(pUser->readTbs, NULL); @@ -835,6 +883,48 @@ SSdbRaw *mndUserActionEncode(SUserObj *pUser) { stb = taosHashIterate(pUser->alterTbs, stb); } + stb = taosHashIterate(pUser->readViews, NULL); + while (stb != NULL) { + size_t keyLen = 0; + void *key = taosHashGetKey(stb, &keyLen); + SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER) + SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER); + + size_t valueLen = 0; + valueLen = strlen(stb) + 1; + SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER) + SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER); + stb = taosHashIterate(pUser->readViews, stb); + } + + stb = taosHashIterate(pUser->writeViews, NULL); + while (stb != NULL) { + size_t keyLen = 0; + void *key = taosHashGetKey(stb, &keyLen); + SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER) + SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER); + + size_t valueLen = 0; + valueLen = strlen(stb) + 1; + SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER) + SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER); + stb = taosHashIterate(pUser->writeViews, stb); + } + + stb = taosHashIterate(pUser->alterViews, NULL); + while (stb != NULL) { + size_t keyLen = 0; + void *key = taosHashGetKey(stb, &keyLen); + SDB_SET_INT32(pRaw, dataPos, keyLen, _OVER) + SDB_SET_BINARY(pRaw, dataPos, key, keyLen, _OVER); + + size_t valueLen = 0; + valueLen = strlen(stb) + 1; + SDB_SET_INT32(pRaw, dataPos, valueLen, _OVER) + SDB_SET_BINARY(pRaw, dataPos, stb, valueLen, _OVER); + stb = taosHashIterate(pUser->alterViews, stb); + } + int32_t *useDb = taosHashIterate(pUser->useDbs, NULL); while (useDb != NULL) { size_t keyLen = 0; @@ -950,11 +1040,17 @@ static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) { int32_t numOfReadTbs = 0; int32_t numOfWriteTbs = 0; int32_t numOfAlterTbs = 0; + int32_t numOfReadViews = 0; + int32_t numOfWriteViews = 0; + int32_t numOfAlterViews = 0; int32_t numOfUseDbs = 0; SDB_GET_INT32(pRaw, dataPos, &numOfReadTbs, _OVER) SDB_GET_INT32(pRaw, dataPos, &numOfWriteTbs, _OVER) if (sver >= 6) { SDB_GET_INT32(pRaw, dataPos, &numOfAlterTbs, _OVER) + SDB_GET_INT32(pRaw, dataPos, &numOfReadViews, _OVER) + SDB_GET_INT32(pRaw, dataPos, &numOfWriteViews, _OVER) + SDB_GET_INT32(pRaw, dataPos, &numOfAlterViews, _OVER) } SDB_GET_INT32(pRaw, dataPos, &numOfUseDbs, _OVER) @@ -965,6 +1061,13 @@ static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) { pUser->alterTbs = taosHashInit(numOfAlterTbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); + pUser->readViews = + taosHashInit(numOfReadViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); + pUser->writeViews = + taosHashInit(numOfWriteViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); + pUser->alterViews = + taosHashInit(numOfAlterViews, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); + pUser->useDbs = taosHashInit(numOfUseDbs, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BINARY), true, HASH_ENTRY_LOCK); for (int32_t i = 0; i < numOfReadTbs; ++i) { @@ -1027,6 +1130,66 @@ static SSdbRow *mndUserActionDecode(SSdbRaw *pRaw) { taosMemoryFree(key); taosMemoryFree(value); } + + for (int32_t i = 0; i < numOfReadViews; ++i) { + int32_t keyLen = 0; + SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER); + + char *key = taosMemoryCalloc(keyLen, sizeof(char)); + memset(key, 0, keyLen); + SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER); + + int32_t valuelen = 0; + SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER); + char *value = taosMemoryCalloc(valuelen, sizeof(char)); + memset(value, 0, valuelen); + SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER) + + taosHashPut(pUser->readViews, key, keyLen, value, valuelen); + + taosMemoryFree(key); + taosMemoryFree(value); + } + + for (int32_t i = 0; i < numOfWriteViews; ++i) { + int32_t keyLen = 0; + SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER); + + char *key = taosMemoryCalloc(keyLen, sizeof(char)); + memset(key, 0, keyLen); + SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER); + + int32_t valuelen = 0; + SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER); + char *value = taosMemoryCalloc(valuelen, sizeof(char)); + memset(value, 0, valuelen); + SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER) + + taosHashPut(pUser->writeViews, key, keyLen, value, valuelen); + + taosMemoryFree(key); + taosMemoryFree(value); + } + + for (int32_t i = 0; i < numOfAlterViews; ++i) { + int32_t keyLen = 0; + SDB_GET_INT32(pRaw, dataPos, &keyLen, _OVER); + + char *key = taosMemoryCalloc(keyLen, sizeof(char)); + memset(key, 0, keyLen); + SDB_GET_BINARY(pRaw, dataPos, key, keyLen, _OVER); + + int32_t valuelen = 0; + SDB_GET_INT32(pRaw, dataPos, &valuelen, _OVER); + char *value = taosMemoryCalloc(valuelen, sizeof(char)); + memset(value, 0, valuelen); + SDB_GET_BINARY(pRaw, dataPos, value, valuelen, _OVER) + + taosHashPut(pUser->alterViews, key, keyLen, value, valuelen); + + taosMemoryFree(key); + taosMemoryFree(value); + } } for (int32_t i = 0; i < numOfUseDbs; ++i) { @@ -1079,6 +1242,9 @@ _OVER: taosHashCleanup(pUser->readTbs); taosHashCleanup(pUser->writeTbs); taosHashCleanup(pUser->alterTbs); + taosHashCleanup(pUser->readViews); + taosHashCleanup(pUser->writeViews); + taosHashCleanup(pUser->alterViews); taosHashCleanup(pUser->useDbs); taosMemoryFreeClear(pUser->pIpWhiteList); } @@ -1167,6 +1333,9 @@ int32_t mndUserDupObj(SUserObj *pUser, SUserObj *pNew) { pNew->readTbs = mndDupTableHash(pUser->readTbs); pNew->writeTbs = mndDupTableHash(pUser->writeTbs); pNew->alterTbs = mndDupTableHash(pUser->alterTbs); + pNew->readViews = mndDupTableHash(pUser->readViews); + pNew->writeViews = mndDupTableHash(pUser->writeViews); + pNew->alterViews = mndDupTableHash(pUser->alterViews); pNew->topics = mndDupTopicHash(pUser->topics); pNew->useDbs = mndDupUseDbHash(pUser->useDbs); pNew->pIpWhiteList = cloneIpWhiteList(pUser->pIpWhiteList); @@ -1186,6 +1355,9 @@ void mndUserFreeObj(SUserObj *pUser) { taosHashCleanup(pUser->readTbs); taosHashCleanup(pUser->writeTbs); taosHashCleanup(pUser->alterTbs); + taosHashCleanup(pUser->readViews); + taosHashCleanup(pUser->writeViews); + taosHashCleanup(pUser->alterViews); taosHashCleanup(pUser->useDbs); taosMemoryFreeClear(pUser->pIpWhiteList); pUser->readDbs = NULL; @@ -1194,6 +1366,9 @@ void mndUserFreeObj(SUserObj *pUser) { pUser->readTbs = NULL; pUser->writeTbs = NULL; pUser->alterTbs = NULL; + pUser->readViews = NULL; + pUser->writeViews = NULL; + pUser->alterViews = NULL; pUser->useDbs = NULL; } @@ -1218,6 +1393,9 @@ static int32_t mndUserActionUpdate(SSdb *pSdb, SUserObj *pOld, SUserObj *pNew) { TSWAP(pOld->readTbs, pNew->readTbs); TSWAP(pOld->writeTbs, pNew->writeTbs); TSWAP(pOld->alterTbs, pNew->alterTbs); + TSWAP(pOld->readViews, pNew->readViews); + TSWAP(pOld->writeViews, pNew->writeViews); + TSWAP(pOld->alterViews, pNew->alterViews); TSWAP(pOld->useDbs, pNew->useDbs); int32_t sz = sizeof(SIpWhiteList) + pNew->pIpWhiteList->num * sizeof(SIpV4Range); @@ -1537,7 +1715,7 @@ static int32_t mndTablePriviledge(SMnode *pMnode, SHashObj *hash, SHashObj *useD return -1; } } else { - if (taosHashPut(hash, tbFName, len, "t", 2) != 0) { + if (taosHashPut(hash, tbFName, len, alterReq->isView ? "v" : "t", 2) != 0) { return -1; } } @@ -1683,31 +1861,43 @@ static int32_t mndProcessAlterUserPrivilegesReq(SAlterUserReq *pAlterReq, SMnode } } + SHashObj* pReadTbs = pNewUser->readTbs; + SHashObj* pWriteTbs = pNewUser->writeTbs; + SHashObj* pAlterTbs = pNewUser->alterTbs; + +#ifdef TD_ENTERPRISE + if (pAlterReq->isView) { + pReadTbs = pNewUser->readViews; + pWriteTbs = pNewUser->writeViews; + pAlterTbs = pNewUser->alterViews; + } +#endif + if (ALTER_USER_ADD_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) || ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) { - if (mndTablePriviledge(pMnode, pNewUser->readTbs, pNewUser->useDbs, pAlterReq, pSdb) != 0) return -1; + if (mndTablePriviledge(pMnode, pReadTbs, pNewUser->useDbs, pAlterReq, pSdb) != 0) return -1; } if (ALTER_USER_ADD_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) || ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) { - if (mndTablePriviledge(pMnode, pNewUser->writeTbs, pNewUser->useDbs, pAlterReq, pSdb) != 0) return -1; + if (mndTablePriviledge(pMnode, pWriteTbs, pNewUser->useDbs, pAlterReq, pSdb) != 0) return -1; } if (ALTER_USER_ADD_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) || ALTER_USER_ADD_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) { - if (mndTablePriviledge(pMnode, pNewUser->alterTbs, pNewUser->useDbs, pAlterReq, pSdb) != 0) return -1; + if (mndTablePriviledge(pMnode, pAlterTbs, pNewUser->useDbs, pAlterReq, pSdb) != 0) return -1; } if (ALTER_USER_DEL_READ_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) || ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) { - if (mndRemoveTablePriviledge(pMnode, pNewUser->readTbs, pNewUser->useDbs, pAlterReq, pSdb) != 0) return -1; + if (mndRemoveTablePriviledge(pMnode, pReadTbs, pNewUser->useDbs, pAlterReq, pSdb) != 0) return -1; } if (ALTER_USER_DEL_WRITE_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) || ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) { - if (mndRemoveTablePriviledge(pMnode, pNewUser->writeTbs, pNewUser->useDbs, pAlterReq, pSdb) != 0) return -1; + if (mndRemoveTablePriviledge(pMnode, pWriteTbs, pNewUser->useDbs, pAlterReq, pSdb) != 0) return -1; } if (ALTER_USER_DEL_ALTER_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName) || ALTER_USER_DEL_ALL_TB_PRIV(pAlterReq->alterType, pAlterReq->privileges, pAlterReq->tabName)) { - if (mndRemoveTablePriviledge(pMnode, pNewUser->alterTbs, pNewUser->useDbs, pAlterReq, pSdb) != 0) return -1; + if (mndRemoveTablePriviledge(pMnode, pAlterTbs, pNewUser->useDbs, pAlterReq, pSdb) != 0) return -1; } if (ALTER_USER_ADD_SUBSCRIBE_TOPIC_PRIV(pAlterReq->alterType, pAlterReq->privileges)) { @@ -2176,7 +2366,7 @@ static void mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int3 pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); colDataSetVal(pColInfo, *numOfRows, (const char *)tableNameContent, false); - if (strcmp("t", value) != 0) { + if (strcmp("t", value) != 0 && strcmp("v", value) != 0) { SNode *pAst = NULL; int32_t sqlLen = 0; size_t bufSz = strlen(value) + 1; @@ -2197,12 +2387,22 @@ static void mndLoopHash(SHashObj *hash, char *priType, SSDataBlock *pBlock, int3 colDataSetVal(pColInfo, *numOfRows, (const char *)obj, false); taosMemoryFree(obj); taosMemoryFree(sql); + + char notes[2] = {0}; + STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes)); + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); + colDataSetVal(pColInfo, *numOfRows, (const char *)notes, false); } else { char *condition = taosMemoryMalloc(TSDB_PRIVILEDGE_CONDITION_LEN + VARSTR_HEADER_SIZE); STR_WITH_MAXSIZE_TO_VARSTR(condition, "", pShow->pMeta->pSchemas[cols].bytes); pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); colDataSetVal(pColInfo, *numOfRows, (const char *)condition, false); taosMemoryFree(condition); + + char notes[64 + VARSTR_HEADER_SIZE] = {0}; + STR_WITH_MAXSIZE_TO_VARSTR(notes, value[0] == 'v' ? "view" : "", sizeof(notes)); + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); + colDataSetVal(pColInfo, *numOfRows, (const char *)notes, false); } (*numOfRows)++; @@ -2240,11 +2440,14 @@ static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock int32_t numOfReadTbs = taosHashGetSize(pUser->readTbs); int32_t numOfWriteTbs = taosHashGetSize(pUser->writeTbs); int32_t numOfAlterTbs = taosHashGetSize(pUser->alterTbs); - if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics + numOfReadTbs + numOfWriteTbs + numOfAlterTbs >= rows) { + int32_t numOfReadViews = taosHashGetSize(pUser->readViews); + int32_t numOfWriteViews = taosHashGetSize(pUser->writeViews); + int32_t numOfAlterViews = taosHashGetSize(pUser->alterViews); + if (numOfRows + numOfReadDbs + numOfWriteDbs + numOfTopics + numOfReadTbs + numOfWriteTbs + numOfAlterTbs + numOfReadViews + numOfWriteViews + numOfAlterViews >= rows) { mInfo( "will restore. current num of rows: %d, read dbs %d, write dbs %d, topics %d, read tables %d, write tables " - "%d, alter tables %d", - numOfRows, numOfReadDbs, numOfWriteDbs, numOfTopics, numOfReadTbs, numOfWriteTbs, numOfAlterTbs); + "%d, alter tables %d, read views %d, write views %d, alter views %d", + numOfRows, numOfReadDbs, numOfWriteDbs, numOfTopics, numOfReadTbs, numOfWriteTbs, numOfAlterTbs, numOfReadViews, numOfWriteViews, numOfAlterViews); pShow->restore = true; sdbRelease(pSdb, pUser); break; @@ -2278,6 +2481,11 @@ static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock colDataSetVal(pColInfo, numOfRows, (const char *)condition, false); taosMemoryFree(condition); + char notes[2] = {0}; + STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes)); + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); + colDataSetVal(pColInfo, numOfRows, (const char *)notes, false); + numOfRows++; } @@ -2313,6 +2521,11 @@ static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock colDataSetVal(pColInfo, numOfRows, (const char *)condition, false); taosMemoryFree(condition); + char notes[2] = {0}; + STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes)); + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); + colDataSetVal(pColInfo, numOfRows, (const char *)notes, false); + numOfRows++; db = taosHashIterate(pUser->readDbs, db); } @@ -2349,6 +2562,11 @@ static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock colDataSetVal(pColInfo, numOfRows, (const char *)condition, false); taosMemoryFree(condition); + char notes[2] = {0}; + STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes)); + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); + colDataSetVal(pColInfo, numOfRows, (const char *)notes, false); + numOfRows++; db = taosHashIterate(pUser->writeDbs, db); } @@ -2359,6 +2577,12 @@ static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock mndLoopHash(pUser->alterTbs, "alter", pBlock, &numOfRows, pUser->user, pShow); + mndLoopHash(pUser->readViews, "read", pBlock, &numOfRows, pUser->user, pShow); + + mndLoopHash(pUser->writeViews, "write", pBlock, &numOfRows, pUser->user, pShow); + + mndLoopHash(pUser->alterViews, "alter", pBlock, &numOfRows, pUser->user, pShow); + char *topic = taosHashIterate(pUser->topics, NULL); while (topic != NULL) { cols = 0; @@ -2389,6 +2613,11 @@ static int32_t mndRetrievePrivileges(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock colDataSetVal(pColInfo, numOfRows, (const char *)condition, false); taosMemoryFree(condition); + char notes[2] = {0}; + STR_WITH_MAXSIZE_TO_VARSTR(notes, "", sizeof(notes)); + pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); + colDataSetVal(pColInfo, numOfRows, (const char *)notes, false); + numOfRows++; topic = taosHashIterate(pUser->topics, topic); } diff --git a/source/libs/catalog/src/ctgAsync.c b/source/libs/catalog/src/ctgAsync.c index 6dca0a7cfa..c8b87a3cb7 100644 --- a/source/libs/catalog/src/ctgAsync.c +++ b/source/libs/catalog/src/ctgAsync.c @@ -1861,7 +1861,6 @@ int32_t ctgHandleGetViewsRsp(SCtgTaskReq* tReq, int32_t reqType, const SDataBuf* CTG_ERR_JRET(TSDB_CODE_OUT_OF_MEMORY); } - dupViewMetaFromRsp(pRsp, pViewMeta); if (TSDB_CODE_SUCCESS != (code = dupViewMetaFromRsp(pRsp, pViewMeta))) { ctgFreeSViewMeta(pViewMeta); taosMemoryFree(pViewMeta); @@ -2446,7 +2445,8 @@ int32_t ctgLaunchGetUserTask(SCtgTask* pTask) { if (inCache) { pTask->res = rsp.pRawRes; - ctgTaskDebug("Final res got, pass:%d, pCond:%p", rsp.pRawRes->pass, rsp.pRawRes->pCond); + ctgTaskDebug("Final res got, pass:[%d,%d], pCond:[%p,%p]", + rsp.pRawRes->pass[0], rsp.pRawRes->pass[1], rsp.pRawRes->pCond[0], rsp.pRawRes->pCond[1]); CTG_ERR_RET(ctgHandleTaskEnd(pTask, 0)); return TSDB_CODE_SUCCESS; diff --git a/source/libs/catalog/src/ctgCache.c b/source/libs/catalog/src/ctgCache.c index 37f05304d4..6ce4a2727e 100644 --- a/source/libs/catalog/src/ctgCache.c +++ b/source/libs/catalog/src/ctgCache.c @@ -2178,6 +2178,9 @@ int32_t ctgOpUpdateUser(SCtgCacheOperation *operation) { taosHashCleanup(pUser->userAuth.readTbs); taosHashCleanup(pUser->userAuth.writeTbs); taosHashCleanup(pUser->userAuth.alterTbs); + taosHashCleanup(pUser->userAuth.readViews); + taosHashCleanup(pUser->userAuth.writeViews); + taosHashCleanup(pUser->userAuth.alterViews); taosHashCleanup(pUser->userAuth.useDbs); memcpy(&pUser->userAuth, &msg->userAuth, sizeof(msg->userAuth)); @@ -2188,6 +2191,9 @@ int32_t ctgOpUpdateUser(SCtgCacheOperation *operation) { msg->userAuth.readTbs = NULL; msg->userAuth.writeTbs = NULL; msg->userAuth.alterTbs = NULL; + msg->userAuth.readViews = NULL; + msg->userAuth.writeViews = NULL; + msg->userAuth.alterViews = NULL; msg->userAuth.useDbs = NULL; CTG_UNLOCK(CTG_WRITE, &pUser->lock); @@ -2202,6 +2208,9 @@ _return: taosHashCleanup(msg->userAuth.readTbs); taosHashCleanup(msg->userAuth.writeTbs); taosHashCleanup(msg->userAuth.alterTbs); + taosHashCleanup(msg->userAuth.readViews); + taosHashCleanup(msg->userAuth.writeViews); + taosHashCleanup(msg->userAuth.alterViews); taosHashCleanup(msg->userAuth.useDbs); taosMemoryFreeClear(msg); @@ -2540,6 +2549,9 @@ void ctgFreeCacheOperationData(SCtgCacheOperation *op) { taosHashCleanup(msg->userAuth.readTbs); taosHashCleanup(msg->userAuth.writeTbs); taosHashCleanup(msg->userAuth.alterTbs); + taosHashCleanup(msg->userAuth.readViews); + taosHashCleanup(msg->userAuth.writeViews); + taosHashCleanup(msg->userAuth.alterViews); taosHashCleanup(msg->userAuth.useDbs); taosMemoryFreeClear(op->data); break; @@ -3075,9 +3087,12 @@ int32_t ctgGetViewsFromCache(SCatalog *pCtg, SRequestConnInfo *pConn, SCtgViewsC memcpy(pViewMeta, pCache->pMeta, sizeof(*pViewMeta)); pViewMeta->querySql = strdup(pCache->pMeta->querySql); - if (NULL == pViewMeta->querySql) { + pViewMeta->user = strdup(pCache->pMeta->user); + if (NULL == pViewMeta->querySql || NULL == pViewMeta->user) { ctgReleaseViewMetaToCache(pCtg, dbCache, pCache); pViewMeta->pSchema = NULL; + taosMemoryFree(pViewMeta->querySql); + taosMemoryFree(pViewMeta->user); taosMemoryFree(pViewMeta); CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY); } diff --git a/source/libs/catalog/src/ctgUtil.c b/source/libs/catalog/src/ctgUtil.c index 1fa31e0eac..04b3bce6ee 100644 --- a/source/libs/catalog/src/ctgUtil.c +++ b/source/libs/catalog/src/ctgUtil.c @@ -24,6 +24,7 @@ void ctgFreeSViewMeta(SViewMeta* pMeta) { return; } + taosMemoryFree(pMeta->user); taosMemoryFree(pMeta->querySql); taosMemoryFree(pMeta->pSchema); } @@ -196,6 +197,9 @@ void ctgFreeSCtgUserAuth(SCtgUserAuth* userCache) { taosHashCleanup(userCache->userAuth.readTbs); taosHashCleanup(userCache->userAuth.writeTbs); taosHashCleanup(userCache->userAuth.alterTbs); + taosHashCleanup(userCache->userAuth.readViews); + taosHashCleanup(userCache->userAuth.writeViews); + taosHashCleanup(userCache->userAuth.alterViews); taosHashCleanup(userCache->userAuth.useDbs); } @@ -567,6 +571,9 @@ void ctgFreeMsgCtx(SCtgMsgCtx* pCtx) { taosHashCleanup(pOut->readTbs); taosHashCleanup(pOut->writeTbs); taosHashCleanup(pOut->alterTbs); + taosHashCleanup(pOut->readViews); + taosHashCleanup(pOut->writeViews); + taosHashCleanup(pOut->alterViews); taosHashCleanup(pOut->useDbs); taosMemoryFreeClear(pCtx->out); break; @@ -697,7 +704,9 @@ void ctgFreeTaskRes(CTG_TASK_TYPE type, void** pRes) { case CTG_TASK_GET_USER: { if (*pRes) { SUserAuthRes* pAuth = (SUserAuthRes*)*pRes; - nodesDestroyNode(pAuth->pCond); + for (int32_t i = 0; i < AUTH_RES_MAX_VALUE; ++i) { + nodesDestroyNode(pAuth->pCond[i]); + } taosMemoryFreeClear(*pRes); } break; @@ -1635,15 +1644,15 @@ int32_t ctgChkSetTbAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res) { char* pCond = taosHashGet(pTbs, tbFName, strlen(tbFName)); if (pCond) { if (strlen(pCond) > 1) { - CTG_ERR_JRET(nodesStringToNode(pCond, &res->pRawRes->pCond)); + CTG_ERR_JRET(nodesStringToNode(pCond, &res->pRawRes->pCond[AUTH_RES_BASIC])); } - res->pRawRes->pass = true; + res->pRawRes->pass[AUTH_RES_BASIC] = true; goto _return; } if (stbName) { - res->pRawRes->pass = false; + res->pRawRes->pass[AUTH_RES_BASIC] = false; goto _return; } @@ -1663,7 +1672,7 @@ int32_t ctgChkSetTbAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res) { } if (TSDB_SUPER_TABLE == pMeta->tableType || TSDB_NORMAL_TABLE == pMeta->tableType) { - res->pRawRes->pass = false; + res->pRawRes->pass[AUTH_RES_BASIC] = false; goto _return; } @@ -1695,27 +1704,27 @@ _return: CTG_RET(code); } -int32_t ctgChkSetAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res) { +int32_t ctgChkSetBasicAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res) { int32_t code = 0; SUserAuthInfo* pReq = req->pRawReq; SUserAuthRes* pRes = res->pRawRes; SGetUserAuthRsp* pInfo = &req->authInfo; - pRes->pass = false; - pRes->pCond = NULL; + pRes->pass[AUTH_RES_BASIC] = false; + pRes->pCond[AUTH_RES_BASIC] = NULL; if (!pInfo->enable) { - pRes->pass = false; + pRes->pass[AUTH_RES_BASIC] = false; return TSDB_CODE_SUCCESS; } if (pInfo->superAuth) { - pRes->pass = true; + pRes->pass[AUTH_RES_BASIC] = true; return TSDB_CODE_SUCCESS; } if (IS_SYS_DBNAME(pReq->tbName.dbname)) { - pRes->pass = true; + pRes->pass[AUTH_RES_BASIC] = true; ctgDebug("sysdb %s, pass", pReq->tbName.dbname); return TSDB_CODE_SUCCESS; } @@ -1736,13 +1745,13 @@ int32_t ctgChkSetAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res) { if (pReq->tbName.type == TSDB_TABLE_NAME_T && pInfo->readTbs && taosHashGetSize(pInfo->readTbs) > 0) { req->singleType = AUTH_TYPE_READ; CTG_ERR_RET(ctgChkSetTbAuthRes(pCtg, req, res)); - if (pRes->pass || res->metaNotExists) { + if (pRes->pass[AUTH_RES_BASIC] || res->metaNotExists) { return TSDB_CODE_SUCCESS; } } if (pInfo->readDbs && taosHashGet(pInfo->readDbs, dbFName, strlen(dbFName))) { - pRes->pass = true; + pRes->pass[AUTH_RES_BASIC] = true; return TSDB_CODE_SUCCESS; } @@ -1752,13 +1761,13 @@ int32_t ctgChkSetAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res) { if (pReq->tbName.type == TSDB_TABLE_NAME_T && pInfo->writeTbs && taosHashGetSize(pInfo->writeTbs) > 0) { req->singleType = AUTH_TYPE_WRITE; CTG_ERR_RET(ctgChkSetTbAuthRes(pCtg, req, res)); - if (pRes->pass || res->metaNotExists) { + if (pRes->pass[AUTH_RES_BASIC] || res->metaNotExists) { return TSDB_CODE_SUCCESS; } } if (pInfo->writeDbs && taosHashGet(pInfo->writeDbs, dbFName, strlen(dbFName))) { - pRes->pass = true; + pRes->pass[AUTH_RES_BASIC] = true; return TSDB_CODE_SUCCESS; } @@ -1768,7 +1777,7 @@ int32_t ctgChkSetAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res) { if ((pInfo->readDbs && taosHashGet(pInfo->readDbs, dbFName, strlen(dbFName))) || (pInfo->writeDbs && taosHashGet(pInfo->writeDbs, dbFName, strlen(dbFName))) || (pInfo->useDbs && taosHashGet(pInfo->useDbs, dbFName, strlen(dbFName)))) { - pRes->pass = true; + pRes->pass[AUTH_RES_BASIC] = true; return TSDB_CODE_SUCCESS; } @@ -1781,6 +1790,79 @@ int32_t ctgChkSetAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res) { return TSDB_CODE_SUCCESS; } +int32_t ctgChkSetViewAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res) { + int32_t code = 0; + SUserAuthInfo* pReq = req->pRawReq; + SUserAuthRes* pRes = res->pRawRes; + SGetUserAuthRsp* pInfo = &req->authInfo; + + pRes->pass[AUTH_RES_VIEW] = false; + pRes->pCond[AUTH_RES_VIEW] = NULL; + + if (!pInfo->enable) { + return TSDB_CODE_SUCCESS; + } + + if (pInfo->superAuth) { + pRes->pass[AUTH_RES_VIEW] = true; + return TSDB_CODE_SUCCESS; + } + + if (pReq->tbName.type != TSDB_TABLE_NAME_T) { + return TSDB_CODE_SUCCESS; + } + + char viewFName[TSDB_VIEW_FNAME_LEN]; + if (IS_SYS_DBNAME(req->pRawReq->tbName.dbname)) { + snprintf(viewFName, sizeof(viewFName), "%s.%s", req->pRawReq->tbName.dbname, req->pRawReq->tbName.tname); + } else { + tNameExtractFullName(&req->pRawReq->tbName, viewFName); + } + int32_t len = strlen(viewFName) + 1; + + switch (pReq->type) { + case AUTH_TYPE_READ: { + char *value = taosHashGet(pInfo->readViews, viewFName, len); + if (NULL != value) { + pRes->pass[AUTH_RES_VIEW] = true; + return TSDB_CODE_SUCCESS; + } + break; + } + case AUTH_TYPE_WRITE: { + char *value = taosHashGet(pInfo->writeViews, viewFName, len); + if (NULL != value) { + pRes->pass[AUTH_RES_VIEW] = true; + return TSDB_CODE_SUCCESS; + } + break; + } + case AUTH_TYPE_ALTER: { + char *value = taosHashGet(pInfo->alterViews, viewFName, len); + if (NULL != value) { + pRes->pass[AUTH_RES_VIEW] = true; + return TSDB_CODE_SUCCESS; + } + break; + } + default: + break; + } + + return TSDB_CODE_SUCCESS; +} + +int32_t ctgChkSetAuthRes(SCatalog* pCtg, SCtgAuthReq* req, SCtgAuthRsp* res) { +#ifdef TD_ENTERPRISE + CTG_ERR_RET(ctgChkSetBasicAuthRes(pCtg, req, res)); + if (req->pRawReq->isView) { + return TSDB_CODE_SUCCESS; + } +#endif + + CTG_RET(ctgChkSetViewAuthRes(pCtg, req, res)); +} + #if 0 static int32_t ctgCloneMetaDataArray(SArray* pSrc, __array_item_dup_fn_t copyFunc, SArray** pDst) { if (NULL == pSrc) { @@ -1888,7 +1970,7 @@ uint64_t ctgGetViewMetaCacheSize(SViewMeta *pMeta) { return 0; } - return sizeof(*pMeta) + strlen(pMeta->querySql) + 1 + pMeta->numOfCols * sizeof(SSchema); + return sizeof(*pMeta) + strlen(pMeta->querySql) + 1 + strlen(pMeta->user) + 1 + pMeta->numOfCols * sizeof(SSchema); } @@ -1978,6 +2060,33 @@ uint64_t ctgGetUserCacheSize(SGetUserAuthRsp *pAuth) { p = taosHashIterate(pAuth->alterTbs, p); } + p = taosHashIterate(pAuth->readViews, NULL); + while (p != NULL) { + size_t len = 0; + void* key = taosHashGetKey(p, &len); + cacheSize += len + strlen(p); + + p = taosHashIterate(pAuth->readViews, p); + } + + p = taosHashIterate(pAuth->writeViews, NULL); + while (p != NULL) { + size_t len = 0; + void* key = taosHashGetKey(p, &len); + cacheSize += len + strlen(p); + + p = taosHashIterate(pAuth->writeViews, p); + } + + p = taosHashIterate(pAuth->alterViews, NULL); + while (p != NULL) { + size_t len = 0; + void* key = taosHashGetKey(p, &len); + cacheSize += len + strlen(p); + + p = taosHashIterate(pAuth->alterViews, p); + } + int32_t *ref = taosHashIterate(pAuth->useDbs, NULL); while (ref != NULL) { size_t len = 0; @@ -2124,6 +2233,10 @@ int32_t dupViewMetaFromRsp(SViewMetaRsp* pRsp, SViewMeta* pViewMeta) { if (NULL == pViewMeta->querySql) { CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY); } + pViewMeta->user = strdup(pRsp->user); + if (NULL == pViewMeta->user) { + CTG_ERR_RET(TSDB_CODE_OUT_OF_MEMORY); + } pViewMeta->version = pRsp->version; pViewMeta->viewId = pRsp->viewId; pViewMeta->precision = pRsp->precision; diff --git a/source/libs/catalog/test/catalogTests.cpp b/source/libs/catalog/test/catalogTests.cpp index e0e456402b..23fa8d000b 100644 --- a/source/libs/catalog/test/catalogTests.cpp +++ b/source/libs/catalog/test/catalogTests.cpp @@ -2814,7 +2814,7 @@ TEST(apiTest, catalogChkAuth_test) { code = catalogChkAuth(pCtg, mockPointer, &authInfo, &authRes); ASSERT_EQ(code, 0); - ASSERT_EQ(authRes.pass, true); + ASSERT_EQ(authRes.pass[AUTH_RES_BASIC], true); while (true) { uint64_t n = 0; @@ -2828,7 +2828,7 @@ TEST(apiTest, catalogChkAuth_test) { code = catalogChkAuthFromCache(pCtg, &authInfo, &authRes, &exists); ASSERT_EQ(code, 0); - ASSERT_EQ(authRes.pass, true); + ASSERT_EQ(authRes.pass[AUTH_RES_BASIC], true); ASSERT_EQ(exists, true); catalogDestroy(); diff --git a/source/libs/command/src/command.c b/source/libs/command/src/command.c index 0e2510c5c0..252b20a23c 100644 --- a/source/libs/command/src/command.c +++ b/source/libs/command/src/command.c @@ -115,7 +115,7 @@ static int32_t setDescResultIntoDataBlock(bool sysInfoUser, SSDataBlock* pBlock, if (TSDB_VIEW_TABLE != pMeta->tableType) { STR_TO_VARSTR(buf, i >= pMeta->tableInfo.numOfColumns ? "TAG" : ""); } else { - STR_TO_VARSTR(buf, "VIEW"); + STR_TO_VARSTR(buf, "VIEW COL"); } colDataSetVal(pCol4, pBlock->info.rows, buf, false); ++(pBlock->info.rows); diff --git a/source/libs/parser/inc/parTranslater.h b/source/libs/parser/inc/parTranslater.h index 7f721a2c25..e06626fb00 100644 --- a/source/libs/parser/inc/parTranslater.h +++ b/source/libs/parser/inc/parTranslater.h @@ -48,6 +48,8 @@ typedef struct STranslateContext { int32_t biRewriteSelectStar(STranslateContext* pCxt, SSelectStmt* pSelect); int32_t findTable(STranslateContext* pCxt, const char* pTableAlias, STableNode** pOutput); +int32_t getTargetMetaImpl(SParseContext* pParCxt, SParseMetaCache* pMetaCache, const SName* pName, STableMeta** pMeta, bool couldBeView); + #ifdef __cplusplus } #endif diff --git a/source/libs/parser/src/parAstParser.c b/source/libs/parser/src/parAstParser.c index 235520d29c..d16e014d19 100644 --- a/source/libs/parser/src/parAstParser.c +++ b/source/libs/parser/src/parAstParser.c @@ -167,6 +167,12 @@ static int32_t collectMetaKeyFromRealTableImpl(SCollectMetaKeyCxt* pCxt, const c code = reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pUser, pDb, pTable, authType, pCxt->pMetaCache); } +#ifdef TD_ENTERPRISE + if (TSDB_CODE_SUCCESS == code && NULL != pCxt->pParseCxt->pEffectiveUser) { + code = reserveUserAuthInCache(pCxt->pParseCxt->acctId, pCxt->pParseCxt->pEffectiveUser, pDb, pTable, authType, + pCxt->pMetaCache); + } +#endif if (TSDB_CODE_SUCCESS == code) { code = reserveDbVgInfoInCache(pCxt->pParseCxt->acctId, pDb, pCxt->pMetaCache); } diff --git a/source/libs/parser/src/parAuthenticator.c b/source/libs/parser/src/parAuthenticator.c index eb885c1c75..1d2e8eb229 100644 --- a/source/libs/parser/src/parAuthenticator.c +++ b/source/libs/parser/src/parAuthenticator.c @@ -35,8 +35,13 @@ typedef struct SAuthRewriteCxt { static int32_t authQuery(SAuthCxt* pCxt, SNode* pStmt); static void setUserAuthInfo(SParseContext* pCxt, const char* pDbName, const char* pTabName, AUTH_TYPE type, - bool isView, SUserAuthInfo* pAuth) { - snprintf(pAuth->user, sizeof(pAuth->user), "%s", pCxt->pUser); + bool isView, bool effective, SUserAuthInfo* pAuth) { + if (effective) { + snprintf(pAuth->user, sizeof(pAuth->user), "%s", pCxt->pEffectiveUser ? pCxt->pEffectiveUser : ""); + } else { + snprintf(pAuth->user, sizeof(pAuth->user), "%s", pCxt->pUser); + } + if (NULL == pTabName) { tNameSetDbName(&pAuth->tbName, pCxt->acctId, pDbName, strlen(pDbName)); } else { @@ -46,18 +51,25 @@ static void setUserAuthInfo(SParseContext* pCxt, const char* pDbName, const char pAuth->isView = isView; } -static int32_t checkAuthImpl(SAuthCxt* pCxt, const char* pDbName, const char* pTabName, AUTH_TYPE type, SNode** pCond, bool isView) { +static int32_t checkAuthImpl(SAuthCxt* pCxt, const char* pDbName, const char* pTabName, AUTH_TYPE type, SNode** pCond, bool isView, bool effective) { SParseContext* pParseCxt = pCxt->pParseCxt; if (pParseCxt->isSuperUser) { return TSDB_CODE_SUCCESS; } + AUTH_RES_TYPE auth_res_type = isView ? AUTH_RES_VIEW : AUTH_RES_BASIC; SUserAuthInfo authInfo = {0}; - setUserAuthInfo(pCxt->pParseCxt, pDbName, pTabName, type, isView, &authInfo); + setUserAuthInfo(pCxt->pParseCxt, pDbName, pTabName, type, isView, effective, &authInfo); int32_t code = TSDB_CODE_SUCCESS; SUserAuthRes authRes = {0}; if (NULL != pCxt->pMetaCache) { code = getUserAuthFromCache(pCxt->pMetaCache, &authInfo, &authRes); +#ifdef TD_ENTERPRISE + if (isView && TSDB_CODE_PAR_INTERNAL_ERROR == code) { + authInfo.isView = false; + code = getUserAuthFromCache(pCxt->pMetaCache, &authInfo, &authRes); + } +#endif } else { SRequestConnInfo conn = {.pTrans = pParseCxt->pTransporter, .requestId = pParseCxt->requestId, @@ -66,20 +78,23 @@ static int32_t checkAuthImpl(SAuthCxt* pCxt, const char* pDbName, const char* pT code = catalogChkAuth(pParseCxt->pCatalog, &conn, &authInfo, &authRes); } if (TSDB_CODE_SUCCESS == code && NULL != pCond) { - *pCond = authRes.pCond; + *pCond = authRes.pCond[auth_res_type]; } - return TSDB_CODE_SUCCESS == code ? (authRes.pass ? TSDB_CODE_SUCCESS : TSDB_CODE_PAR_PERMISSION_DENIED) : code; + return TSDB_CODE_SUCCESS == code ? (authRes.pass[auth_res_type] ? TSDB_CODE_SUCCESS : TSDB_CODE_PAR_PERMISSION_DENIED) : code; } static int32_t checkAuth(SAuthCxt* pCxt, const char* pDbName, const char* pTabName, AUTH_TYPE type, SNode** pCond) { - return checkAuthImpl(pCxt, pDbName, pTabName, type, pCond, false); + return checkAuthImpl(pCxt, pDbName, pTabName, type, pCond, false, false); } static int32_t checkViewAuth(SAuthCxt* pCxt, const char* pDbName, const char* pTabName, AUTH_TYPE type, SNode** pCond) { - return checkAuthImpl(pCxt, pDbName, pTabName, type, NULL, true); + return checkAuthImpl(pCxt, pDbName, pTabName, type, NULL, true, false); } +static int32_t checkViewEffectiveAuth(SAuthCxt* pCxt, const char* pDbName, const char* pTabName, AUTH_TYPE type, SNode** pCond) { + return checkAuthImpl(pCxt, pDbName, pTabName, type, NULL, true, true); +} static EDealRes authSubquery(SAuthCxt* pCxt, SNode* pStmt) { return TSDB_CODE_SUCCESS == authQuery(pCxt, pStmt) ? DEAL_RES_CONTINUE : DEAL_RES_ERROR; @@ -141,12 +156,33 @@ static int32_t rewriteAppendStableTagCond(SNode** pWhere, SNode* pTagCond, STabl static EDealRes authSelectImpl(SNode* pNode, void* pContext) { SSelectAuthCxt* pCxt = pContext; SAuthCxt* pAuthCxt = pCxt->pAuthCxt; + bool isView = false; if (QUERY_NODE_REAL_TABLE == nodeType(pNode)) { SNode* pTagCond = NULL; STableNode* pTable = (STableNode*)pNode; - pAuthCxt->errCode = checkAuth(pAuthCxt, pTable->dbName, pTable->tableName, AUTH_TYPE_READ, &pTagCond); - if (TSDB_CODE_SUCCESS == pAuthCxt->errCode && NULL != pTagCond) { - pAuthCxt->errCode = rewriteAppendStableTagCond(&pCxt->pSelect->pWhere, pTagCond, pTable); +#ifdef TD_ENTERPRISE + SName name; + STableMeta* pTableMeta = NULL; + int32_t code = getTargetMetaImpl( + pAuthCxt->pParseCxt, pAuthCxt->pMetaCache, toName(pAuthCxt->pParseCxt->acctId, pTable->dbName, pTable->tableName, &name), &pTableMeta, true); + if (TSDB_CODE_SUCCESS != code) { + pAuthCxt->errCode = code; + return DEAL_RES_ERROR; + } else if (TSDB_VIEW_TABLE == pTableMeta->tableType) { + isView = true; + } + taosMemoryFree(pTableMeta); +#endif + if (!isView) { + pAuthCxt->errCode = checkAuth(pAuthCxt, pTable->dbName, pTable->tableName, AUTH_TYPE_READ, &pTagCond); + if (TSDB_CODE_SUCCESS == pAuthCxt->errCode && NULL != pTagCond) { + pAuthCxt->errCode = rewriteAppendStableTagCond(&pCxt->pSelect->pWhere, pTagCond, pTable); + } + } else { + pAuthCxt->errCode = checkViewAuth(pAuthCxt, pTable->dbName, pTable->tableName, AUTH_TYPE_READ, NULL); + if (TSDB_CODE_SUCCESS != pAuthCxt->errCode && NULL != pAuthCxt->pParseCxt->pEffectiveUser) { + pAuthCxt->errCode = checkViewEffectiveAuth(pAuthCxt, pTable->dbName, pTable->tableName, AUTH_TYPE_READ, NULL); + } } return TSDB_CODE_SUCCESS == pAuthCxt->errCode ? DEAL_RES_CONTINUE : DEAL_RES_ERROR; } else if (QUERY_NODE_TEMP_TABLE == nodeType(pNode)) { @@ -278,7 +314,7 @@ static int32_t authDropView(SAuthCxt* pCxt, SDropViewStmt* pStmt) { #ifndef TD_ENTERPRISE return TSDB_CODE_OPS_NOT_SUPPORT; #endif - return checkViewAuth(pCxt, pStmt->dbName, pStmt->viewName, AUTH_TYPE_WRITE, NULL); + return checkViewAuth(pCxt, pStmt->dbName, pStmt->viewName, AUTH_TYPE_ALTER, NULL); } static int32_t authQuery(SAuthCxt* pCxt, SNode* pStmt) { diff --git a/source/libs/parser/src/parInsertSql.c b/source/libs/parser/src/parInsertSql.c index 5046c2ef5c..3a12d59776 100644 --- a/source/libs/parser/src/parInsertSql.c +++ b/source/libs/parser/src/parInsertSql.c @@ -965,10 +965,10 @@ static int32_t checkAuth(SParseContext* pCxt, SName* pTbName, bool* pMissCache, if (TSDB_CODE_SUCCESS == code) { if (!exists) { *pMissCache = true; - } else if (!authRes.pass) { + } else if (!authRes.pass[AUTH_RES_BASIC]) { code = TSDB_CODE_PAR_PERMISSION_DENIED; - } else if (NULL != authRes.pCond) { - *pTagCond = authRes.pCond; + } else if (NULL != authRes.pCond[AUTH_RES_BASIC]) { + *pTagCond = authRes.pCond[AUTH_RES_BASIC]; } } return code; @@ -1959,9 +1959,9 @@ static int32_t checkAuthFromMetaData(const SArray* pUsers, SNode** pTagCond) { if (TSDB_CODE_SUCCESS == pRes->code) { SUserAuthRes* pAuth = pRes->pRes; if (NULL != pAuth->pCond) { - *pTagCond = nodesCloneNode(pAuth->pCond); + *pTagCond = nodesCloneNode(pAuth->pCond[AUTH_RES_BASIC]); } - return pAuth->pass ? TSDB_CODE_SUCCESS : TSDB_CODE_PAR_PERMISSION_DENIED; + return pAuth->pass[AUTH_RES_BASIC] ? TSDB_CODE_SUCCESS : TSDB_CODE_PAR_PERMISSION_DENIED; } return pRes->code; } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index e586423c77..92f793cde1 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -363,7 +363,7 @@ static int32_t getViewMetaImpl(SParseContext* pParCxt, SParseMetaCache* pMetaCac return code; } -static int32_t getTargetMetaImpl(SParseContext* pParCxt, SParseMetaCache* pMetaCache, const SName* pName, STableMeta** pMeta, bool couldBeView) { +int32_t getTargetMetaImpl(SParseContext* pParCxt, SParseMetaCache* pMetaCache, const SName* pName, STableMeta** pMeta, bool couldBeView) { int32_t code = TSDB_CODE_SUCCESS; if (pParCxt->async) { @@ -7489,21 +7489,27 @@ static int32_t validateCreateView(STranslateContext* pCxt, SCreateViewStmt* pStm return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_VIEW_QUERY, "Invalid view query type"); } +/* STableMeta* pMetaCache = NULL; int32_t code = getTableMeta(pCxt, pStmt->dbName, pStmt->viewName, &pMetaCache); if (TSDB_CODE_SUCCESS == code) { taosMemoryFreeClear(pMetaCache); return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_VIEW_CONFLICT_WITH_TABLE, "View name is conflict with table"); } +*/ return TSDB_CODE_SUCCESS; } static int32_t translateCreateView(STranslateContext* pCxt, SCreateViewStmt* pStmt) { +#ifndef TD_ENTERPRISE + return TSDB_CODE_OPS_NOT_SUPPORT; +#endif + SParseSqlRes res = {.resType = PARSE_SQL_RES_SCHEMA}; int32_t code = validateCreateView(pCxt, pStmt); if (TSDB_CODE_SUCCESS == code) { - code = (*pCxt->pParseCxt->parseSqlFp)(pCxt->pParseCxt->parseSqlParam, pStmt->pQuerySql, false, &res); + code = (*pCxt->pParseCxt->parseSqlFp)(pCxt->pParseCxt->parseSqlParam, pStmt->pQuerySql, false, NULL, &res); } if (TSDB_CODE_SUCCESS == code) { SName name; @@ -7534,6 +7540,10 @@ static int32_t translateCreateView(STranslateContext* pCxt, SCreateViewStmt* pSt static int32_t translateDropView(STranslateContext* pCxt, SDropViewStmt* pStmt) { +#ifndef TD_ENTERPRISE + return TSDB_CODE_OPS_NOT_SUPPORT; +#endif + SCMDropViewReq dropReq = {0}; SName name; tNameSetDbName(&name, pCxt->pParseCxt->acctId, pStmt->dbName, strlen(pStmt->dbName)); @@ -7690,14 +7700,30 @@ static int32_t translateGrantTagCond(STranslateContext* pCxt, SGrantStmt* pStmt, } static int32_t translateGrant(STranslateContext* pCxt, SGrantStmt* pStmt) { + int32_t code = 0; SAlterUserReq req = {0}; req.alterType = TSDB_ALTER_USER_ADD_PRIVILEGES; req.privileges = pStmt->privileges; +#ifdef TD_ENTERPRISE + SName name; + STableMeta* pTableMeta = NULL; + code = getTargetMeta(pCxt, toName(pCxt->pParseCxt->acctId, pStmt->objName, pStmt->tabName, &name), &pTableMeta, true); + if (TSDB_CODE_SUCCESS != code) { + if (TSDB_CODE_PAR_TABLE_NOT_EXIST != code) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_GET_META_ERROR, tstrerror(code)); + } + } else if (TSDB_VIEW_TABLE == pTableMeta->tableType) { + req.isView = true; + } + taosMemoryFree(pTableMeta); +#endif strcpy(req.user, pStmt->userName); sprintf(req.objname, "%d.%s", pCxt->pParseCxt->acctId, pStmt->objName); sprintf(req.tabName, "%s", pStmt->tabName); - int32_t code = translateGrantTagCond(pCxt, pStmt, &req); + if (!req.isView) { + code = translateGrantTagCond(pCxt, pStmt, &req); + } if (TSDB_CODE_SUCCESS == code) { code = buildCmdMsg(pCxt, TDMT_MND_ALTER_USER, (FSerializeFunc)tSerializeSAlterUserReq, &req); } @@ -7706,14 +7732,29 @@ static int32_t translateGrant(STranslateContext* pCxt, SGrantStmt* pStmt) { } static int32_t translateRevoke(STranslateContext* pCxt, SRevokeStmt* pStmt) { + int32_t code = 0; SAlterUserReq req = {0}; req.alterType = TSDB_ALTER_USER_DEL_PRIVILEGES; req.privileges = pStmt->privileges; + +#ifdef TD_ENTERPRISE + SName name; + STableMeta* pTableMeta = NULL; + code = getTargetMeta(pCxt, toName(pCxt->pParseCxt->acctId, pStmt->objName, pStmt->tabName, &name), &pTableMeta, true); + if (TSDB_CODE_SUCCESS != code) { + if (TSDB_CODE_PAR_TABLE_NOT_EXIST != code) { + return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_GET_META_ERROR, tstrerror(code)); + } + } else if (TSDB_VIEW_TABLE == pTableMeta->tableType) { + req.isView = true; + } + taosMemoryFree(pTableMeta); +#endif strcpy(req.user, pStmt->userName); sprintf(req.objname, "%d.%s", pCxt->pParseCxt->acctId, pStmt->objName); sprintf(req.tabName, "%s", pStmt->tabName); - int32_t code = buildCmdMsg(pCxt, TDMT_MND_ALTER_USER, (FSerializeFunc)tSerializeSAlterUserReq, &req); + code = buildCmdMsg(pCxt, TDMT_MND_ALTER_USER, (FSerializeFunc)tSerializeSAlterUserReq, &req); tFreeSAlterUserReq(&req); return code; } diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index b5dc56cacc..5dea2d676e 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -563,6 +563,7 @@ static void stringToUserAuth(const char* pStr, int32_t len, SUserAuthInfo* pUser pUserAuth->tbName.type = TSDB_DB_NAME_T; } pUserAuth->type = getIntegerFromAuthStr(p, &p); + pUserAuth->isView = getIntegerFromAuthStr(p, &p); } static int32_t buildTableReq(SHashObj* pTablesHash, SArray** pTables) { diff --git a/source/libs/parser/test/mockCatalog.cpp b/source/libs/parser/test/mockCatalog.cpp index 21b5c13a2f..fee155de15 100644 --- a/source/libs/parser/test/mockCatalog.cpp +++ b/source/libs/parser/test/mockCatalog.cpp @@ -284,12 +284,12 @@ int32_t __catalogGetDBCfg(SCatalog* pCtg, SRequestConnInfo* pConn, const char* d } int32_t __catalogChkAuth(SCatalog* pCtg, SRequestConnInfo* pConn, SUserAuthInfo *pAuth, SUserAuthRes* pRes) { - pRes->pass = true; + pRes->pass[0] = true; return 0; } int32_t __catalogChkAuthFromCache(SCatalog* pCtg, SUserAuthInfo *pAuth, SUserAuthRes* pRes, bool* exists) { - pRes->pass = true; + pRes->pass[0] = true; *exists = true; return 0; } diff --git a/source/libs/parser/test/mockCatalogService.cpp b/source/libs/parser/test/mockCatalogService.cpp index f6a8b407d7..254ac7d927 100644 --- a/source/libs/parser/test/mockCatalogService.cpp +++ b/source/libs/parser/test/mockCatalogService.cpp @@ -590,7 +590,7 @@ class MockCatalogServiceImpl { for (int32_t i = 0; i < num; ++i) { SMetaRes res = {0}; res.pRes = taosMemoryCalloc(1, sizeof(SUserAuthRes)); - ((SUserAuthRes*)res.pRes)->pass = true; + ((SUserAuthRes*)res.pRes)->pass[0] = true; taosArrayPush(*pUserAuthData, &res); } } diff --git a/tests/script/tsim/view/insert_view.sim b/tests/script/tsim/view/insert_view.sim new file mode 100644 index 0000000000..99d23b7bcd --- /dev/null +++ b/tests/script/tsim/view/insert_view.sim @@ -0,0 +1,11 @@ +sql connect +sql use testa; + +sql create view view1 as select * from cta11; +sql_error insert into view1 values (now, 1); +sql create table ctat using sta1 tags(1); +sql insert into ctat select * from view1; +sql drop view view1; +sql drop table ctat; + +#system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/tsim/view/query_view.sim b/tests/script/tsim/view/query_view.sim index d6a8899656..ab5cfe1839 100644 --- a/tests/script/tsim/view/query_view.sim +++ b/tests/script/tsim/view/query_view.sim @@ -75,6 +75,31 @@ endi sql drop view view1; sql drop view view2; +sql create view view1 as select * from sta1; +sql create view view2 as select * from sta2; +sql create view view3 as select a.ts ts, a.f af, b.f bf from view1 a join view2 b on a.ts = b.ts; +sql create view view3a as select a.ts ts, a.f, b.f from view1 a join view2 b on a.ts = b.ts; +sql create view view4 as select _wstart, avg(bf) - avg(af) as b from view3 interval(1s); +sql_error create view view4a as select _wstart, avg(b.f) - avg(a.f) as b from view3 interval(1s); +sql create view view5 as select count(*),avg(b) from view4 interval(1s) having avg(b) > 0; +sql select * from view5; +if $rows != 4 then + return -1 +endi +if $data00 != 1 then + print $data00 + return -1 +endi +if $data01 != 110.000000000 then + return -1 +endi +sql drop view view1; +sql drop view view2; +sql drop view view3; +sql drop view view3a; +sql drop view view4; +sql drop view view5; + sql use information_schema; sql create view view1 as select * from ins_views; sql select * from view1;