測試平臺-flask_admin+mongoEngine 實現資料許可權
該文原創為新潮質量保障技術團隊中的 “上進的中年軟體測試從業者”,用於技術交流分享
前幾天看到一句話感觸頗多,大意是是團隊管理者總是喜歡培養一個小一號的自己。說白了也就是喜歡和自己做事風格一致,但是暫時又不如自己的人。這兩點都很容易解讀,大多數人對自己都比較寬容,而對別人會相對苛刻一些;同時也希望自己是這個團隊的權威,不希望受到挑戰。
之前有跟同事聊過,我希望我周圍全是P7或者M3以上的大牛。只所以這樣說,是因為14年我出來找工作的時候,本來信心滿滿結果卻碰了一頭的包。而我自認為之前的那份工作經歷,以及我的個人表現是能夠非常輕鬆的找到一份滿意的工作。自此以後終於頓悟,更有後面豐富的工作經歷的磨礪,明白了兩個道理、一件事:
- 不做井底之蛙
- 磨刀不誤砍柴工
- 合作真的能夠共贏
都是很簡單的道理,有些人天生就懂,有些人就需要交點學費了。
開篇
本來都在發愁,馬上兩週就到了,似乎沒什麼素材可寫了。好在有這樣一件事在牽絆著,沒有素材自己創造素材也要寫。
最早的時候,我們有介紹如果通過flask_admin和MongoEngine來實現業務許可權控制,具體請參考測試平臺之許可權和角色實現。有過開發和一定測試經驗的小夥伴一定也接觸過資料許可權控制,通俗來講就是我的資料不希望你可以看,你的資料也不要擾亂我的正常資料的使用。
背景
當測試平臺逐漸投入使用後,發現過多的資料量會影響大家的工作效率,而不同專案組之前一般是不關係彼此的測試資料的。之前設計平臺的時候並沒有考慮資料許可權方面的控制,今天就簡單給大家說一下大概的設計思路。
##調研
熟悉flask_admin+mongoEngine這套MVC框架的小夥伴,Model層對collection定義的Document, 本身具備了對呼叫者返回全部資料的能力,這源於objects屬性:
# Provide a default queryset unless exists or one has been set
if 'objects' not in dir(new_class):
new_class.objects = QuerySetManager()
結合官方文件和原始碼的介紹,這裡大概知道objects和querySet有那麼千絲萬縷的關係,實際上也不用過多的猜測,預設返回全部資料,源於對objects屬性沒有做任何限制。
根據上面的調研,我們發現可以對objects屬性做限制,即可實現資料許可權,但是這裡就有問題了:你會發現這樣並沒有實現真正意義的資料許可權,而是強制性的讓資料固定的只返回一部分給呼叫者。如下面的程式碼所示,這裡只是實現了給呼叫者返回的永遠都是有效標識的資料,而並沒有對不同的使用者進行資料許可權。
@queryset_manager
def objects(doc_cls, queryset):
return queryset.filter(available=True)
所以,在Model層做資料許可權是❌的。
但是這裡也給了我們很好的啟示,我們可以定義不同的資料集合,方便呼叫者使用,如下面的程式碼:
`@queryset_manager
def objects(doc_cls, queryset):
"""
reference引用時,預設返回的資料
:param queryset:
:return:
"""
tester = TesterForm.objects(testerId=current_user.id).first()
return queryset.filter(Q(creator=tester) | Q(updater=tester) | Q(projectTesters=tester)).filter(
available=True).filter(Q(readyToTestDate_lte=datetime.datetime.now().date()) & Q(
readyToReleaseDate_gte=datetime.datetime.now().date()))
@queryset_manager
def objects_tester_rule(doc_cls, queryset):
"""
測試人員資料許可權
:param queryset:
:return:
"""
tester = TesterForm.objects(testerId=current_user.id).first()
return queryset.filter(Q(creator=tester) | Q(updater=tester) | Q(projectTesters=tester)).filter(
available=True)
@queryset_manager
def objects_all(doc_cls, queryset):
"""
全部資料
:param queryset:
:return:
"""
return queryset.filter()`
PS:現在寫這篇文章的時候,才有點後知後覺,Model層確實不應該涉及資料許可權,而是專心的處理資料整合和對映方面工作。
既然在Model層無法實現資料許可權,那我們就可以在View層嘗試實現資料許可權。
解決過程
flask_admin作為後臺管理框架,有一套後臺管理的腳手架,包括自動生成列表、通過各種屬性控制列表能力(新增、編輯、修改)、自動生成路由介面等。這裡我們就找到了一個預設查詢列表資料的方法:
def get_query(self):
"""
Returns the QuerySet for this view. By default, it returns all the
objects for the current model.
"""
return self.model.objects
這裡我們發現get_query預設返回了Model層對應Document的全部資料(如果Model做了限制,如只返回available欄位為True的,這裡同樣只能獲取相同的資料),找到了對應的方法,就可以有針對應的進行處理,如下面的場景,每個人只能看到自己建立的資料:
def get_query(self):
return self.model.objects(tester=current_user)
場景升級
我們現在來看解決過程確實很簡單,前提是你要了解這套框架。
瞭解mongoEngine的小夥伴知道它提供瞭如MySQL資料關聯同樣功能的一種特殊欄位型別ReferenceField,那如何對ReferenceField進行資料限制呢。比如說有一個專案表、一個bug表,bug表的專案欄位關聯到專案表,我需要在bug檢視建立bug時只能選擇我自己建立的專案,該如何做資料許可權控制呢?
這個時候就要用到我們上面介紹到的對Document定義不同的資料集即可,如重定義objects只返回當前使用者的資料(前提是我們已經知道ReferenceField獲取的就是objects屬性的資料,感興趣的可以去研究原始碼),定義另外一個objects_all返回Document所有的資料給其他呼叫者使用,如專案檢視可以採用重寫get_query的方法獲取所有的資料,而不是預設的objects屬性的資料:
def get_query(self):
return self.model.objects_all()
這裡有點繞,感興趣的歡迎私聊。
思考
上面的解決方案似乎解決了所有的問題,但是作為一名測試人員,還是發現了一個場景是無法解決。也就是在上面場景下,有另外一個用例的表,專案欄位同樣也是關聯的專案表,但是通過ReferenceField需要看到的專案是全部的專案(我們知道在這個場景裡面objects已經被重寫只返回當前使用者的專案,並且ReferenceField預設獲取objects物件的資料),但是這裡,使用者在寫用例的時候也只能選擇自己參與的專案,而不能選擇所有的專案。
因為暫時還沒有這樣的場景,所以也就沒有過多去調研了,有過這方面實戰的小夥伴請不吝賜教。
結語
下次會是什麼不期而至的難題呢,自動化、平臺建設、CI/CD還是?因為牽絆所以堅持,因為堅持所以牽絆,加油。
我總是習慣給自己標榜溝通能力差,希望有人幫我塑造一個溝通能力強的人設,可能真的會讓我這方面有所提升。
又是一個週末的到來,祝各位小夥伴週末愉快。
相關文章
- 如何用 Vue 實現前端許可權控制(路由許可權 + 檢視許可權 + 請求許可權)Vue前端路由
- 基於.NET 5實現的開源通用許可權管理平臺
- 許可權系統:一文搞懂功能許可權、資料許可權
- SpringSecurity許可權管理系統實戰—九、資料許可權的配置SpringGse
- Laravel實現許可權控制Laravel
- 滲透測試-許可權維持
- 【專案實踐】一文帶你搞定頁面許可權、按鈕許可權以及資料許可權
- 需要一個前臺許可權管理,或問如何實現
- 資料庫的許可權管理資料庫
- 資料分析的許可權控制
- Android平臺targetSdkVersion設定及動態許可權Android
- .NET 平臺 WPF 通用許可權開發框架 (ABP)框架
- 基於RBAC實現許可權管理
- Vue許可權路由實現總結Vue路由
- 從0實現RBAC許可權模型模型
- 往hdfs寫資料無許可權
- Mysql資料庫許可權問題MySql資料庫
- 資料許可權技術驗證
- 資料許可權驗證MyBatis版MyBatis
- 修改檔案、資料夾許可權
- 資料庫學習:許可權管理資料庫
- 基於RBAC做資料許可權
- linux 檔案、資料夾許可權Linux
- gm手遊平臺代理 包站免費許可權gm遊戲平臺遊戲
- vue許可權路由實現方式總結Vue路由
- 使用動態路由實現許可權管理路由
- springboot+Vue 實現介面測試平臺Spring BootVue
- 許可權之選單許可權
- linux 檔案許可權 s 許可權和 t 許可權解析Linux
- 安卓gm版手遊平臺 gm許可權手遊平臺哪個好安卓
- 自動化平臺中的ORM和許可權設計ORM
- vue許可權路由實現方式總結二Vue路由
- SpringBoot(一) 如何實現AOP的許可權控制Spring Boot
- 通過 VirtualApp 實現免 Root 許可權 HookAPPHook
- NODE + JWT + Mongo(簡單實現許可權管理)JWTGo
- 前端許可權控制系統的實現思路前端
- SpringBoot整合SpringSecurityOauth2實現鑑權-動態許可權Spring BootGseOAuth
- 資料湖統一後設資料與許可權