Compare commits

...

1690 Commits

Author SHA1 Message Date
老广 e617245b26
merge: to master 2025-10-16 17:30:34 +08:00
feng d309d11a8f perf: Command count 2025-10-16 17:11:42 +08:00
feng 4771693a56 fix: dashboard command count 2025-10-16 16:25:01 +08:00
Chenyang Shen cefc820ac1
Merge pull request #16163 from jumpserver/pr@dev@asset_acl_filter
perf: Asset acl filter action
2025-10-16 15:25:38 +08:00
feng d007afdb43 perf: Asset acl filter action 2025-10-16 15:21:32 +08:00
feng e8921a43be perf: Translate 2025-10-16 14:32:59 +08:00
wangruidong a9b44103d4 fix: Handle email sending failure with appropriate error response 2025-10-16 11:28:41 +08:00
jiangweidong 4abf2bded6 perf: oracle cdb mode, common users need to start username with C## 2025-10-16 09:57:54 +08:00
feng 54693089a0 perf: replace command objects 2025-10-15 19:32:14 +08:00
Aaron3S 0b859dd502 feat: update i18n 2025-10-15 19:17:44 +08:00
feng 3fb27f969a perf: datamaskingrule perm 2025-10-15 17:33:27 +08:00
Aaron3S 45627a1d92 feat: update data masking rule filter 2025-10-15 16:51:58 +08:00
feng 245e2dab66 perf: Filter effective 2025-10-15 16:51:32 +08:00
Aaron3S 8f0a41b1a8 fix: fix data masking org problem 2025-10-15 15:51:14 +08:00
feng 1a9e56c520 perf: Translate 2025-10-15 15:24:19 +08:00
feng 67c2f471b4 perf: oracle sqlserver db2 dameng clickhouse redis db_name allow_blank 2025-10-15 11:30:00 +08:00
github-actions[bot] b04f96f5f2 perf: Update Dockerfile with new base image tag 2025-10-14 18:09:25 +08:00
Eric 30f03b7d89 perf: change python base
perf: update deps
2025-10-14 18:09:25 +08:00
wangruidong 28a97d0b5a fix: Incorrect language display in some email content 2025-10-14 18:08:21 +08:00
Eric 3410686690 perf: fix python base ci 2025-10-14 17:47:31 +08:00
Eric 6860e2327f perf: add python base ci build 2025-10-14 17:41:05 +08:00
feng 20253e760c perf: translate 2025-10-14 17:13:42 +08:00
Aaron3S a63cfde8d2 feat: add translate 2025-10-14 16:03:38 +08:00
feng 92e250e03b perf: user_can_authenticate add logger 2025-10-14 15:48:47 +08:00
wangruidong 098f0950cb fix: Incorrect language display in email content 2025-10-14 15:33:04 +08:00
feng 39b0830a6b perf: web script default [] 2025-10-14 13:59:11 +08:00
wangruidong 2e847bc2bc fix: Error in updating message subscription 500 2025-10-14 10:14:50 +08:00
wangruidong f82f31876a fix: Mysql has set a gateway, and the command execution failed. 2025-10-14 10:14:23 +08:00
github-actions[bot] cde182c015 perf: Update Dockerfile with new base image tag 2025-10-10 17:06:14 +08:00
Eric b990cdf561 perf: update deps 2025-10-10 17:06:14 +08:00
feng c9a062823d perf: Translate 2025-10-10 17:02:30 +08:00
feng 643ba4fc15 fix: Asset web script dont create 2025-10-10 11:43:11 +08:00
feng d16a55bbe2 perf: Ticket details cannot view assets from other organizations. 2025-10-09 18:41:25 +08:00
fit2bot ae31554729
perf: AppletHostOnly label match (#16109)
Co-authored-by: wangruidong <940853815@qq.com>
2025-10-09 18:13:37 +08:00
github-actions[bot] 53b47980a2 perf: Update Dockerfile with new base image tag 2025-10-09 16:55:50 +08:00
Eric d31b5ee570 perf: update Dockerfile-base 2025-10-09 16:55:50 +08:00
feng 65aea1ea36 perf: Push account and change secret support gid 2025-10-09 16:39:32 +08:00
feng 5abb5c5d5a perf: Themes deep blue 2025-10-09 15:36:14 +08:00
feng 93e41a5004 perf: Luna themes default 2025-10-09 15:02:37 +08:00
feng 95f51bbe48 perf: Perference add themes 2025-10-09 14:47:11 +08:00
feng 0184d292ec perf: MFA code 2025-10-09 14:29:08 +08:00
fit2bot 23a6d320c7
feat: update i18n (#16101)
* feat: data masking

* feat: update i18n

---------

Co-authored-by: Aaron3S <chenyang@fit2cloud.com>
Co-authored-by: 老广 <ibuler@qq.com>
2025-10-09 10:03:11 +08:00
Aaron3S b16304c48a feat: data masking 2025-10-09 09:59:23 +08:00
Gerry.tan 7cd1e4d3a0 perf: Dynamically configure the validity period of the email verification code 2025-09-28 11:26:32 +08:00
Eric 64a9987c3f perf: update rdp params 2025-09-28 11:20:52 +08:00
feng 18bfe312fa perf: open web ui 2025-09-25 15:49:10 +08:00
Bryan 9280884c1c
Merge pull request #16056 from jumpserver/dev
v4.10.8-lts
2025-09-18 16:52:13 +08:00
wangruidong c593f91d77 fix: Account backup: when sending to the mailbox fails, the task status also shows the success problem. 2025-09-18 15:44:35 +08:00
feng 46da05652a fix: Fixed the issue where the final connection verification failed when the domain name contains . 2025-09-18 14:08:00 +08:00
feng 9249aba1a9 perf: Video player version 2025-09-18 11:03:58 +08:00
fit2bot eca637c120
perf: Translate msg template (#16050)
* fix: Correct translation for device and user limits in django.po

* perf: Translate msg template

---------

Co-authored-by: wangruidong <940853815@qq.com>
2025-09-17 19:04:06 +08:00
feng ddacd5fce1 fix: Ticket direct approval 2025-09-17 18:58:16 +08:00
wangruidong 3ca5c04099 fix: Add ignore_https_errors option to browser context 2025-09-17 16:30:54 +08:00
wangruidong 6603a073ec fix: Case 2025-09-17 15:32:23 +08:00
wangruidong d745f7495a fix: Conflict 2025-09-17 15:32:23 +08:00
wangruidong 76f1667c89 perf: Restore msg template default value config 2025-09-17 15:32:23 +08:00
wangruidong 1ab1954299 fix: reset password msg error 2025-09-17 15:32:23 +08:00
wangruidong c8335999a4 perf: Translate msg template 2025-09-17 15:32:23 +08:00
feng 5b4a67362d perf: Translate 2025-09-17 15:10:54 +08:00
fit2bot e025073da2
fix: The number of exported data is incorrect (#16043)
Co-authored-by: wangruidong <940853815@qq.com>
2025-09-16 18:52:24 +08:00
feng 2155bc6862 perf: Migrate 2025-09-16 16:46:30 +08:00
wangruidong 953b515817 perf: Add is_alive filter to TerminalFilterSet 2025-09-16 16:30:57 +08:00
ibuler 7f7a354b2d fix: get obj error on queryset limit 2025-09-16 16:28:54 +08:00
Eric 2b2f7ea3f0 perf: add rdp true color 24 bit 2025-09-16 16:28:14 +08:00
feng 529123e1b5 perf: Translate 2025-09-16 16:15:09 +08:00
ibuler e156ab6ad8 fix: force page limit 2025-09-16 13:48:06 +08:00
wangruidong 3c1fd134ae fix: There is something wrong with the format of the site message 2025-09-16 13:33:43 +08:00
Bai b15f663c87 fix: AK/SK remained valid after the user expired. 2025-09-16 13:32:25 +08:00
wangruidong 93906dff0a fix: Export report pdf failed 2025-09-16 11:36:42 +08:00
Bai 307befdacd fix: login acl action reject > reviewers 500 2025-09-16 11:17:42 +08:00
feng626 dbfc4d3981 Revert "perf: User acl 500"
This reverts commit 849edd33c1.
2025-09-16 11:15:51 +08:00
feng 849edd33c1 perf: User acl 500 2025-09-16 10:50:41 +08:00
feng 37cceec8fe perf: get protocols error 500 2025-09-16 10:40:42 +08:00
feng d2494c25cc perf: Translate 2025-09-15 19:19:01 +08:00
feng 023952582e fix: Push account failed 2025-09-15 15:32:27 +08:00
halo 863fe95100 perf: client version 2025-09-12 18:53:16 +08:00
wangruidong 4b0bdb18c9 perf: Template msg example error 2025-09-12 18:47:47 +08:00
Eric 10da053a95 perf: change applet-hosts view default limit 2025-09-12 18:43:38 +08:00
mikebofs c40bc46520 fix: asset permission exclude accounts with -action 2025-09-12 11:16:27 +08:00
feng a732cc614e perf: Asset user login notify 2025-09-11 14:16:00 +08:00
ibuler bb29d519c6 perf: exclude accounts date expired 2025-09-11 11:42:44 +08:00
ibuler b56c3a76a7 fix: user option error 2025-09-11 11:21:59 +08:00
fit2bot ab908d24a7
perf: add i18n (#16001)
* perf: change some api view default limit

* perf: add i18n

---------

Co-authored-by: mikebofs <mikebofs@gmail.com>
2025-09-10 18:18:18 +08:00
fit2bot 79cabe1b3c
feat: setting email template content (#15974)
* feat: setting email template content

* perf: tempale list

* perf: custom template render to string

* perf: content serialize valid

* perf: Custom msg template base class

* perf: Template content reset

* perf: Update templates config

* perf: Remove useless code

---------

Co-authored-by: wangruidong <940853815@qq.com>
2025-09-10 16:49:52 +08:00
feng 231b7287c1 perf: Notify info css optimization 2025-09-10 14:04:19 +08:00
feng be7a4c0d6e perf: Create account unique message 2025-09-09 17:39:18 +08:00
feng 009da19050 perf: Change secret windows password cannot contain > ^ 2025-09-09 16:41:45 +08:00
feng dfda6b1e08 perf: Change secret del over report 2025-09-09 15:48:03 +08:00
fit2bot 59b40578d8
fix: adhoc SQL Server 2008 (#15984)
* fix: Resolve the issue of errors occurring during automated execution with SQL Server 2008

* fix: adhoc SQL Server 2008

* perf: add todo information

---------

Co-authored-by: halo <wuyihuangw@gmail.com>
2025-09-09 14:26:42 +08:00
Eric e5db28c014 perf: user add has_public_keys 2025-09-09 14:23:39 +08:00
Eric 6d1f26b0f8 perf: add redis cluster mode setting 2025-09-09 13:51:53 +08:00
Ewall555 2333dbbe33 fix: avoid AttributeError when default_limit is missing 2025-09-09 13:32:52 +08:00
fit2bot 16461b0fa9
perf: support global search (#15961)
* perf: support global search

* perf: change serach

* perf: search model add asset permission

---------

Co-authored-by: mikebofs <mikebofs@gmail.com>
Co-authored-by: ibuler <ibuler@qq.com>
2025-09-05 16:40:18 +08:00
mikebofs 528b0ea1ba perf: change some api view default limit 2025-09-05 16:20:26 +08:00
ibuler 60f06adaa9 fix: wechat or phone decrypt err 2025-09-04 11:59:04 +08:00
Bai 7a6187b95f fix: temp token backend 2025-09-03 18:10:10 +08:00
Bai aacaf3a174 perf: aks encrypt 2025-09-03 11:16:04 +08:00
Bai 3c9d2534fa perf: aks encrypt 2025-09-03 11:16:04 +08:00
wangruidong 4f79abe678 perf: Connect methods acl allow accept action 2025-09-03 11:00:56 +08:00
fit2bot ae9956ff91
chore: change readme 2025-09-02 15:22:44 +08:00
Bai 429677e0ce perf: readme 2025-09-02 14:54:28 +08:00
ibuler 034ee65157 perf: decrypt secret logic 2025-09-02 10:38:10 +08:00
Eric fdd7d9b6b1 perf: add vnc client method 2025-09-02 10:34:39 +08:00
wangruidong db0e21f5d9 fix: Lazy import Azure and Google Cloud dependencies 2025-08-29 11:10:43 +08:00
wangruidong 468b84eb3d perf: Validate connection token id 2025-08-29 11:09:40 +08:00
ibuler 28d5475d0f perf: try to decrypt then origin value 2025-08-29 11:00:02 +08:00
ibuler b9c60d856f perf: allow some api page no limits 2025-08-28 17:05:11 +08:00
feng bd1d73c6dd perf: Report localtime 2025-08-28 15:39:54 +08:00
wangruidong bf92c756d4 fix: Ensure command arguments are safely quoted in safe_run_cmd 2025-08-28 14:14:55 +08:00
feng 62ebe0d636 perf: Third login redirect url query string 2025-08-27 14:45:56 +08:00
github-actions[bot] 0b1fea8492 perf: Update Dockerfile with new base image tag 2025-08-27 11:05:19 +08:00
mikebofs 65b5f573f8 perf: change requirements 2025-08-27 11:05:19 +08:00
mikebofs bb639e1fe7 perf: revert django-simple-history version 2025-08-27 10:43:21 +08:00
fit2bot 395b868dcf
perf: swagger done (#15865)
* perf: swagger upgrade

* perf: upgrade to drf-spectacular

* perf: 添加部分注解

* perf: swagger done

---------

Co-authored-by: ibuler <ibuler@qq.com>
2025-08-27 10:27:01 +08:00
wangruidong 1350b774b3 perf: Improve chart rendering wait logic in export process 2025-08-26 16:20:22 +08:00
wrd af7a00c1b1 fix: typo 2025-08-26 15:31:13 +08:00
wangruidong 965ec7007c perf: Enhance eager loading by including labels in queryset 2025-08-26 15:31:13 +08:00
fit2bot 1372fd7535
feat: asset permission support exclude some account
* perf: add perm exclude

* perf: exclude node action account

* perf: add i18n

* perf: pop exclude account

---------

Co-authored-by: mikebofs <mikebofs@gmail.com>
2025-08-26 14:57:57 +08:00
wangruidong 3b0ef4cca7 fix: Add nmap to Dockerfile dependencies 2025-08-25 16:29:10 +08:00
Aaron3S 6832abdaad feat: change some translate 2025-08-25 11:05:49 +08:00
feng c6bf290dbb perf: Report translate 2025-08-22 18:57:14 +08:00
feng 23ab66c11a perf: Translate 2025-08-22 18:05:30 +08:00
feng 1debaa5547 perf: report perm 2025-08-22 17:53:52 +08:00
Bai 47413966c9 perf: captcha > CAPTCHA 2025-08-22 16:25:45 +08:00
Eric 703f39607c perf: default allow hosts 2025-08-22 14:12:45 +08:00
Bryan f31994fdcd
Merge pull request #15899 from jumpserver/dev 2025-08-21 19:03:18 +08:00
feng b65ff0d84c perf: Translate 2025-08-21 18:52:38 +08:00
wangruidong 30d781dd12 fix: Export PDF wait for render done 2025-08-21 18:44:09 +08:00
wangruidong 9551cd4da9 fix: Export PDF with org id 2025-08-21 17:56:26 +08:00
mikebofs 87b456c941 perf: change default width 2025-08-21 16:19:56 +08:00
mikebofs d4d5224c17 perf: support export dashboard 2025-08-21 16:19:56 +08:00
wangruidong dabb30d90a perf: Change report name 2025-08-21 16:19:25 +08:00
feng 82192d38e1 perf: Translate 2025-08-21 15:32:04 +08:00
feng 571d2b4575 perf: Custom platform translate 2025-08-21 14:51:38 +08:00
Eric ea64313c4e perf: fix conenct token platform fields 2025-08-21 14:03:15 +08:00
Bai 8764cdb733 feat: support protocols search 2025-08-21 11:49:18 +08:00
feng 980394efed perf: Transalte 2025-08-21 11:31:29 +08:00
wangruidong 2c94f10d64 fix: The approval setting org admin, and the approver is blank 2025-08-21 10:25:10 +08:00
wangruidong e1c9f5180d perf: Export pdf using days parameter 2025-08-21 10:23:00 +08:00
wangruidong 3f1d7fa230 perf: Pdf file i18n 2025-08-21 10:23:00 +08:00
wangruidong 44bcd6e399 fix: Send email pdf deps 2025-08-21 10:23:00 +08:00
feng 5f87d98c31 perf: Translate 2025-08-20 18:17:46 +08:00
feng 540becdcbe perf: org admin view settings 2025-08-20 17:11:27 +08:00
feng 6929c4968e perf: Check api 2025-08-20 11:16:46 +08:00
Aaron3S 63b213d3a8 feat: add translate 2025-08-19 19:19:23 +08:00
feng 64fe7a55ec perf: Mongodb ping 2025-08-19 19:08:52 +08:00
feng 27829e09ef perf: Translate 2025-08-19 18:57:23 +08:00
jiangweidong 1bfc7daef6 perf: Avoid Oracle password modification SQL injection risks 2025-08-19 18:55:46 +08:00
Bai 9422aebc5e perf: email i18n 2025-08-19 18:49:25 +08:00
wangruidong 8c0cd20b48 fix: Disable passkey mfa in safe mode 2025-08-19 18:21:33 +08:00
Bai 0c612648a0 perf: email protocol rename 2025-08-19 17:04:32 +08:00
feng 36e01a316c perf: Regular command groups can be filled in with new lines 2025-08-19 15:51:39 +08:00
feng e1b96e01eb perf: Translate 2025-08-19 15:05:13 +08:00
wangruidong 144f4b4466 fix: Virtual apps manifest i18n 2025-08-19 14:54:03 +08:00
wangruidong 8e007004c2 perf: Translate label for groups parameter 2025-08-19 14:51:52 +08:00
github-actions[bot] c14f740209 perf: Update Dockerfile with new base image tag 2025-08-19 14:50:45 +08:00
Eric 13a85f062c perf: fix uv pip resolution 2025-08-19 14:50:45 +08:00
fit2bot 7f9d027bd3
perf: Send command translate (#15820)
Co-authored-by: wangruidong <940853815@qq.com>
Co-authored-by: Bryan <jiangjie.bai@fit2cloud.com>
2025-08-18 19:14:48 +08:00
wangruidong c037ce1c29 perf: Send report email 2025-08-18 19:12:29 +08:00
wangruidong ee7c6b4708 fix: Init db error 2025-08-18 19:11:59 +08:00
feng d0e625e322 perf: Translate 2025-08-18 19:08:34 +08:00
feng c65794a99d perf: KOKO translate 2025-08-18 18:39:42 +08:00
Eric 1e4bca6e24 perf: add lion i18n 2025-08-18 18:28:22 +08:00
feng c1c5025fbb perf: Account automation report 2025-08-18 17:40:49 +08:00
Eric 96020fa6b4 perf: add lion i18n 2025-08-18 11:42:33 +08:00
wangruidong 5ad6f87a9e fix: Docker build error 2025-08-18 10:53:33 +08:00
feng 9b0c73c9f9 perf: translate 2025-08-15 18:57:46 +08:00
wangruidong c029714ffd fix: Export pdf failed 2025-08-15 17:42:48 +08:00
wangruidong c1e8a1b561 fix: Install export pdf deps 2025-08-15 17:42:48 +08:00
feng 21126de2c1 perf: get_cpu_model_count 2025-08-15 16:45:39 +08:00
feng 7d06819bbe perf: foot_js 2025-08-15 16:35:43 +08:00
Eric 92b20fe2ef perf: add lion i18n 2025-08-15 16:24:18 +08:00
feng 4326d35065 perf: User report 2025-08-14 18:55:15 +08:00
feng 4810eae725 perf: group_stats 2025-08-14 16:09:43 +08:00
fit2bot 24f7946b7b
perf: change some field to encrypt field (#15842)
* perf: conn token add remote addr

* perf: change some field to encrypt field

---------

Co-authored-by: ibuler <ibuler@qq.com>
2025-08-14 15:05:18 +08:00
王晓阳 4b9c4a550e
feat: support vastbase 2025-08-14 14:31:31 +08:00
feng d3ec23ba85 perf: group_stats 2025-08-14 11:45:36 +08:00
feng e3c33bca32 perf: User report 2025-08-14 11:12:58 +08:00
feng 0fb7e84678 perf: user asset account report 2025-08-13 18:51:08 +08:00
feng ab30bfb2d2 perf: mysql pg playbook 2025-08-13 15:15:53 +08:00
feng d9d034488f fix: report 2025-08-12 19:19:00 +08:00
feng 24bd7b7e1a fix rbac pam 2025-08-12 14:48:16 +08:00
wangruidong 7fb5fd3956 fix: set ansible_timeout for account connectivity tasks 2025-08-11 10:37:23 +08:00
feng 9c621f5ff5 perf: rbac pam 2025-08-08 13:52:38 +08:00
feng ac8998b9ee perf: Account risk delete normal account 2025-08-06 17:02:53 +08:00
wangruidong b258537890 fix: Fallback to browser language if user language is not set 2025-08-06 14:15:30 +08:00
fit2bot b38d83c578
feat: report charts (#15630)
* perf: initial

* perf: basic finished

* perf: depend

* perf: Update Dockerfile with new base image tag

* perf: Add user report api

* perf: Update Dockerfile with new base image tag

* perf: Use user report api

* perf: Update Dockerfile with new base image tag

* perf: user login report

* perf: Update Dockerfile with new base image tag

* perf: user change password

* perf: change password dashboard

* perf: Update Dockerfile with new base image tag

* perf: Translate

* perf: asset api

* perf: asset activity

* perf: Asset report

* perf: add charts_map

* perf: account report

* perf: Translate

* perf: account automation

* perf: Account automation

* perf: title

* perf: Update Dockerfile with new base image tag

---------

Co-authored-by: ibuler <ibuler@qq.com>
Co-authored-by: feng <1304903146@qq.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: wangruidong <940853815@qq.com>
Co-authored-by: feng626 <57284900+feng626@users.noreply.github.com>
2025-08-06 14:05:38 +08:00
feng 257f290d18 perf: Translate 2025-08-06 11:33:52 +08:00
wangruidong d185be2180 perf: Optimize redis connection number 2025-08-04 18:53:34 +08:00
ibuler 4e33b5b478 perf: some risk example file path 2025-08-01 10:35:15 +08:00
wangruidong 1406437d4e fix: Failed to switch languages 2025-08-01 10:24:17 +08:00
feng e46aa95980 perf: check_asset_permission_will_expired filter is_active=True 2025-08-01 10:18:52 +08:00
Eric c619a35a04 perf: update lion i18n tip 2025-08-01 10:18:12 +08:00
wangruidong 29f10bf10e perf: ES connect error detail 2025-07-31 17:15:55 +08:00
wangruidong a822905ae7 fix: When the cas user doesn't exist, you will be prompted with an error when logging in. 2025-07-31 17:15:18 +08:00
zhaojisen dc5a743f4f revert style 2025-07-30 14:27:52 +08:00
zhaojisen 1de8781704 Fixed: Fix the issue with the login page footer 2025-07-30 14:27:52 +08:00
wangruidong f3d9f4c446 fix: Failed to switch languages 2025-07-29 16:40:30 +08:00
jiangweidong 6b5d5c15ae feat: Add an embedded form to ChatAI 2025-07-29 14:15:01 +08:00
feng 1074a0df19 perf: MFA coce reuse 2025-07-29 11:00:39 +08:00
Eric 04dca794dd fix: fix chrome_app password_manager dialog 2025-07-29 10:21:46 +08:00
ibuler 14e0396508 perf: change ip db path 2025-07-29 10:20:37 +08:00
wangruidong 835eb2e3d0 perf: Improve error handling for email sending in tasks 2025-07-28 10:30:42 +08:00
ibuler be24f28d9b perf: in safe mode passkey cannot be as mfa 2025-07-25 10:50:46 +08:00
wangruidong 26cea550c4 fix: The applet list is not translated. 2025-07-25 10:49:47 +08:00
wangruidong 36ae076cb0 fix: Open redirect security vulnerability 2025-07-24 15:50:05 +08:00
feng 51c5294fb4 perf: Ticket filter org 2025-07-24 14:36:15 +08:00
feng da083fffa3 perf: Translate email help text 2025-07-24 14:35:21 +08:00
feng 1df04d2a94 perf: Pam rbac 2025-07-23 10:21:38 +08:00
Eric 299e52cd11 perf: vnc_guide method only by xpack 2025-07-22 14:37:38 +08:00
feng 38b268b104 fix: Circular import 2025-07-22 14:36:22 +08:00
wangruidong 6095e9c9bd perf: Modify the layout to flex 2025-07-22 14:35:05 +08:00
ibuler c4a348aac6 perf: remove client redirect api 2025-07-22 14:34:11 +08:00
feng 75575af56f perf: Callback client 2025-07-22 13:51:08 +08:00
Bryan 71766418bb
Merge pull request #15742 from jumpserver/dev
merge: v4.10.4-lts
2025-07-17 15:12:58 +08:00
feng 8f91cb1473 perf: Translate 2025-07-17 15:12:01 +08:00
feng b72e8eba7c perf: Change the secret and retry in batches 2025-07-17 14:21:31 +08:00
feng d1d6f3fe9c perf: string_punctuation remove > ^ 2025-07-17 14:02:19 +08:00
wangruidong 6095c9865f fix: Action tips translate 2025-07-17 11:48:28 +08:00
wangruidong 6c374cb41f fix: View replay generate multiple operation logs 2025-07-17 11:24:16 +08:00
Eric df64145adc perf: lion i18n 2025-07-16 19:49:07 +08:00
ibuler 44d77ba03f perf: random password exclude some char 2025-07-16 19:35:04 +08:00
wangruidong 3af188492f fix: Gather account failed 2025-07-16 19:19:43 +08:00
feng 9e798cd0b6 perf: Translate and tools version 2025-07-16 17:43:35 +08:00
feng 4d22c0722b fix: Exclude special char failed 2025-07-16 16:10:17 +08:00
Eric e6a1662780 perf: add lion i18n 2025-07-15 18:58:42 +08:00
wangruidong cc4be36752 perf: Log IntegrityError details during user authentication 2025-07-15 18:58:16 +08:00
wangruidong e1f5d3c737 fix: Delete user failed(DoesNotExist) when user create share session 2025-07-15 18:43:43 +08:00
wangruidong c0adc1fe74 fix: Gather account error 2025-07-15 18:43:14 +08:00
feng 613715135b perf: Translate 2025-07-15 11:46:39 +08:00
Eric fe1d5f9828 perf: add en i18n 2025-07-11 15:34:24 +08:00
Eric 1d375e15c5 perf: add i18n keys 2025-07-11 15:34:24 +08:00
Eric ac21d260ea perf: add lion i18n 2025-07-11 15:34:24 +08:00
wangruidong accde77307 fix: Add third party login check is block 2025-07-11 15:33:48 +08:00
ibuler c7dcf1ba59 perf: playbook task db save if conn timeout 2025-07-11 11:00:20 +08:00
wangruidong b564bbebb3 perf: Translate 2025-07-11 10:30:40 +08:00
Eric 9440c855f4 perf: add lion i18n 2025-07-10 12:50:11 +08:00
w940853815 f282b2079e Update comment 2025-07-10 11:39:37 +08:00
wangruidong 1790cd8345 fix: Add additional third-party authentication backends and adjust MFA check 2025-07-10 11:39:37 +08:00
ibuler 7da74dc6e8 fix: integrate with azure oidc 2025-07-10 11:33:41 +08:00
Ewall555 33b0068f49 feat: exclude SSO token permissions for change and delete actions 2025-07-10 11:29:18 +08:00
Ewall555 9a446c118b feat: support rbac SSO token 2025-07-10 11:29:18 +08:00
Eric 4bf337b2b4 perf: add VNC terminal type 2025-07-10 11:28:32 +08:00
wangruidong 2acbb80920 perf: Add account date_expired 2025-07-09 10:47:06 +08:00
gerry-f2c ae859c5562
perf: dbeaver uses a fixed driver directory (#15689) 2025-07-08 18:02:24 +08:00
Eric a9bc716af5 perf: add encrypt field for sqlserver 2008 2025-07-08 18:01:31 +08:00
feng 2d5401e76e perf: Translate 2025-07-08 16:01:52 +08:00
Gerry.tan d933e296bc perf: ES command log supports fuzzy search 2025-07-08 11:25:44 +08:00
wangruidong 1e5a995917 fix: Ticket filter error 2025-07-08 10:42:40 +08:00
wangruidong baaaf83ab9 perf: Translate 2025-07-08 10:35:04 +08:00
wangruidong ab06ac1f1f perf: Update IP group validation to include address validation 2025-07-08 10:34:34 +08:00
jiangweidong 99c4622ccb fix: SSO access to web assets with encrypted password auto-filling 2025-07-08 10:19:32 +08:00
Eric 9bdfab966f perf: add replay_size on session 2025-07-08 10:18:54 +08:00
老广 1a1acb62de
Update README.md 2025-07-08 10:16:43 +08:00
wanghe-fit2cloud 2a128ea01b docs: Add GitCode badges 2025-07-07 15:33:08 +08:00
王贺 5a720b41bf docs: Add GitCode badge 2025-07-07 13:42:15 +08:00
feng 726c5cf34d fix: View replay record operate log 2025-07-07 10:37:29 +08:00
wangruidong 06afc8a0e1 perf: Translate 2025-07-02 19:04:15 +08:00
ibuler 276fd928a7 perf: add pg client 2025-07-01 16:18:25 +08:00
dependabot[bot] 05c6272d7e chore(deps): bump requests from 2.31.0 to 2.32.4
Bumps [requests](https://github.com/psf/requests) from 2.31.0 to 2.32.4.
- [Release notes](https://github.com/psf/requests/releases)
- [Changelog](https://github.com/psf/requests/blob/main/HISTORY.md)
- [Commits](https://github.com/psf/requests/compare/v2.31.0...v2.32.4)

---
updated-dependencies:
- dependency-name: requests
  dependency-version: 2.32.4
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-07-01 15:59:44 +08:00
Bai c3f877d116 fix: check count 2025-07-01 15:35:17 +08:00
wangruidong 60deef2abf fix: Org admin cannot use system tools. 2025-07-01 15:23:34 +08:00
wangruidong 058754dc1b perf: Translate time cost 2025-06-30 10:05:13 +08:00
feng a238c5d34b perf: operate record 2025-06-27 19:03:24 +08:00
feng626 76c6ed0f95
Merge pull request #15649 from jumpserver/pr@dev@translate
perf: Translate
2025-06-27 14:01:16 +08:00
feng626 0d07f7421b
Merge branch 'dev' into pr@dev@translate 2025-06-27 14:01:05 +08:00
Ewall555 b07d4e207c perf: Translate 2025-06-27 13:59:57 +08:00
feng dc92963059 perf: Translate 2025-06-27 13:15:07 +08:00
feng 9abd708a0a fix: ES search session count 2025-06-27 10:32:28 +08:00
jiangweidong c9270877eb fix: According to the CMPP2.0 protocol standard, modify the attribute alignment. 2025-06-26 18:41:30 +08:00
feng b5518dd2ba perf: Pam perm tree 2025-06-26 18:14:57 +08:00
wangruidong 1d40f5ecbc fix: Handle ValidationError in account_obj property 2025-06-26 15:23:16 +08:00
ibuler 91fee6c034 perf: change some 18n 2025-06-26 14:54:06 +08:00
feng 1b65055c5e perf: Account backup backup_type limit 2025-06-23 18:27:27 +08:00
feng e79ef516a5 perf: Change secret windoes translate 2025-06-23 15:59:55 +08:00
Ewall555 8843f247d6 fix: Use local Python interpreter variable in RDP automation scripts 2025-06-23 14:15:46 +08:00
ibuler cb42df542d fix: bitwardne request data encode 2025-06-23 14:13:15 +08:00
Ewall555 46ddad1d59 perf: Update metismenu plugin to version 3.0.7 2025-06-23 14:11:23 +08:00
Bryan a9399dd709
Merge pull request #15608 from jumpserver/dev
v4.10.2
2025-06-19 20:14:21 +08:00
feng f55a6ae364 perf: Translate 2025-06-19 20:09:06 +08:00
feng 34772b8fb4 fix: client login get session_key 2025-06-19 18:48:46 +08:00
feng 286891061b perf: face acl 2025-06-19 17:58:08 +08:00
feng 269bf1283e perf: Translate 2025-06-19 17:07:25 +08:00
Bai d32c11bced fix: login page i18n same with personal settings 2025-06-19 16:47:53 +08:00
feng fb64af2eb2 perf: Translate 2025-06-19 16:17:09 +08:00
Eric 82f32cbba3 perf: replace koko category to luna 2025-06-19 16:09:41 +08:00
wangruidong 411b485448 fix: The title of the risk detection email and server performance check notification i18n 2025-06-19 15:33:46 +08:00
feng 60608e92ea fix: Connection failure after directly connecting to asset ACL 2025-06-19 15:28:12 +08:00
feng 6922c62b50 perf: Translate 2025-06-19 11:49:47 +08:00
Eric 531c23d983 perf: add lina i18n 2025-06-19 10:22:24 +08:00
feng df9e6cf866 perf: Translate 2025-06-18 16:37:33 +08:00
halo 65f2b92eb3 perf: Update client version and perf translate 2025-06-17 19:26:59 +08:00
feng626 bac621991e
Merge pull request #15592 from jumpserver/pr@dev@translate
perf: Translate
2025-06-17 19:26:52 +08:00
feng626 db24d34b64
Merge branch 'dev' into pr@dev@translate 2025-06-17 19:25:59 +08:00
feng 265c066054 perf: Translate 2025-06-17 19:23:55 +08:00
feng dad6b5def0 perf: Translate 2025-06-17 18:51:39 +08:00
feng 00f6c3a5de perf: Change secret record 2025-06-17 17:11:25 +08:00
wangruidong cfbd162890 fix: Correct language retrieval in profile to use the provided object 2025-06-16 19:04:45 +08:00
wangruidong 17e8f25cb4 fix: Update language preference setting to include category 2025-06-16 19:04:45 +08:00
wangruidong 71bf8c8699 fix: The luna page cannot switch language settings 2025-06-16 19:04:45 +08:00
wangruidong 98342e0b70 fix: The login page cannot switch language settings 2025-06-16 19:04:45 +08:00
wangruidong 70aaa9cf8f fix: Activate user language when sending emails 2025-06-16 19:04:45 +08:00
Aaron3S 70b2d28760 feat: remove fuzzy 2025-06-16 18:40:18 +08:00
Aaron3S 8265a069e2 feat: translate 2025-06-16 18:40:18 +08:00
feng 9ec48aae0c perf: Translate 2025-06-16 14:55:23 +08:00
feng 41658af8fd perf: Suggestion api 2025-06-16 14:03:27 +08:00
fit2bot 7dfb31840e
tinkner request ak first 2025-06-16 11:39:20 +08:00
ibuler 2f55db60ec perf: change redirect client auth to session 2025-06-13 10:41:28 +08:00
ibuler 551e6d0479 perf: client login redirect 2025-06-13 10:41:28 +08:00
feng 61c54314d7 perf: Face translate 2025-06-12 18:55:35 +08:00
wangruidong 4e7cd37c1d fix: Ensure user language is activated when sending notifications 2025-06-12 18:30:22 +08:00
wangruidong e89f43dcd3 perf: Translate 2025-06-12 18:30:22 +08:00
wangruidong 259ead4c6e fix: Prevent nested resource issues in type nodes tree API 2025-06-12 18:29:22 +08:00
feng 348b2a833a perf: Translate 2025-06-12 18:28:33 +08:00
feng 8aec1604ce perf: Change secret clear account queue status 2025-06-12 16:55:04 +08:00
feng be28a6954a perf: Login to change password and filter out useless accounts 2025-06-11 19:16:29 +08:00
feng 79c2284a01 perf: Change secret after successful login 2025-06-11 18:41:31 +08:00
feng c2b44cfd84 perf: Translate 2025-06-11 16:36:55 +08:00
ibuler 1e07cba545 perf: open svc account register on deploy 2025-06-11 13:32:00 +08:00
ibuler 48a9b2664a perf: change ftplog asset length 2025-06-11 13:27:23 +08:00
ZhaoJiSen b3bfbf5046
Merge pull request #15550 from jumpserver/pr@dev@send_mail_async
perf: send_mail_async func log subject recipients info
2025-06-11 11:17:25 +08:00
feng 08aa1e48b9 perf: send_mail_async func log subject recipients info 2025-06-11 11:16:03 +08:00
ZhaoJiSen 97d7427090
Merge pull request #15549 from jumpserver/pr@dev@translate
perf: Translate
2025-06-10 19:14:21 +08:00
feng 9f9d5855c4 perf: Translate 2025-06-10 19:12:31 +08:00
ZhaoJiSen 2db8f0f444
Merge pull request #15546 from jumpserver/pr@dev@send_mail_async
perf: send_mail_async add log
2025-06-10 17:47:22 +08:00
feng b75210b0c3 perf: send_mail_async add log 2025-06-10 17:45:59 +08:00
wangruidong 4713c6ddf6 fix: Task search error 2025-06-10 16:58:37 +08:00
feng b70fb58faf perf: Change secret after successful login 2025-06-10 16:57:28 +08:00
Aaron3S 3991976a00 feat: magnus support mongodb 2025-06-10 15:51:12 +08:00
ewall555 90256208dd perf: Update jsencrypt library version 2025-06-09 18:43:18 +08:00
wangruidong bbd3b32aa1 perf: Remove username hint 2025-06-09 16:58:51 +08:00
wangruidong ec20a4fd02 fix: Failed to update database assets 2025-06-09 15:04:27 +08:00
wangruidong d179ce1cd4 perf: Add celery worker count config 2025-06-09 14:02:31 +08:00
ZhaoJiSen caf23f5b05
Merge pull request #15529 from jumpserver/pr@dev@translate
perf: Translate
2025-06-06 18:23:10 +08:00
feng626 4bb19d59ef
Merge branch 'dev' into pr@dev@translate 2025-06-06 18:22:24 +08:00
feng 74ed693a95 perf: Translate 2025-06-06 18:19:44 +08:00
feng 4a7a1fd95c perf: Optimize the results returned by the suggestion api for different organizations 2025-06-06 18:09:05 +08:00
wangruidong 56268433e0 perf: Translate adhoc 2025-06-06 17:56:53 +08:00
ibuler ea59677b13 perf: swagger auth required 2025-06-06 17:56:25 +08:00
ibuler 94ed26e115 perf: change i18n 2025-06-06 17:56:25 +08:00
wangruidong 284d793253 perf: leak password can bulk delete 2025-06-06 17:05:13 +08:00
wangruidong 570566d9dd perf: set ansible_timeout for account connectivity tasks 2025-06-04 18:41:41 +08:00
wangruidong 3f85c67aee perf: Add retention period for expired user tokens and implement cleanup task 2025-06-04 18:39:49 +08:00
wangruidong 53a84850dc fix: Ensure platform_id is a digit before querying Platform 2025-06-04 18:37:05 +08:00
feng e4be9621bb perf: Custom push account 2025-06-03 14:52:06 +08:00
Eric f8b778ada2 perf: tinker to v0.2.2 2025-06-03 13:54:21 +08:00
fit2bot 5c28b15e39
perf: update chrome applet to support language setting (#15509)
* perf: update chrome applet to support language setting

* perf: fix field name

---------

Co-authored-by: Eric <xplzv@126.com>
2025-06-03 13:54:04 +08:00
wangruidong 5e0babdba8 perf: Language settings in personal settings 2025-05-29 11:13:04 +08:00
feng 8a3acb649e fix: ES non-global organizations cannot be queried 2025-05-27 14:31:27 +08:00
Eric 1ade652381 perf: upgrade tinker to v0.2.1 2025-05-23 11:20:17 +08:00
github-actions[bot] 7472f83d7a Auto-translate README 2025-05-22 18:34:57 +08:00
Bai c56a3d0a2e perf: add ko readme 2025-05-22 18:10:34 +08:00
feng 1a10225823 perf: view task log 2025-05-22 17:44:19 +08:00
feng 56c94d7b3c fix: The account suggestions api cannot find the account associated with the DS 2025-05-22 11:50:17 +08:00
ibuler 16e7a12974 perf: static file download and catch 2025-05-20 13:14:47 +08:00
ibuler 1364889083 fix: aggregate resource api 2025-05-20 13:14:21 +08:00
feng 4f19954640 perf: SSO add mfa 2025-05-20 13:12:13 +08:00
feng 1b2e376681 perf: Account list not display spec_info field 2025-05-19 16:13:36 +08:00
ibuler 14c5162153 perf: client auth changed 2025-05-19 11:27:31 +08:00
Bai f9245e17cd perf: readme 2025-05-16 18:43:39 +08:00
Aaron3S 6bd1ec960b feat: add a new piico gm alg 2025-05-16 15:07:39 +08:00
ibuler 77cc02ae60 perf: change google authenticator apk download 2025-05-15 17:41:49 +08:00
Bryan d0cb9e5432
Merge pull request #15412 from jumpserver/dev
v4.10.0
2025-05-15 17:11:43 +08:00
feng 9969395500 fix: perm del node and user group 500 2025-05-15 15:55:32 +08:00
wangruidong e1f03a194b fix: Asset list gather account raise connection already closed 2025-05-15 15:48:19 +08:00
Eric aa0125385a perf: fix NoneType error 2025-05-15 15:01:57 +08:00
feng 8e8579bebe perf: translate 2025-05-15 14:41:19 +08:00
feng ad5ce5d4cf perf: translate 2025-05-15 14:01:51 +08:00
ibuler 4f009504ad perf: load custom protocols 2025-05-15 11:41:33 +08:00
ibuler 986bc926fc perf: iframe set to sameorigin 2025-05-14 19:29:16 +08:00
feng 6aafb0f01a perf: Translate 2025-05-14 18:18:45 +08:00
feng 43775096d1 perf: Login switch language 2025-05-14 17:40:09 +08:00
ibuler f826f43495 perf: simplify db using 2025-05-14 15:11:46 +08:00
ibuler e9ff988d8c perf: db connection close if needt 2025-05-14 14:43:14 +08:00
feng a72e6456d9 perf: Connect method exclude face 2025-05-14 14:02:27 +08:00
ibuler 941a784a5b perf: 修改 migrations 2025-05-13 19:15:01 +08:00
ibuler edaf9bb0b2 perf: domain enabled to gateway enabled 2025-05-13 16:36:56 +08:00
feng e8ca177fe4 perf: translate 2025-05-13 14:50:14 +08:00
ewall555 a88ebeff15 feat: Set the default expiration days for adding user and asset permissions 2025-05-13 10:35:21 +08:00
ibuler bd0c50a3e4 fix: account username has domain, then set again 2025-05-12 18:36:26 +08:00
feng 9f121723c4 perf: auditor add asset user view perm 2025-05-12 17:57:48 +08:00
feng 245ed79b17 perf: Translate 2025-05-12 17:05:37 +08:00
ibuler 01c07a834b perf: 修改 adhoc 翻译 2025-05-12 10:50:43 +08:00
ibuler 4fb61e0af6 perf: org id error 2025-05-12 10:24:33 +08:00
Emmanuel Ferdman 19b7be33ae Resolve warnings of logger library
Signed-off-by: Emmanuel Ferdman <emmanuelferdman@gmail.com>
2025-05-12 09:51:30 +08:00
feng 7797c76032 perf: migrate 2025-05-09 18:25:41 +08:00
老广 eb777854d4
Pr@dev@fix django version (#15374)
* fix: Downgrade django and djangorestframework versions for compatibility

* perf: Update Dockerfile with new base image tag

* perf: Update Dockerfile with new base image tag

---------

Co-authored-by: wangruidong <940853815@qq.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-05-09 17:50:11 +08:00
Eric 22d4bd5292 perf: optimize file removal 2025-05-09 17:21:24 +08:00
ibuler 47d0d8b7a0 perf: stop dep check 2025-05-09 17:20:33 +08:00
wangruidong 5e298e5749 fix: Downgrade django and djangorestframework versions for compatibility 2025-05-09 16:10:49 +08:00
w940853815 ad3ba5034e Revert "fix: Upgrading django version causes json serialization problems"
This reverts commit ad56845d89.
2025-05-09 16:04:58 +08:00
feng f1a1c3660d perf: Luna en translate 2025-05-09 15:14:56 +08:00
feng eaf5bc5eb3 perf: I18n api 2025-05-09 14:46:48 +08:00
feng 30e680ad91 fix: ES the calculated quantity is 0 2025-05-08 17:23:15 +08:00
wangruidong c9f281e8f7 fix: Handle exceptions in leak password check 2025-05-08 17:13:23 +08:00
wangruidong ad56845d89 fix: Upgrading django version causes json serialization problems 2025-05-08 17:12:53 +08:00
feng c3dceec3c7 perf: Connectivity add rdp error 2025-05-08 16:07:30 +08:00
wangruidong 100dad75f1 fix: i18n error 2025-05-08 14:50:54 +08:00
feng aa52060f24 perf: Upgrade bootstrap js to 5.3.6 2025-05-08 14:12:17 +08:00
wangruidong 089a5f50f4 feat: Add LeakPasswords config 2025-05-07 17:47:22 +08:00
feng626 0bdbb6fd84
Merge pull request #15352 from jumpserver/pr@dev@connectivity_choice
perf: Connectivity choice
2025-05-07 17:30:48 +08:00
feng626 dd5bcab4ff
Merge branch 'dev' into pr@dev@connectivity_choice 2025-05-07 17:30:30 +08:00
feng 49f0e51769 perf: Connectivity choice 2025-05-07 17:25:10 +08:00
wangruidong 5577e39f21 perf: Support watermark customization 2025-05-07 16:52:58 +08:00
老广 e2830ecdd6
perf: passkey auth auto mfa 2025-05-07 16:24:39 +08:00
feng 8065e04f26 perf: Translate 2025-05-07 15:50:04 +08:00
feng fe70b60e95 perf: Users lina translate 2025-05-07 11:31:22 +08:00
feng 1f7836353a perf: translate 2025-05-07 10:32:08 +08:00
feng a4296b3129 perf: Clean push record period 2025-05-06 18:32:56 +08:00
feng ffc92fa7b4 perf: Clean push record period 2025-05-06 18:22:54 +08:00
github-actions[bot] f94e032858 perf: Update Dockerfile with new base image tag 2025-04-30 11:13:34 +08:00
ibuler 25429e30ba perf: update quirements 2025-04-30 11:13:34 +08:00
CaptainB 5c7d539c6f chore: Configure Dependabot to group Python dependencies 2025-04-30 11:04:21 +08:00
fit2bot a8a6e03428
perf: update deps 2025-04-30 10:58:19 +08:00
wangruidong 71b9b2df74 fix: Add AdminConnectionToken to operate log exclude_models 2025-04-30 10:51:25 +08:00
Eric f1bc69b253 perf: add luna i18n 2025-04-29 18:12:10 +08:00
wangruidong 282ca25504 perf: Skip alert if login city seen in past 7 days 2025-04-29 17:46:10 +08:00
fit2bot 1bb44e783a
perf: some i18n (#15312)
Co-authored-by: ibuler <ibuler@qq.com>
2025-04-29 17:45:29 +08:00
feng a64fe4b0be perf: Account translate 2025-04-29 14:44:22 +08:00
feng a75faf8da6 perf: Discover account translate 2025-04-29 14:36:13 +08:00
Bryan 537a9325a3
Update README.md (#15305)
* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md
2025-04-28 11:36:05 +08:00
feng a9d455e867 perf: ntlm_err 2025-04-27 18:53:43 +08:00
feng d06d26ac54 perf: Display asset/account connectivity error message 2025-04-27 18:50:00 +08:00
fit2bot e992c44e11
perf: change lfs files download (#15293)
* perf: change lfs files download

* perf: clean unused ansible module

* perf: update lfs download

* perf: Update Dockerfile with new base image tag

* perf: change download path

* perf: Update Dockerfile with new base image tag

---------

Co-authored-by: ibuler <ibuler@qq.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-04-27 14:35:10 +08:00
feng 24fe058fd9 perf: lina translate 2025-04-25 18:07:09 +08:00
feng a3fef9cc54 perf: Update the key when the integration-application is updated or created 2025-04-25 17:29:44 +08:00
ibuler 471053e62a perf: change mcp integrate 2025-04-25 17:28:03 +08:00
jiangweidong dc6308b030 perf: if the apply-asset-ticket name is 128 characters long, will raise 500 2025-04-25 17:27:13 +08:00
feng f016ae6161 perf: add sftplog command models field index 2025-04-25 15:21:55 +08:00
feng 14a8d877e0 perf: ko translate 2025-04-25 15:04:03 +08:00
feng ddf20570a1 perf: device support ad 2025-04-23 19:38:01 +08:00
feng 1ad9616b7f perf: gather facts gpu info 2025-04-22 17:48:21 +08:00
刘瑞斌 d7bc6bb201 chore: use uv as package-ecosystem 2025-04-21 13:36:24 +08:00
feng f855043468 perf: luna ru translate 2025-04-21 11:34:51 +08:00
fit2bot 3159a4e794
perf: change domain to zone (#15255)
* perf: change domain to zone

* perf: change domain to zone

* perf: change some word

* perf: update gateway enabled i18n

* perf: change migrations

---------

Co-authored-by: ibuler <ibuler@qq.com>
2025-04-21 10:30:18 +08:00
feng 57fcebfdd3 fix: No data found for the carrying organization 2025-04-18 16:50:07 +08:00
feng626 c500bb4e4c Revert "Revert "perf:Stored command records in ES support accurate searching.""
This reverts commit 6bc1c5bd50.
2025-04-18 16:50:07 +08:00
feng fd062b0da6 perf: ru translate 2025-04-18 14:52:44 +08:00
ibuler bcb112d5c6 perf: user profile api 2025-04-18 14:11:56 +08:00
fit2bot 533dbf316c
perf: add ali rds dependencies (#15247)
* perf: add ali rds dependencies

* perf: Update Dockerfile with new base image tag

---------

Co-authored-by: Eric <xplzv@126.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-04-18 12:11:51 +08:00
github-actions[bot] 9cce94b709 perf: Update Dockerfile with new base image tag 2025-04-18 11:53:40 +08:00
Eric 8b815d812b perf: modify Dockerfile-base 2025-04-18 11:53:40 +08:00
github-actions[bot] a168fc8a62 perf: Update Dockerfile with new base image tag 2025-04-18 11:29:07 +08:00
Eric faae1a09d1 perf: lint dependencies 2025-04-18 11:29:07 +08:00
github-actions[bot] 26e819e120 perf: Update Dockerfile with new base image tag 2025-04-18 11:29:07 +08:00
Eric 79579654a1 perf: use uv tool
perf: add Homepage
perf: add env
2025-04-18 11:29:07 +08:00
老广 558188da90
merge: dev to master
Ready to relase
2025-04-17 20:24:45 +08:00
feng626 6bc1c5bd50 Revert "perf:Stored command records in ES support accurate searching."
This reverts commit 3d6d2af268.
2025-04-17 20:16:06 +08:00
ibuler 36f312b943 perf: page queryset mixin 2025-04-17 19:47:51 +08:00
ibuler 11811c453b perf: page queryset mixin 2025-04-17 19:47:51 +08:00
ibuler 12fadeec58 perf: revert terminal api 2025-04-17 19:34:23 +08:00
ibuler b49fd21e08 perf: 虚拟账号 api 2025-04-17 17:50:42 +08:00
feng 9b982eb592 perf: change secret api perm 2025-04-17 17:15:06 +08:00
wangruidong 31652ef5b1 fix: include openid in source validation logic 2025-04-17 16:24:00 +08:00
feng 8fef18b991 perf: gather account windows playbook failed_when: false 2025-04-17 15:55:49 +08:00
ibuler c804c053d2 perf: revert api 2025-04-17 15:53:52 +08:00
ibuler bef2282604 perf: asset list compute account amount 2025-04-17 15:15:36 +08:00
feng cabc069045 perf: Translate 2025-04-17 15:12:16 +08:00
feng 99c9a021b7 fix: update applet host (platform failed) 2025-04-17 14:55:36 +08:00
ibuler 6cb3cc1f29 perf: 修改 DS 的一些翻译 2025-04-17 14:47:11 +08:00
feng 67422ef4ba fix: automation no account 2025-04-17 14:00:24 +08:00
gerry 3d6d2af268 perf:Stored command records in ES support accurate searching. 2025-04-17 11:43:16 +08:00
wangruidong ee97e45cc3 fix: Allow superusers delete adhoc and playbook 2025-04-17 10:54:47 +08:00
feng 0131eaa6db perf: es search 2025-04-16 18:15:58 +08:00
feng eaa390fd6f perf: update asset directory_services allow_empty true 2025-04-16 17:39:55 +08:00
ibuler e2b8fd0d40 perf: change account filter by asset 2025-04-16 17:37:36 +08:00
feng 2aace05099 perf: as account username 2025-04-16 17:29:23 +08:00
ibuler 1ee70af93d perf: applet account select 2025-04-16 16:43:34 +08:00
feng fa70fb2921 perf: Translate 2025-04-16 15:37:11 +08:00
ibuler 01a6019022 perf: swagger api 2025-04-16 14:53:51 +08:00
wangruidong 5c61a11d82 fix: add periodic_display to read_only_fields in Job serializer 2025-04-16 14:18:11 +08:00
fit2bot 67f3341310
perf: change db prefetch (#15215) 2025-04-16 13:48:12 +08:00
feng cb49e26387 perf: refresh asset type tree 2025-04-16 11:44:07 +08:00
feng 314da330c0 perf: Asset account filter 2025-04-16 11:36:58 +08:00
halo f1c98fda34 perf: client version 2025-04-16 10:39:10 +08:00
ibuler 1fdd1036d3 perf: directory service db 2025-04-15 20:24:10 +08:00
feng e286997090 perf: koko translate 2025-04-15 17:26:06 +08:00
wangruidong ce3daf5496 fix: update translation strings and improve error handling in inventory and job modules 2025-04-15 16:49:35 +08:00
feng 631570b819 perf: Asset filter 2025-04-15 16:45:50 +08:00
feng 9b1bff0847 perf: client version 2025-04-15 12:28:59 +08:00
feng ee8a2afe16 fix: ES no data found 2025-04-15 12:07:56 +08:00
CaptainB 1a01c0537c chore: Add Dependabot configuration for pip dependencies 2025-04-15 11:47:59 +08:00
jiangweidong 64393fe695 fix: Error in using set method 2025-04-15 11:47:01 +08:00
jiangweidong 11ef4fab4e perf: Es subsequent optimization 2025-04-15 11:47:01 +08:00
jiangweidong 9f8256f885 fix: Solve the problem that log details cannot be viewed in non-default organizations 2025-04-15 11:47:01 +08:00
fit2bot 5390fbacec
perf: some swagger api (#15203)
* perf: some swagger api

* perf: update deps

* perf: Update Dockerfile with new base image tag

---------

Co-authored-by: ibuler <ibuler@qq.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-04-15 11:43:36 +08:00
wangruidong 8b9fe3c72b perf: add default logo handling in IntegrationApplicationSerializer 2025-04-15 11:08:15 +08:00
wangruidong 20070e0647 fix: improve crontab validation logic 2025-04-15 11:07:23 +08:00
ibuler 47b72cb35e perf: add leak password db config 2025-04-14 17:27:27 +08:00
feng 2ca0e9a5a2 perf: automation .account -> .all_accounts 2025-04-14 14:18:56 +08:00
feng 3b2ac101c8 perf: windows ad asset info 2025-04-14 10:14:38 +08:00
feng 6795f036dd perf: ad asset automation gather_facts_enabled true 2025-04-11 17:53:43 +08:00
feng aaa1f48258 perf: koko translate 2025-04-11 17:45:58 +08:00
feng 53c5bab203 perf: user login acl remove warning notify_and_warn action 2025-04-10 15:56:31 +08:00
feng 1254d28463 perf: windows ad gather account 2025-04-10 15:33:42 +08:00
wangruidong d6b1a577fc fix: resolve ForeignKeyViolation in AccountRisk 2025-04-09 19:30:05 +08:00
wangruidong 5ab85d3561 perf: File directory adjustment 2025-04-09 19:29:52 +08:00
wangruidong 467f4c5d4f perf: Translate 2025-04-09 19:29:52 +08:00
wangruidong f2404319af fix: account_prefer 2025-04-09 19:29:52 +08:00
wangruidong bbeadf7dbe perf: optimize adhoc asset selection experience 2025-04-09 19:29:52 +08:00
feng 941bd9b3f4 perf: Translate 2025-04-09 19:22:32 +08:00
feng 37a307a9d0 perf: Windows AD 2025-04-09 18:22:00 +08:00
ibuler 528f9045d0 perf: update connection token 2025-04-09 11:11:39 +08:00
ibuler a317549a01 perf: migrations merge 2025-04-08 19:21:37 +08:00
ibuler 0f5681de7d chore: remove workflow 2025-04-08 19:21:37 +08:00
ibuler a7c514f8d8 perf: rename some workd 2025-04-08 19:21:37 +08:00
ibuler 75ea0079a2 perf: update ad domain 2025-04-08 19:21:37 +08:00
ibuler 4cc1687bf8 perf: update ad 2025-04-08 19:21:37 +08:00
ibuler 76e57b9a3e perf: update ad 2025-04-08 19:21:37 +08:00
ibuler ba3bce1e2e perf: perm account valid 2025-04-08 19:21:37 +08:00
ibuler 45f0343cfa perf: update ds 2025-04-08 19:21:37 +08:00
ibuler acaa4cf2d5 perf: rename ad to ds 2025-04-08 19:21:37 +08:00
ibuler 3f452daee8 perf: ad as asset 2025-04-08 19:21:37 +08:00
feng 5e25361ee8 perf: Operate default log 2025-04-08 18:37:25 +08:00
jiangweidong 7b7604e14d Added cloud sync global released asset tab (v4.9) 2025-04-08 18:31:53 +08:00
Eric f9037878c3 perf: add remoteapp bitmapcache settings 2025-04-08 17:36:48 +08:00
fit2bot 29ddfcac17
fix: Optimize UserConfirmDialog to send code via email (#15164)
* fix: Optimize UserConfirmDialog to send code via email

* fix: Optimize verification failure without error reporting

---------

Co-authored-by: halo <wuyihuangw@gmail.com>
Co-authored-by: Bryan <jiangjie.bai@fit2cloud.com>
2025-04-08 15:50:15 +08:00
wangruidong 519ec65ad4 perf: LDAP strict sync 2025-04-08 15:43:15 +08:00
jiangweidong 1f60e328b6 perf: Export resources to add operation logs 2025-04-08 15:37:29 +08:00
Bai e8e0ea920b perf: change jumpserver.org to jumpserver.com 2025-04-08 14:23:28 +08:00
Aaron3S 4fd8efd043 feat: remove oracle dyn port 2025-04-08 13:50:30 +08:00
wangruidong 623c800d31 fix: failure when deleting remote account in SQL Server 2025-04-08 13:48:48 +08:00
wangruidong d2c6e3c7a6 fix: Job audit: Search job list, filter failures based on command 2025-04-08 13:41:59 +08:00
github-actions[bot] dc5883576d Auto-translate README 2025-04-08 13:34:21 +08:00
Bai 0a9c9fb227 perf: change readme 2025-04-08 13:26:48 +08:00
Bai 15a1a58eca perf: change support email 2025-04-08 13:20:22 +08:00
halo 782401ef86 fix: Implement function _check_code 2025-04-07 16:20:43 +08:00
maninhill 8abcd201bc chore: Update README.md 2025-04-03 15:11:38 +08:00
Bryan cdbc10ac72 Update README.md 2025-03-31 17:37:01 +08:00
Bryan ceeef890e6 Update README.md 2025-03-31 17:37:01 +08:00
Bryan dc8a172884 Update README.md 2025-03-28 17:53:22 +08:00
Bryan 62115e43bb Update README.md 2025-03-28 17:53:22 +08:00
Bryan 5eced85e69 Update README.md 2025-03-28 17:53:22 +08:00
Bryan ec99b17b76 Update README.md 2025-03-28 17:53:22 +08:00
Bryan 84569720c3 Update README.md 2025-03-28 17:53:22 +08:00
feng 65984d38f1 perf: Account filter 2025-03-28 16:34:53 +08:00
feng f6913ac63c perf: Priacy mode 2025-03-27 18:34:11 +08:00
Halo 514b2cdfc5
feat: Email as a method for multi-factor authentication (#15134)
* feat: Email as a method for multi-factor authentication

* perf: Optimize the MFA email sending logic

* perf: Optimize some parameters

* perf: Translate
2025-03-27 17:26:38 +08:00
ibuler b55000663e perf: 提升服务注册安全性 2025-03-27 16:25:28 +08:00
ibuler 9ed822bb3e perf: 优化获取 labels 2025-03-27 16:23:14 +08:00
feng ea599d7695 perf: Perm the template push account 2025-03-27 14:13:29 +08:00
feng 01c5d68b35 perf: change secret change_secret_result 2025-03-27 14:08:19 +08:00
feng 2e2c331941 perf: translate 2025-03-25 18:03:10 +08:00
feng 266ea9b858 perf: Change secret 2025-03-25 16:05:47 +08:00
feng 5f2e838342 perf: koko sftp translate 2025-03-25 14:33:50 +08:00
ZhaoJiSen 544ad5532b
Merge pull request #15117 from jumpserver/pr@dev@koko_translate
perf: koko translate
2025-03-25 11:02:08 +08:00
feng d22d715ee7 perf: koko translate 2025-03-25 10:59:45 +08:00
halo dd2366532c perf: Use a domain account to avoid automatically creating a local account 2025-03-25 10:22:16 +08:00
ibuler 9667a3d340 perf: add crontab check min 60m 2025-03-25 09:56:37 +08:00
feng c8e6e5d38c perf: Login language 2025-03-24 18:55:40 +08:00
feng 9d1047fae2 perf: Translate 2025-03-24 16:51:49 +08:00
feng 28f97d746d perf: Translate 2025-03-24 15:39:37 +08:00
ibuler be72344c63 perf: update tk create 2025-03-24 10:54:17 +08:00
ibuler d3176b68a8 perf: 优化 admin token 判断 2025-03-24 10:06:22 +08:00
ibuler 5411f65546 perf: update get permed account 2025-03-24 09:51:46 +08:00
ibuler e3ba468004 fix: 修复 token 直连的问题 2025-03-24 09:51:46 +08:00
feng a03a11efa4 perf: Translate 2025-03-21 15:49:42 +08:00
feng d344495417 perf: Translate 2025-03-21 14:24:37 +08:00
github-actions[bot] 9412bd0331 Auto-translate README 2025-03-21 13:29:01 +08:00
Bai 8d73ddb1cd perf: update readme languages 2025-03-21 13:17:56 +08:00
Bai 7fe56a5e1a perf: README 2025-03-21 10:35:27 +08:00
Bryan ad5460dab8
Merge pull request #15086 from jumpserver/dev
v4.8.0
2025-03-20 18:44:44 +08:00
wangruidong db259d4e8b fix: Failed to delete account 2025-03-20 17:01:43 +08:00
feng afc31ee5ce perf: translate 2025-03-20 15:33:53 +08:00
feng 69cc47e0cb perf: account backup 2025-03-20 13:25:40 +08:00
wangruidong 2455afc2d2 fix: Use ConfirmOrIgnore for confirmed status in account updates 2025-03-20 11:14:16 +08:00
Chenyang Shen 33cb793c19
Merge pull request #15078 from jumpserver/pr@dev@fix_face_vector_diabled
fix: fix face live can not enable
2025-03-19 20:47:39 +08:00
Aaron3S 5522ba0241 fix: fix face live can not enable 2025-03-19 20:45:35 +08:00
wangruidong 0fed338277 fix: Change secret failed, no module named libs 2025-03-19 20:23:02 +08:00
feng 8f78919b3e perf: Change secret filter days 2025-03-19 18:56:23 +08:00
wangruidong f6fc9b1f5c fix: Update account status to confirmed 2025-03-19 18:30:09 +08:00
jiangweidong 365dbf6e14 fix: CTYun cannot sync 2025-03-19 17:59:43 +08:00
wangruidong e5a5d5f727 fix: Account filter error 2025-03-19 16:34:42 +08:00
wangruidong e0d6b843ee fix: Add account_deleted_accounts to RiskSummary 2025-03-19 15:25:47 +08:00
wangruidong 2a31a7d444 fix: Validate input data for account status updates 2025-03-19 14:45:17 +08:00
wangruidong e68d5564c6 fix: Ansible could not initialize the preferred locale 2025-03-19 11:21:15 +08:00
feng 4fdb049c9d perf: translate 2025-03-19 11:07:42 +08:00
wangruidong e5f66c4be2 fix: password_expired account, not listed as risk account 2025-03-18 19:19:51 +08:00
wangruidong 325edfe704 fix: long_time_no_login account, not listed as risk account 2025-03-18 18:59:23 +08:00
feng626 3a93aeb155
Merge pull request #15064 from jumpserver/pr@dev@license
perf: License
2025-03-18 18:56:50 +08:00
feng626 28d6f2f9ef
Merge branch 'dev' into pr@dev@license 2025-03-18 18:56:41 +08:00
feng 2bfcebd064 perf: License 2025-03-18 18:54:12 +08:00
老广 6f2cb9b3c6
Merge pull request #15063 from jumpserver/pr@dev@add_delete_account_action
perf: update some 18n
2025-03-18 17:52:05 +08:00
fit2bot cdebfd8121
perf: add delete account action (#15059) 2025-03-18 16:57:27 +08:00
ibuler 57d05e6ff0 perf: update some 18n 2025-03-18 16:56:46 +08:00
ibuler 49378d1f13 perf: update ansible env set 2025-03-18 16:32:59 +08:00
wangruidong e802e145af fix: Create ssh_key failed 2025-03-18 16:23:01 +08:00
ibuler 2faad88b78 perf: remove ga also 2025-03-18 16:07:49 +08:00
ibuler 33a47139b3 perf: ansible env to jms 2025-03-18 16:02:33 +08:00
wangruidong 50faa3242a perf: Translate 2025-03-18 14:51:04 +08:00
ibuler d89164db63 perf: add delete account action 2025-03-18 14:38:54 +08:00
ibuler f72fc19ba6 perf: change Command 2025-03-18 13:48:14 +08:00
feng 7bd03c7863 perf: change secret filter 2025-03-18 13:29:36 +08:00
wangruidong ed95a89a77 fix: Create ssh_key set is_active error 2025-03-18 11:29:40 +08:00
Chenyang Shen 428a4470c9
Merge pull request #15054 from jumpserver/pr@dev@feat_add_translate
feat: add translate
2025-03-18 10:44:00 +08:00
Aaron3S b206e751da feat: add translate 2025-03-18 10:40:06 +08:00
ibuler 6913518046 perf: update automation report template 2025-03-17 19:21:52 +08:00
wangruidong f5a2f5e538 fix: Check authorized_keys change failed 2025-03-17 19:18:34 +08:00
feng f4fa153ffa perf: push account secret 2025-03-17 18:45:25 +08:00
feng626 c70d7f709f
Merge pull request #15047 from jumpserver/pr@dev@excution
perf: Automation execution
2025-03-17 17:28:37 +08:00
feng626 ec95144907
Merge branch 'dev' into pr@dev@excution 2025-03-17 17:28:03 +08:00
feng 424ef4d9a5 perf: Automation execution 2025-03-17 17:26:09 +08:00
wangruidong 40bbc4a02c perf: Translate ExecuteAfterSaving 2025-03-17 16:32:39 +08:00
wangruidong a784ca29c3 fix: Update counter naming for group and sudo changes in RiskSummary 2025-03-17 15:58:37 +08:00
fit2bot b7820c6a5b
perf: update automation report 2025-03-17 10:31:49 +08:00
feng 7bac1b42e4 perf: risk add account 2025-03-14 17:41:13 +08:00
feng 0a6757946a perf: translate 2025-03-14 17:02:39 +08:00
wangruidong e4d169cabe perf: migrations type length 2025-03-14 15:09:06 +08:00
wangruidong c80ca5236d perf: migrations bulk_size 2025-03-14 14:57:16 +08:00
wangruidong f513eb62a6 perf: migrations automationexecution type 2025-03-14 14:46:20 +08:00
wangruidong 94e8c62953 fix: Allow empty files in FileSerializer 2025-03-13 18:54:20 +08:00
feng bd783e6a8d perf: asset perm expire 2025-03-13 18:25:28 +08:00
wangruidong 35bc3a0e2b fix: Account risk search failed 2025-03-13 18:21:51 +08:00
ibuler 996bee3afd perf: update gathered account sync 2025-03-13 18:03:16 +08:00
feng 7c4931b6af perf: execution type 2025-03-13 17:54:02 +08:00
wangruidong 9992fb35be perf: Translate IpGroup 2025-03-13 17:10:09 +08:00
wangruidong cc63c956cb fix: Delete gather account failed 2025-03-13 16:25:27 +08:00
feng 15919085bc perf: change secret push record list 2025-03-13 14:58:11 +08:00
wangruidong 9e4b82bf45 perf: Translate risk handle 2025-03-13 10:00:31 +08:00
wangruidong 28f85a0186 perf: BaseManager email subject translate 2025-03-12 19:05:23 +08:00
feng 30e64ecfc1 perf: change secret 2025-03-12 18:57:03 +08:00
feng 042c3d1ba8 perf: gather account node_id filter 2025-03-12 18:05:42 +08:00
feng 94a8122eac perf: report 2025-03-12 17:57:15 +08:00
feng 88450d796f perf: translate 2025-03-12 16:45:19 +08:00
wangruidong 3d28e255c0 fix: Account risk page change secret failed 2025-03-12 16:01:42 +08:00
wangruidong 153be1508f perf: Remove account_deleted, password_error, no_admin_account others risk 2025-03-12 15:40:54 +08:00
ibuler 6e83420e67 perf: update i18n 2025-03-12 15:19:34 +08:00
wangruidong e03d983020 fix: Gather account new-found risk failed 2025-03-12 14:54:15 +08:00
feng 0afc1e6f5b perf: translate 2025-03-12 11:02:40 +08:00
wangruidong a9ea801862 fix: Update username and address_last_login field length in account models 2025-03-12 10:36:35 +08:00
Bai 23f9b79142 feat: support Spanish and Russian 2025-03-12 10:24:34 +08:00
ibuler 4db15d9af7 perf: update action choice field default 2025-03-12 10:23:01 +08:00
ZhaoJiSen bc9782bd55
Merge pull request #15001 from jumpserver/pr@dev@account_risk_filter
perf: account filter node
2025-03-11 19:20:14 +08:00
feng 635e9f5079 perf: account filter node 2025-03-11 19:19:14 +08:00
Eric_Lee 71259886fe
Merge pull request #14834 from jumpserver/pr@dev@perf_replay_file
perf: use a custom local path to save session replay file
2025-03-11 19:12:42 +08:00
feng626 a26cc7ce1f
Merge pull request #15000 from jumpserver/pr@dev@connectiontoken
perf: connection token
2025-03-11 18:34:35 +08:00
feng a2aa5e9bf9 perf: connection token 2025-03-11 18:32:38 +08:00
ZhaoJiSen 82de373f8e
Merge pull request #14998 from jumpserver/pr@dev@chage_secret
perf: change secret drop bulk record
2025-03-11 17:39:45 +08:00
feng 59e7778e4a perf: change secret drop bulk record 2025-03-11 17:37:04 +08:00
feng626 60eaec68c6
Merge pull request #14996 from jumpserver/pr@dev@fix_long_time_no_login_risk
fix: long_time_no_login account, not listed as risk account
2025-03-11 16:40:31 +08:00
wangruidong 43973122bf fix: Remove the empty contents of the log 2025-03-11 16:39:08 +08:00
wangruidong 8668955d4a fix: long_time_no_login account, not listed as risk account 2025-03-11 16:06:47 +08:00
ZhaoJiSen 5571fb6f42
Merge pull request #14993 from jumpserver/pr@dev@report
perf: report css
2025-03-11 15:10:55 +08:00
feng 62b9b6883e perf: report css 2025-03-11 15:04:40 +08:00
老广 7af1c6a2bb
Merge pull request #14991 from jumpserver/pam
fix: OIDC PKCE S256
2025-03-11 11:02:09 +08:00
Bai 3e96c2fe79 fix: OIDC PKCE S256 2025-03-11 09:14:23 +08:00
feng626 3a1d3c1f5c
Merge pull request #14990 from jumpserver/pam
Pam
2025-03-10 19:14:00 +08:00
zhaojisen 9466c7105c Perf: Perf All Report 2025-03-10 17:39:36 +08:00
feng a3467bdabc perf: change secret 2025-03-10 17:34:20 +08:00
feng 4c547215aa perf: account integrationapplication filter 2025-03-10 16:37:53 +08:00
ibuler 2580e7a712 perf: update accounts migrations 2025-03-10 16:20:42 +08:00
ibuler 038d93e318 Merge branch 'pam' of github.com:jumpserver/jumpserver into pam 2025-03-10 15:25:46 +08:00
ibuler f46cc0f040 perf: update user serializer 2025-03-10 15:24:41 +08:00
feng 423d6db2ac perf: change record dashboard 2025-03-10 14:48:18 +08:00
wangruidong 243083e876 perf: Translate application detail 2025-03-10 14:26:21 +08:00
wangruidong c84bc52c70 perf: Translate check account 2025-03-10 10:43:12 +08:00
wangruidong 090ad0ba83 fix: Add drf filter set to SecretRecordMixin 2025-03-07 18:17:13 +08:00
feng 033750f108 perf: execution automation ObjectRelatedField 2025-03-07 17:05:12 +08:00
feng 405344de74 perf: Automation 2025-03-07 16:54:20 +08:00
fit2bot 763e67bd1d
perf: Integrate authentication to update user attribute logic (#14979) 2025-03-07 16:25:28 +08:00
wangruidong e8c581b08a fix: Integrations Application: Failed to filter accounts by selecting multiple attributes when creating or editing 2025-03-07 14:45:49 +08:00
feng 47029be3da perf: Change secret 2025-03-06 19:15:16 +08:00
wangruidong bc70c480f7 fix: Integration Application: No Java example in the help docs 2025-03-06 17:45:48 +08:00
jiangweidong d2d9d3d841 fix: Slove the problem that the third-party auth cannot update user name 2025-03-06 17:02:56 +08:00
ibuler 56d0a6d0b0 Merge branch 'pam' of github.com:jumpserver/jumpserver into pam 2025-03-06 10:23:26 +08:00
ibuler 060e8ace70 perf: update i18n 2025-03-06 10:22:32 +08:00
feng 821622638a perf: translate 2025-03-05 17:30:26 +08:00
老广 51c67f0e9d
Merge pull request #14968 from jumpserver/pr@dev@pam
perf: update i18n
2025-03-04 19:19:38 +08:00
ibuler 70c8db839e perf: update i18n 2025-03-04 19:13:20 +08:00
ibuler c9208d2cf7 Merge branch 'pam' of github.com:jumpserver/jumpserver into pam 2025-03-04 15:46:52 +08:00
ibuler 58177fdfb0 perf: update some i18n 2025-03-04 15:46:45 +08:00
wangruidong 76dd2f8153 fix: Creating an integration application with the same name results in a server error. 2025-03-03 18:28:09 +08:00
wangruidong edd998da20 fix: Premailer failed to parse the report HTML. 2025-03-03 16:46:43 +08:00
feng 8b2276ce08 perf: koko sftp superuser perm 2025-03-03 16:17:16 +08:00
wangruidong f42f46ffe4 fix: User list: some quick filters are ineffective. 2025-03-03 14:56:32 +08:00
ibuler b2f8f9d248 perf: update pam i18n 2025-03-03 14:46:54 +08:00
ibuler 8105681304 perf: update i18n 2025-03-03 14:44:52 +08:00
feng b4d3f6099a perf: translate 2025-03-03 10:52:21 +08:00
feng 9b48da11dc perf: translate 2025-02-28 18:55:35 +08:00
feng 904154a62b perf: translate 2025-02-28 18:50:18 +08:00
feng 7181dad5ad perf: Translate 2025-02-28 18:40:47 +08:00
jiangweidong 2a250d13d8 fix: Solve the problem that some messages cannot be sent from unauthenticated email 2025-02-28 17:44:36 +08:00
feng caa1e2e1ac perf: Translate 2025-02-28 17:05:36 +08:00
wangruidong 5b044299b9 fix: Back account translate 2025-02-28 14:55:42 +08:00
wangruidong d48a12e266 perf: Translate 2025-02-28 11:04:29 +08:00
feng 35ec9dc2f4 perf: Translate 2025-02-27 18:50:06 +08:00
老广 33f3281a1f
Merge pull request #14943 from jumpserver/pr@dev@update_pam
merge: with dev
2025-02-27 17:14:59 +08:00
ibuler 93810fb0db merge: with dev 2025-02-27 17:05:35 +08:00
ibuler 8fc2b86189 Merge branch 'pam' of github.com:jumpserver/jumpserver into pam 2025-02-27 17:00:00 +08:00
ibuler 6217733aba perf: update some i18n 2025-02-27 16:59:52 +08:00
feng 4b4d7b6787 perf: During MFA authentication, if the current code has been used and successfully authenticated, it cannot be used again for authentication 2025-02-27 15:35:56 +08:00
ibuler acbc3e1e44 Merge branch 'pam' of github.com:jumpserver/jumpserver into pam 2025-02-27 13:27:43 +08:00
ibuler 110b3a334d perf: update i18n 2025-02-27 13:27:35 +08:00
wangruidong a498b22e80 perf: Update account change secret status and date on successful secret change 2025-02-26 16:20:39 +08:00
wangruidong 385bf47b11 perf: Add last login date update for account on session save 2025-02-26 16:20:39 +08:00
ibuler 16400082e7 perf: update i18n 2025-02-26 15:34:04 +08:00
wangruidong cbc009cb3f fix: Return Response object for successful account risk handling 2025-02-26 10:31:33 +08:00
feng 919cdeae20 perf: report to iframe 2025-02-25 19:14:13 +08:00
feng 456b96a369 perf: Translate 2025-02-25 14:49:22 +08:00
wangruidong ff9ad2680f perf: Update confirmation backend definitions to use ConfirmType 2025-02-25 10:53:19 +08:00
Bai 96a0cbc35d fix: import error 2025-02-25 10:53:19 +08:00
feng 08963ebb40 perf: Translate 2025-02-24 19:26:34 +08:00
wangruidong 908e6cb81a fix: Migrate account backup automation and execution data 2025-02-24 18:50:06 +08:00
feng c206f5d09c perf: user filter error 2025-02-24 15:33:23 +08:00
github-actions[bot] f0c7a7508b perf: Update Dockerfile with new base image tag 2025-02-24 15:09:38 +08:00
Bai d386189c77 fix: pyproject.toml 2025-02-24 15:09:38 +08:00
ibuler f0fa381b9f perf: update action run on 2025-02-24 14:51:53 +08:00
Bai 8b2af5ee0a fix: make messages errors 2025-02-24 14:28:31 +08:00
ibuler 0541c0a9d4 perf: squash migrations 2025-02-24 14:08:47 +08:00
feng e4c7eb8035 perf: Account filter 2025-02-24 11:50:48 +08:00
Bai e33aeaa338 fix: migrations files modify 2025-02-24 11:26:20 +08:00
feng 1282fffff7 perf: Change secret 2025-02-21 17:46:56 +08:00
fit2bot 3f4141ca0b
merge: with pam (#14911)
* perf: change i18n

* perf: pam

* perf: change translate

* perf: add check account

* perf: add date field

* perf: add account filter

* perf: remove some js

* perf: add account status action

* perf: update pam

* perf: 修改 discover account

* perf: update filter

* perf: update gathered account

* perf: 修改账号同步

* perf: squash migrations

* perf: update pam

* perf: change i18n

* perf: update account risk

* perf: 更新风险发现

* perf: remove css

* perf: Admin connection token

* perf: Add a switch to check connectivity after changing the password, and add a custom ssh command for push tasks

* perf: Modify account migration files

* perf: update pam

* perf: remove to check account dir

* perf: Admin connection token

* perf: update check account

* perf: 优化发送结果

* perf: update pam

* perf: update bulk update create

* perf: prepaire using thread timer for bulk_create_decorator

* perf: update bulk create decorator

* perf: 优化 playbook manager

* perf: 优化收集账号的报表

* perf: Update poetry

* perf: Update Dockerfile with new base image tag

* fix: Account migrate 0012 file

* perf: 修改备份

* perf: update pam

* fix: Expand resource_type filter to include raw type

* feat: PAM Service (#14552)

* feat: PAM Service

* perf: import package name

---------

Co-authored-by: jiangweidong <1053570670@qq.com>

* perf: Change secret dashboard (#14551)

Co-authored-by: feng <1304903146@qq.com>

* perf: update migrations

* perf: 修改支持 pam

* perf: Change secret record table dashboard

* perf: update status

* fix: Automation send report

* perf: Change secret report

* feat: windows accounts gather

* perf: update change status

* perf: Account backup

* perf: Account backup report

* perf: Account migrate

* perf: update service to application

* perf: update migrations

* perf: update logo

* feat: oracle accounts gather (#14571)

* feat: oracle accounts gather

* feat: sqlserver accounts gather

* feat: postgresql accounts gather

* feat: mysql accounts gather

---------

Co-authored-by: wangruidong <940853815@qq.com>

* feat: mongodb accounts gather

* perf: Change secret

* perf: Migrate

* perf: Merge conflicting migration files

* perf: Change secret

* perf: Automation filter org

* perf: Account push

* perf: Random secret string

* perf: Enhance SQL query and update risk handling in accounts

* perf: Ticket filter assignee_id

* perf: 修改 account remote

* perf: 修改一些 adhoc 任务

* perf: Change secret

* perf: Remove push account extra api

* perf: update status

* perf: The entire organization can view activity log

* fix: risk field check

* perf: add account details api

* perf: add demo mode

* perf: Delete gather_account

* perf: Perfect solution to account version problem

* perf: Update status action to handle multiple accounts

* perf: Add GatherAccountDetailField and update serializers

* perf: Display account history in combination with password change records

* perf: Lina translate

* fix: Update mysql_filter to handle nested user info

* perf: Admin connection token validate_permission account

* perf: copy move account

* perf: account filter risk

* perf: account risk filter

* perf: Copy move account failed message

* fix: gather account sync account to asset

* perf: Pam dashboard

* perf: Account dashboard total accounts

* perf: Pam dashboard

* perf: Change secret filter account secret_reset

* perf: 修改 risk filter

* perf: pam translate

* feat: Check for leaked duplicate passwords. (#14711)

* feat: Check for leaked duplicate passwords.

* perf: Use SQLite instead of txt as leak password database

---------

Co-authored-by: jiangweidong <1053570670@qq.com>
Co-authored-by: 老广 <ibuler@qq.com>

* perf: merge with remote

* perf: Add risk change_password_add handle

* perf: Pam dashboard

* perf: check account manager import

* perf: 重构扫描

* perf: 修改 db

* perf: Gather account manager

* perf: update change db lib

* perf: dashboard

* perf: Account gather

* perf: 修改 asset get queryset

* perf: automation report

* perf: Pam account

* perf: Pam dashboard api

* perf: risk add account

* perf: 修改 risk check

* perf: Risk account

* perf: update risk add reopen action

* perf: add pylintrc

* Revert "perf: automation report"

This reverts commit 22aee54207.

* perf: check account engine

* perf: Perf: Optimism Gather Report Style

* Perf: Remove unuser actions

* Perf: Perf push account

* perf: perf gather account

* perf: Automation report

* perf: Push account recorder

* perf: Push account record

* perf: Pam dashboard

* perf: perf

* perf: update intergration

* perf: integrations application detail add account tab page

* feat: Custom change password supports configuration of interactive items

* perf: Go and Python demo code

* perf: Custom secret change

* perf: add user filter

* perf: translate

* perf: Add demo code docs

* perf: update some i18n

* perf: update some i18n

* perf: Add Java, Node, Go, and cURL demo code

* perf: Translate

* perf: Change secret translate

* perf: Translate

* perf: update some i18n

* perf: translate

* perf: Ansible playbook

* perf: update some choice

* perf: update some choice

* perf: update account serializer remote unused code

* perf: conflict

* perf: update import

---------

Co-authored-by: ibuler <ibuler@qq.com>
Co-authored-by: feng <1304903146@qq.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: wangruidong <940853815@qq.com>
Co-authored-by: jiangweidong <1053570670@qq.com>
Co-authored-by: feng626 <57284900+feng626@users.noreply.github.com>
Co-authored-by: zhaojisen <1301338853@qq.com>
2025-02-21 16:39:57 +08:00
wangruidong d516349a68 perf: Translate 2025-02-20 18:24:27 +08:00
Bryan 4d37dca0de
Merge pull request #14901 from jumpserver/dev
v4.7.0
2025-02-20 10:21:16 +08:00
Chenyang Shen 8730fa8dee
Merge pull request #14900 from jumpserver/pr@dev@translate
perf: translate
2025-02-19 19:26:09 +08:00
Aaron3S 9a5a775652 feat: add luna i18n 2025-02-19 19:17:21 +08:00
feng 8304ae9070 perf: translate 2025-02-19 16:27:10 +08:00
wangruidong 9533861e24 fix: VariableSerializer allow null in default_value 2025-02-18 15:26:11 +08:00
Aaron3S abbfbcde83 feat: add i18n 2025-02-18 15:10:13 +08:00
wangruidong 046a9d41bf fix: Removing labels from asset details will cause an error. 2025-02-17 18:21:28 +08:00
fit2bot 363bb20da7
feat: Chen i18n (#14851)
Co-authored-by: jiangweidong <1053570670@qq.com>
2025-02-17 11:25:54 +08:00
wangruidong 2b7c8b9c07 fix: Upgrading v3 to v4 generates two ticket flow 2025-02-14 16:10:20 +08:00
Aaron3S db040bbd06 feat: add translate 2025-02-14 11:30:56 +08:00
feng a761ec9aa1 perf: Translate 2025-02-13 16:55:09 +08:00
feng c0ffe45ce9 perf: deepseek 2025-02-13 16:40:29 +08:00
wangruidong 404d58a9c9 fix: When the organization does not exist, close ticket with an error. 2025-02-13 16:31:47 +08:00
feng f64eab7a15 perf: Translate 2025-02-13 11:48:59 +08:00
feng 46f94fd138 perf: Chat ai help text 2025-02-13 11:30:07 +08:00
wangruidong 2f1c0090b7 fix: markdown render issue 2025-02-12 15:48:05 +08:00
feng b0d6a09276 perf: translate 2025-02-10 19:15:39 +08:00
feng d8db76cc7b perf: DeepSeek 2025-02-08 15:40:24 +08:00
wangruidong b35a55ed54 fix: Cannot set original org when exception occurs 2025-02-08 11:13:14 +08:00
Bai dc5ecfcc4b fix: setting field encrypt issue 2025-02-06 17:14:10 +08:00
Eric 594d5b8128 perf: use a custom local path to save session replay file 2025-01-23 15:55:43 +08:00
Bryan 2ca4002624
Merge pull request #14813 from jumpserver/dev
v4.6.0
2025-01-15 14:38:17 +08:00
wangruidong 543dde57ab perf: modify average_time_cost calculation in job model 2025-01-14 18:28:31 +08:00
w940853815 c088437fe5 Revert "perf: Optimize average_time_cost calculation in job model"
This reverts commit eafb5ecfb3.
2025-01-14 18:18:44 +08:00
feng e721ec147c perf: luna translate 2025-01-14 17:30:00 +08:00
wangruidong 5d18d6dee0 fix: Add with_expired param to permission utils 2025-01-14 16:41:39 +08:00
feng ecfd338428 perf: Lina translate 2025-01-14 15:16:17 +08:00
Eric 4b28b079dc perf: fix rdp file resolution value 2025-01-14 13:57:11 +08:00
wangruidong c1c3236a30 fix: Add redirect_url check in base view 2025-01-14 11:54:17 +08:00
feng 4b19750581 perf: Client version 2025-01-14 10:32:07 +08:00
wangruidong eafb5ecfb3 perf: Optimize average_time_cost calculation in job model 2025-01-13 17:12:11 +08:00
Bai 583486e26e fix: radius user auth skip backend 2025-01-13 15:49:23 +08:00
Bai 8198620a2e feat: add gitignore 2025-01-09 10:50:57 +08:00
wangruidong c0b301d52b fix: ldap ha periodic task did not execute as expected 2025-01-08 18:34:53 +08:00
feng 7791d6222a perf: translate 2025-01-08 14:33:04 +08:00
Bai b740d9d42f fix: circle imported for perms-api 2025-01-08 10:35:13 +08:00
wangruidong 48d0187604 fix: circular import 2025-01-07 14:01:38 +08:00
wangruidong 6217018427 perf: Translate var_name help_text 2025-01-06 11:36:11 +08:00
jiangweidong 923f40e523 feat: VMware automatically syncs folders to node-translation 2025-01-03 18:50:12 +08:00
Bai 1f1fe2084b fix: koko press r dont refresh user perm-nodes 2025-01-03 17:13:32 +08:00
刘瑞斌 b8b1a6ac9c chore: update readme 2024-12-30 16:04:32 +08:00
wangruidong 35f88722af fix: Add type check for secure command execution 2024-12-24 15:58:56 +08:00
Bai 7e6d2749ae fix: core download page error 2024-12-20 16:35:24 +08:00
Bai be57b101ff fix: set default ldap user dn cache time (0) 2024-12-20 16:35:03 +08:00
Bai 41c8cb6307 fix: api prometheus count 2024-12-20 11:14:55 +08:00
Bai 3a7ae01ede fix: add settings for license version and facelive 2024-12-19 17:37:39 +08:00
Bryan 053d640e4c
Merge pull request #14699 from jumpserver/dev
v4.5.0
2024-12-19 16:04:45 +08:00
老广 d17ca4f6a7 Revert "perf: update const import"
This reverts commit 2956f2e4b7.
2024-12-19 16:03:29 +08:00
Bryan f3acc28ded
Merge pull request #14697 from jumpserver/dev
v4.5.0
2024-12-19 15:57:11 +08:00
Aaron3S 5a14bb13d0 feat: remove mfa check when unbind face code 2024-12-19 15:50:38 +08:00
ibuler 2956f2e4b7 perf: update const import 2024-12-19 15:49:13 +08:00
feng e983ac3cbc perf: Translate 2024-12-19 15:18:39 +08:00
ibuler fab156dc5f perf: update login success redirect 2024-12-19 14:34:49 +08:00
wangruidong f6f897317e perf: default_value field allow blank 2024-12-19 12:01:08 +08:00
Aaron3S a0441cd6ea feat: add translate 2024-12-19 11:13:13 +08:00
Chenyang Shen e9abd1e72d
Merge pull request #14688 from jumpserver/pr@dev@fix_face_openid
fix: fix openid user can't login with face verify
2024-12-19 11:08:45 +08:00
Aaron3S 9fcb4ecba0 fix: fix openid user can't login with face verify 2024-12-19 10:56:44 +08:00
feng 4b637ad86e perf: Client version 3.0.0 2024-12-18 19:33:45 +08:00
jiangweidong 829f867962 perf: The command amount does not record operation logs. 2024-12-18 19:33:02 +08:00
feng 7f965b55f4 perf: Translate 2024-12-18 18:21:43 +08:00
Chenyang Shen 0e0be618e5
Merge pull request #14684 from jumpserver/pr@dev@feat_refresh_cache_facelive
feat: refresh facelive cache
2024-12-18 18:10:39 +08:00
Aaron3S 9577af3221 feat: refresh facelive cache 2024-12-18 18:08:13 +08:00
Aaron3S a6b7cc9d1b fix: fix 401 error on face verify when use openid login 2024-12-18 18:07:42 +08:00
feng 7a9a71197a perf: Client login 2024-12-18 18:01:38 +08:00
jiangweidong 3cd68ba0a9 perf: push account without increasing version. 2024-12-18 16:51:39 +08:00
jiangweidong 02bdd0f07d perf: push account without increasing version. 2024-12-18 16:51:39 +08:00
jiangweidong 98cf6f82b7 perf: create account add activity log 2024-12-18 15:54:57 +08:00
wangruidong 27fd5d51b9 perf: Translate 2024-12-18 15:53:47 +08:00
wangruidong 095ca91e30 feat: add 'labels' to DomainSerializer fields_m2m 2024-12-18 10:57:30 +08:00
wangruidong d05514962a fix: calc platform asset count 2024-12-17 19:08:55 +08:00
Bai c4066a03fa fix: login show system org 2024-12-17 19:08:31 +08:00
Aaron3S a7d4c4ca2a feat: change face online killer name 2024-12-17 18:53:09 +08:00
Chenyang Shen 5b0f8f63a3
Merge pull request #14670 from jumpserver/pr@dev@feat_add_some_translate
feat: add some translate
2024-12-17 18:24:01 +08:00
Aaron3S c4bcae68bf feat: add some translate 2024-12-17 18:03:13 +08:00
Aaron3S 29ca50f97e feat: add face online acl check for exchange token 2024-12-17 17:18:37 +08:00
feng 49aaf8d53e perf: Remove the login status after the client logs in 2024-12-17 15:32:39 +08:00
feng 931e15173b perf: perm asset api date_updated order 2024-12-17 14:43:19 +08:00
feng 4018a59b2e perf: Account backup filter org 2024-12-17 11:23:32 +08:00
Chenyang Shen 88905bd28d
Merge pull request #14664 from jumpserver/pr@dev@feat_add_face_verify_on_exchange_token
feat: add face verify on exchange connect token
2024-12-16 19:00:56 +08:00
Aaron3S abad98a190 feat: add face verify on exchange connect token 2024-12-16 18:54:32 +08:00
Chenyang Shen 7419139b29
Merge pull request #14663 from jumpserver/pr@dev@feat_exclude_some_action_for_acl
feat: exclude face action for login acl and command acl
2024-12-16 18:22:09 +08:00
Aaron3S a1fd3b1ecb feat: exclude face action for login acl and command acl 2024-12-16 18:17:00 +08:00
wangruidong 8a8a7f9947 fix: filter custom assets in secret type check 2024-12-16 17:37:05 +08:00
Chenyang Shen f9e6fc98fb
Merge pull request #14654 from jumpserver/pr@dev@feat_update_migrations
feat: update migrations
2024-12-13 12:42:17 +08:00
Aaron3S 0dd015bcba feat: update migrations 2024-12-13 12:40:06 +08:00
Aaron3S d1ea31c9a4 feat: face online 2024-12-12 18:31:21 +08:00
feng e2bf56e624 perf: translate 2024-12-12 15:49:37 +08:00
feng 26040a5560 perf: pt_br translate 2024-12-12 14:40:59 +08:00
Bai 54726f0a2d perf: Passkey Model field token max_length 1024 2024-12-12 14:29:23 +08:00
Eric 7fd88b95f9 perf: update lion i18n 2024-12-12 11:21:19 +08:00
feng 4f271d6405 perf: RBAC remove assets gpt custom 2024-12-11 19:05:33 +08:00
feng fe17a8c3a0 perf: The entire organization can view activity log 2024-12-11 18:45:41 +08:00
fit2bot ee5e97e860
perf: add rdp connection speed option (#14641)
* perf: add rdp connection speed option

* perf: remove print code

---------

Co-authored-by: Eric <xplzv@126.com>
2024-12-11 18:42:05 +08:00
fit2bot dddfc66efd
perf: add encrypted configuration API (#14632)
* perf: 添加加密配置API

* perf: modify url

---------

Co-authored-by: Eric <xplzv@126.com>
2024-12-11 11:34:09 +08:00
Bai d005bd804f fix: user orgs add field: is_system 2024-12-10 19:19:06 +08:00
Bai 08de04fdbc fix: fixed an issue when third-part user auth 2024-12-10 16:41:38 +08:00
Bai 9ed7c41514 fix: fixed an issue when third-part user auth 2024-12-10 16:41:38 +08:00
Eric 1a81b76a46 perf: add new Qwerty for keyboard layout 2024-12-10 15:26:18 +08:00
github-actions[bot] cf99a7a031 perf: Update Dockerfile with new base image tag 2024-12-10 15:25:37 +08:00
Bai 64551b13a1 feat: deps add ipython==8.30.0 2024-12-10 15:25:37 +08:00
Chenyang Shen c715300416
Merge pull request #14623 from jumpserver/pr@dev@separate_face_module
feat: Separate the face recognition module.
2024-12-09 17:00:34 +08:00
feng d9031ae02b perf: Ticket filter assignee_id 2024-12-09 16:58:17 +08:00
Aaron3S 0d2ba5c518 feat: Separate the face recognition module. 2024-12-09 16:57:05 +08:00
Bai 817957dbac fix: fixed an issue where auth backend could pass inspect 2024-12-09 15:38:20 +08:00
feng 3796af78a6 perf: Random secret string 2024-12-09 15:25:31 +08:00
github-actions[bot] 1191e4ab2d perf: Update Dockerfile with new base image tag 2024-12-09 14:21:01 +08:00
吴小白 1c6fcc5826 feat: migrating boto to boto3 2024-12-09 14:21:01 +08:00
Chenyang Shen 4728f95634
Merge pull request #14610 from jumpserver/pr@dev@feat_face_login_acl
feat: login asset face verify acl
2024-12-09 11:34:09 +08:00
Aaron3S 013502186b feat: login asset face verify acl 2024-12-09 11:19:04 +08:00
feng a6d040cd34 perf: Automation filter org 2024-12-06 18:00:56 +08:00
Bai 398758baa6 fix: when oidc enabled and use_state user login raise 400 2024-12-06 16:26:28 +08:00
吴小白 e29bddd89e feat: bump python from 3.11.10 to 3.11.11 2024-12-06 10:29:41 +08:00
Bai e35c915ee3 perf: add workflows auto release docs 2024-12-06 10:20:24 +08:00
Bryan de2dd583d0 Update README.zh-hant.md 2024-12-05 14:49:42 +08:00
Bryan 43f1d7eeae Update README.pt-br.md 2024-12-05 14:49:42 +08:00
Bryan 9bb63e0933 Update README.zh-hans.md 2024-12-05 14:49:42 +08:00
Bryan c9e03fd5d8 Update README.ja.md 2024-12-05 14:49:42 +08:00
github-actions[bot] 7a147242c9 Auto-translate README 2024-12-05 14:49:42 +08:00
github-actions[bot] 392c261a96 Auto-translate README 2024-12-05 14:49:42 +08:00
Bai 2bbccae0f5 perf: readme 2024-12-05 14:39:23 +08:00
Bai 606fa9bfbc feat: change action 2024-12-05 14:24:38 +08:00
fit2bot 96e7b165dd
Auto-translate README (#14584)
* Auto-translate README

* Auto-translate README

* Auto-translate README

* Auto-translate README

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-12-05 14:17:27 +08:00
Bai 148413d280 feat: add auto translate readme 2024-12-05 13:34:04 +08:00
Bai a46a81d477 feat: add auto translate readme 2024-12-05 13:34:04 +08:00
feng ff0f9eb6eb perf: Change secret update version 2024-12-05 10:50:07 +08:00
jiangweidong d8dfaf0868 fix: Solve the problem of version increase caused by push account 2024-12-04 18:50:30 +08:00
Bai 3267c8074b feat: add actions for translate readme 2024-12-04 17:45:21 +08:00
Bai 7b14d680b2 feat: add actions for translate readme 2024-12-04 17:24:12 +08:00
Bai 0980808bb7 fix: compile languages error 2024-12-03 18:14:42 +08:00
Bai 0519f15bbf fix: compile languages error 2024-12-03 18:07:55 +08:00
Eric f6742eb4c6 perf: add dbeaver-patch version 2024-12-03 17:36:59 +08:00
fit2bot f8d11013fc
feat: support pt-br language (#14567)
Co-authored-by: Bai <baijiangjie@gmail.com>
2024-12-03 17:11:08 +08:00
jiangweidong 7875777ed1 fix: Resolving Azure test connection failure issues 2024-12-03 14:34:48 +08:00
jiangweidong 0ca81a8f30 fix: To resolve the 500 error during local updates after an account is deleted from Vault 2024-12-03 14:34:07 +08:00
Bryan 09accbd922
perf: update issue template sorted (#14563)
* perf: update issue template sorted

* perf: update issue template sorted

* Rename 1_bug_report_cn.yml to 2_bug_report_cn.yml

* perf: update issue template sorted

* Rename 1_question.yml to 2_question.yml

* Update and rename 2_feature_request.yml to 3_feature_request.yml

* Rename 2_bug_report_cn.yml to 4_bug_report_cn.yml

* Rename 3_question_cn.yml to 5_question_cn.yml

* Update and rename 2_feature_request_cn.yml to 6_feature_request_cn.yml
2024-12-03 11:21:29 +08:00
fit2bot 945204c45b
perf: Script to Add a Non-existent release_assets Field (#14558)
* perf: Script to Add a Non-existent release_assets Field

* perf: docstring

---------

Co-authored-by: jiangweidong <1053570670@qq.com>
2024-12-02 16:51:52 +08:00
Bai 2d62dc0657 fix: azure vault max_workers 2024-12-02 11:08:59 +08:00
fit2bot fa61688c28
feat: Vault adds Amazon Secrets Manager (#14515)
* feat: Vault adds Amazon Secrets Manager

* perf: optimizing the code

---------

Co-authored-by: jiangweidong <1053570670@qq.com>
2024-11-29 17:51:28 +08:00
halo 801edc7cc9 perf: After optimizing the execution of the azure vault task, the data is out of sync 2024-11-29 16:27:35 +08:00
Bai d0617a0ea4 fix: login log get ipv6 error 2024-11-29 14:59:01 +08:00
Chenyang Shen 1191ed1793
Merge pull request #14546 from jumpserver/pr@dev@feat_move_face_to_profile
feat: move face setiing to profile
2024-11-28 18:19:32 +08:00
Aaron3S 4036420d0e feat: move face setiing to profile 2024-11-28 18:06:57 +08:00
jiangweidong 35a1655905 perf: Oauth2.0 support two methods for passing authentication credentials. 2024-11-26 14:12:56 +08:00
feng d4dc31aefa perf: Modify default_context COPYRIGHT 2024-11-25 15:30:26 +08:00
wangruidong 04ec34364f perf: Add viewAssetOnlineSessionInfo conf 2024-11-25 15:28:57 +08:00
Aaron3S 01b8c1f7a8 fix: Fix the uncaught exception when face capture fails 2024-11-25 10:17:28 +08:00
Bai 77598a0f23 perf: update readme 2024-11-22 16:43:44 +08:00
wangruidong eafb074fda refactor: API endpoint 2024-11-22 15:14:26 +08:00
Bryan d4d903f5c6
perf: Update README.md (#14516)
* perf: Update README.md

* perf: Update README.md
2024-11-22 10:38:32 +08:00
吴小白 c9c55b5fcb fix: add libldap2-dev 2024-11-21 20:53:11 +08:00
Bryan 25987545db
Merge pull request #14511 from jumpserver/dev
v4.4.0
2024-11-21 19:00:35 +08:00
wangruidong f7313bfcc1 perf: Audits job api disable periodic task 2024-11-21 18:56:16 +08:00
Bai d2f7376f78 fix: job execution stop failed 2024-11-21 18:38:10 +08:00
wangruidong 6db56eb2aa fix: view ops job celery log no perms 2024-11-21 18:14:45 +08:00
fit2bot 442290703a
fix: pyfreerdp verify account, the default value of gateway_args field is wrong (#14490)
* fix: pyfreerdp verify account, the default value of gateway_args field is wrong

* fix: pyfreerdp verify account, the default value of gateway_args field is wrong

---------

Co-authored-by: Ewall555 <a03216@foxmail.com>
2024-11-21 14:26:22 +08:00
feng e491a724ed perf: Video player download 2024-11-21 14:25:50 +08:00
feng 230924baac fix: Vault proxy 2024-11-21 13:40:33 +08:00
wangruidong 0ae2f04f28 fix: view ops job celery log no perms 2024-11-21 13:24:29 +08:00
feng 68a490d305 perf: Hide azure vault 2024-11-21 13:02:40 +08:00
wangruidong 6abfeee683 feat: Add periodic display and validate job params 2024-11-20 22:07:56 +08:00
Aaron3S 1a03f7b265 feat: add license edition check 2024-11-20 20:09:11 +08:00
feng 2dae2b3789 perf: Translate 2024-11-20 18:21:31 +08:00
Aaron3S bdbbebab76 feat: perf face capture page 2024-11-20 17:54:27 +08:00
Chenyang Shen 33170887f4
Merge pull request #14495 from jumpserver/pr@dev@feat_add_check_api_white_list
feat: add 'face_context' to check_api white list
2024-11-20 17:52:06 +08:00
Aaron3S 88302c8846 feat: add 'face_context' to check_api white list 2024-11-20 16:38:22 +08:00
feng 4068b5c76a perf: Change secret ssh_key_change_strategy modify the default value 2024-11-20 16:27:21 +08:00
feng 9966ad4c71 perf: Dynamic update vault 2024-11-20 15:58:20 +08:00
Aaron3S 9cfe974c52 feat: 添加 mfa middleware 白名单 2024-11-20 14:18:52 +08:00
feng d9a9f890f5 perf: Lina AzureKeyVault translate 2024-11-20 14:08:27 +08:00
fit2bot e2904ab042
perf: Custom SMS (files) support obtaining more user information. (#14486)
* perf: Custom SMS (files) support obtaining more user information.

* perf: Remove the useless modules

* perf: modify

---------

Co-authored-by: jiangweidong <1053570670@qq.com>
2024-11-20 10:29:14 +08:00
Aaron3S f92c557235 feat: 增加人脸识别超时控制 2024-11-20 10:27:04 +08:00
halo cfadbc164c perf: If the cloud vault initialization fails, the task will not be executed. 2024-11-20 10:15:14 +08:00
feng 374a102bc4 perf: Translate 2024-11-19 18:58:43 +08:00
feng 84e1411c22 fix: Clone endpoint 500 2024-11-19 18:09:00 +08:00
wangruidong e28bf170d1 perf: MFA Translate 2024-11-19 17:55:11 +08:00
wangruidong 7c9e3a1362 perf: Optimize summary calculation 2024-11-19 17:55:11 +08:00
feng fba80342a5 perf: Translate 2024-11-19 17:54:45 +08:00
Aaron3S 5eeff0aabf feat: 设置人脸上下文存活时间 2024-11-19 17:34:44 +08:00
Aaron3S 5b4de02fff feat: 增加绑定成功失败提示 2024-11-19 17:30:31 +08:00
wangruidong b6a5854fa2 perf: Optimize summary calculation 2024-11-19 16:13:38 +08:00
Chenyang Shen 9771d3c817
Merge pull request #14476 from jumpserver/pr@dev@feat_add_face_i18n
FEAT: Add face recognition translation
2024-11-19 15:11:03 +08:00
Aaron3S b33a0cf0b1 feat: 添加人脸识别翻译 2024-11-19 15:08:39 +08:00
Chenyang Shen f9fa6ad9c1
Merge pull request #14474 from jumpserver/pr@dev@feat_update_face_capture_page
feat: Optimized the face collection page
2024-11-19 15:01:45 +08:00
Aaron3S 4b2db2b6a1 feat: 优化人脸采集页面 2024-11-19 14:28:31 +08:00
Halo 822b353a40
perf: Translate (#14468)
* feat: azure key vault

* perf: add azure-keyvault-secrets

* perf:azure kv api

* perf: Translate

* perf: Update Dockerfile with new base image tag

* perf: Error when secret is empty

* perf: Translate

* perf: Update Dockerfile with new base image tag

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-11-18 18:48:33 +08:00
feng 2908d4ee5f perf: Delete asset fail 2024-11-18 10:08:37 +08:00
wangruidong 482c4ced0c perf: Translate 2024-11-15 18:00:35 +08:00
halo b2a5e457a9 fix: vault synchronization task exception 2024-11-15 17:46:17 +08:00
wangruidong 343c3607fa fix: modify job audit rbac 2024-11-15 15:47:20 +08:00
wangruidong f03263eedf fix: Radius login failed 2024-11-15 15:44:05 +08:00
Aaron3S 98d7ecbf3e fix: 修改错误的url地址 2024-11-13 17:35:43 +08:00
halo 477ccda8ca perf: VAULT_BACKEND cannot be modified from the frontend 2024-11-13 17:31:47 +08:00
wangruidong fcdc2b9510 fix: Solve audit job and variable bugs 2024-11-13 17:31:17 +08:00
wangruidong 1ee57cfda0 perf: ticket info add org name 2024-11-12 18:15:31 +08:00
wangruidong 804bd289a4 fix: Other people can delete adhoc or playbook 2024-11-12 17:44:21 +08:00
Aaron3S 86273865c8 feat: 增加人脸识别功能 2024-11-12 17:41:39 +08:00
Eric 5142f0340c perf: add license info for component config 2024-11-12 16:52:45 +08:00
Bai 7c80c52d02 fix: Set the default language to en 2024-11-12 15:43:57 +08:00
Bai eb30b61ca9 fix: Set the default language to en 2024-11-12 15:38:01 +08:00
wangruidong dd5a272cdf perf: Add task handler for ops job with creator assignment 2024-11-12 15:16:01 +08:00
wangruidong 5b27acf4ef perf: Admin and auditor can view and stop task 2024-11-12 11:25:12 +08:00
Eric 1a41a7450e perf: vnc proxy port to 15900 2024-11-11 19:46:24 +08:00
fit2bot e1b501c7d4
feat: azure key vault (#14406)
* feat: azure key vault

* perf: add azure-keyvault-secrets

* perf:azure kv api

* perf: Translate

* perf: Update Dockerfile with new base image tag

* perf: Error when secret is empty

* perf: Translate

---------

Co-authored-by: halo <wuyihuangw@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-11-11 19:41:47 +08:00
Eric b660bfb7ff perf: add nec vnc component and endpoint migrations 2024-11-11 18:54:52 +08:00
wangruidong 5724912480 perf: Add check for SECURITY_COMMAND_EXECUTION settings in ops tasks 2024-11-11 18:14:43 +08:00
feng 11b3bafd5a perf: Translate 2024-11-08 15:34:37 +08:00
wangruidong 9f90838df1 perf: Optimize username handling in push_account 2024-11-07 10:47:01 +08:00
wangruidong b01916001e fix: User import fails if MFA field is set to Disabled (0) 2024-11-07 10:45:05 +08:00
fit2bot c96ae1022b
feat: Supports running adhoc,playbook with variable (#14417)
* perf:Create a job that supports adding node parameters

* feat: add variable model

* feat: Modify Variable and AdHoc models,

* feat: Parameters can be set when running job

* feat: Supports setting  variable type

* feat: Supports running adhoc with parameters

* feat: Supports running playbook with parameters

* fix: Translate

* feat: Support setting variables for scheduled tasks

* perf: Translate

---------

Co-authored-by: wangruidong <940853815@qq.com>
2024-11-07 10:38:34 +08:00
jiangweidong 8f11167db0 perf: i18n - Supports automatic release of assets and prevents accidental release of network errors 2024-11-06 15:07:26 +08:00
老广 a53397b76f
Update llm-code-review.yml 2024-11-05 18:20:38 +08:00
老广 8f13224454
Create llm-code-review.yml 2024-11-04 18:34:06 +08:00
Bai 8f4dd25e69 feat: DEFAULT_EXPIRED_YEARS put in public settings API 2024-11-01 18:24:54 +08:00
Bai 9c8762e3a0 feat: support configuration DEFAULT_EXPIRED_YEARS 2024-11-01 15:48:57 +08:00
Bai a8cf788122 feat: add GitHub Action to automatically publish release notes to Discord changelog channel. 2024-11-01 15:24:07 +08:00
Bai 7355a4f152 feat: add GitHub Action to automatically publish release notes to Discord changelog channel. 2024-11-01 14:21:48 +08:00
ibuler 2cf80e6615 perf: login success to call client 2024-10-31 18:36:42 +08:00
ibuler 9a18ed631c fix: oracle platform create error 2024-10-30 16:33:18 +08:00
Bai 1e16f1cb9f fix: console dashboard proportion describe 2024-10-29 19:09:50 +08:00
fit2bot 35b8b080ab
perf: add to cron.d (#14375)
* perf: add to cron.d

* perf: Update Dockerfile with new base image tag

---------

Co-authored-by: ibuler <ibuler@qq.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-29 16:15:07 +08:00
ibuler 4219d54db3 perf: add cron in dockerfile 2024-10-29 15:39:54 +08:00
ibuler c3620254b3 perf: change docker file 2024-10-29 15:32:57 +08:00
fit2bot d30de0b6a0
perf: update chrome applets hang (#14353)
* perf: update chrome applets hang

* perf: remove debug print

---------

Co-authored-by: Eric <xplzv@126.com>
2024-10-29 15:19:15 +08:00
github-actions[bot] af91b6faeb perf: Update Dockerfile with new base image tag 2024-10-29 15:18:24 +08:00
ibuler 49b84b019d perf: using poetry mirror 2024-10-29 15:18:24 +08:00
ibuler a0ee520572 perf: remove cache 2024-10-29 15:18:24 +08:00
fit2bot 972afe0bfe
perf: revert old deps (#14371)
* perf: revert old deps

* perf: update poetry

* perf: Update Dockerfile with new base image tag

---------

Co-authored-by: ibuler <ibuler@qq.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-29 14:24:31 +08:00
wangruidong e47e9b0a11 fix: Unique basename 2024-10-29 11:38:46 +08:00
fit2bot 87e54d8823
perf: add cron (#14364)
* perf: add cron

* Update Dockerfile-base

* perf: Update Dockerfile with new base image tag

---------

Co-authored-by: ibuler <ibuler@qq.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-29 10:56:42 +08:00
jiangweidong a73c8d8285 fix: Wechat ticket message some url cannot clicked 2024-10-25 15:05:13 +08:00
Eric b0dd8d044d perf: add error msg when applet task failed 2024-10-24 14:55:33 +08:00
jiangweidong 7c55c42582 perf: Links in WeCom messages can be opened without re-logging in. 2024-10-22 17:02:59 +08:00
fit2bot cc1fcd2b98
perf: move storage sdk to core (#14318)
* perf: move storage sdk to core

* perf: Update Dockerfile with new base image tag

---------

Co-authored-by: ibuler <ibuler@qq.com>
Co-authored-by: Bai <baijiangjie@gmail.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-22 15:20:10 +08:00
fit2bot 8434d8d5ba
perf: update dependency (#14307)
* perf: update dependency

* perf: remove source build

* perf: Update Dockerfile with new base image tag

* perf: use cache build

* perf: Update Dockerfile with new base image tag

* fix: variable incorrectly defined

* perf: Update Dockerfile with new base image tag

* fix: openpyxl fixed version

* perf: Update Dockerfile with new base image tag

* perf: remove cache

* perf: Update Dockerfile with new base image tag

* perf: update pyproject.toml

* perf: Update Dockerfile with new base image tag

* perf: remove cache

* perf: Update Dockerfile with new base image tag

---------

Co-authored-by: 吴小白 <296015668@qq.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-10-22 14:16:19 +08:00
feng 044fd238b8 perf: Remove ssh_key_change_strategy add value 2024-10-21 15:25:38 +08:00
feng be096a1319 perf: List preference translate 2024-10-18 14:36:13 +08:00
吴小白 6fa14833b3 perf: use python embed 2024-10-18 11:02:49 +08:00
feng 1f32ab274c fix: Error subpub_msg log 2024-10-17 15:17:32 +08:00
Bryan 6720ecc6e0
Merge pull request #14319 from jumpserver/dev
v4.3.0
2024-10-17 14:55:38 +08:00
feng b0f86e43a6 perf: Translate 2024-10-17 12:05:25 +08:00
ibuler 9b0c81333f perf: debug pub sub 2024-10-17 10:16:44 +08:00
Eric 05fc966444 perf: add koko i18n 2024-10-16 18:25:42 +08:00
Eric b87650038f perf: update code 2024-10-16 18:11:00 +08:00
wangruidong d4f69a7ff8 perf: Translate 2024-10-16 17:59:18 +08:00
ibuler 0e1e26c29c perf: disable f1 key 2024-10-16 17:01:10 +08:00
Huaqing Chen 1b8cdbc4dd 修复websocket不能使用Authorization Header的问题 2024-10-15 14:13:38 +08:00
feng 2a781c228f perf: Cas user cannot bind organization 2024-10-15 10:50:20 +08:00
ZhaoJiSen 35d6b0f16a
Merge pull request #14299 from jumpserver/pr@dev@change_password_length
perf: Change secret remove redundant checks
2024-10-14 16:45:27 +08:00
feng ca8987fef6 perf: Change secret remove redundant checks 2024-10-14 16:39:31 +08:00
ZhaoJiSen b385133071
Merge pull request #14297 from jumpserver/pr@dev@translate
perf: Translate
2024-10-14 16:09:21 +08:00
feng aa78a03efa perf: Translate 2024-10-14 16:05:38 +08:00
wangruidong 31f8a19392 perf: Translate account history 2024-10-14 15:31:17 +08:00
wangruidong 7a528b499a perf: import data validate platform 2024-10-14 14:05:24 +08:00
Eric 1c6ce422cf perf: update tinker v0.1.9 2024-10-12 16:30:28 +08:00
Eric f9cf2ea2e5 perf: fix api error when deleting offline panda components 2024-10-12 16:15:23 +08:00
Aaron3S 575b3a617f feat: 添加 chen 翻译 2024-10-12 15:44:38 +08:00
wangruidong b7362d3f51 fix: adhoc execute alert msg 2024-10-12 15:43:03 +08:00
ZhaoJiSen 6ee3860124
Merge pull request #14287 from jumpserver/pr@dev@translate
perf: Translate
2024-10-12 14:40:23 +08:00
feng 7e111da529 perf: Translate 2024-10-12 14:35:18 +08:00
wangruidong 578458f734 perf: site msg content optimize 2024-10-11 11:28:56 +08:00
Bai bd56697d6d perf: DEFAULT_PAGE_SIZE same as MAX_LIMIT_PER_PAGE 2024-10-10 18:00:01 +08:00
wangruidong aad824d127 perf: add created_by field 2024-10-09 16:14:22 +08:00
wangruidong 63f828da0b perf: Default endpoint cannot be disabled 2024-10-09 16:12:37 +08:00
wangruidong 7c211b3fb6 perf: Translate 2024-10-08 15:01:53 +08:00
feng 3881edd2ba perf: Optimize file audit download prompt 2024-09-29 16:12:49 +08:00
feng b882b12d04 perf: Check the validity of the connection token 2024-09-27 17:10:08 +08:00
wangruidong addd2e7d1c perf: Endpoint add is_active field 2024-09-27 16:00:05 +08:00
Bai ad6d2e1cd7 fix: Fixed the issue that the workbench user login log only displays failed logs 2024-09-27 14:34:23 +08:00
github-actions[bot] 5f07271afa perf: Update Dockerfile with new base image tag 2024-09-27 14:30:48 +08:00
Bai efdcd4c708 perf: upgrade geoip2 and .mmdb 2024-09-27 14:30:48 +08:00
jiangweidong b62763bca3 perf: Cloud Sync IP Policy Updated to Preferred Option i18n 2024-09-27 14:29:09 +08:00
wangruidong e95da730f2 perf: Koko can display assets custom name 2024-09-27 14:25:55 +08:00
fit2bot 43fa3f420a
fix: Addressing the issue of unauthorized execution of system tools (#14209)
* fix: Addressing the issue of unauthorized execution of system tools

* perf: Optimization conditions

---------

Co-authored-by: jiangweidong <1053570670@qq.com>
2024-09-27 14:17:16 +08:00
wangruidong 0311446384 perf: playbook clone with file 2024-09-27 14:13:35 +08:00
feng f7030e4fee perf: Login encryption key cache added 2024-09-26 15:11:35 +08:00
ZhaoJiSen fce8cc375f
Merge pull request #14230 from jumpserver/pr@dev@max_password_length
perf: The maximum length of the randomly generated password is changed to 36
2024-09-25 11:00:45 +08:00
feng 920199c6df perf: The maximum length of the randomly generated password is changed to 36 2024-09-25 10:52:16 +08:00
feng d09eb3c4fa perf: Lock username is not case sensitive 2024-09-23 14:11:55 +08:00
ibuler 6e8affcdd6 perf: ops db migrate 2024-09-19 21:39:55 +08:00
老广 0b3a7bb020
Merge pull request #14203 from jumpserver/dev
merge: from dev to master
2024-09-19 19:37:19 +08:00
wangruidong 647736f4e3 fix: SAML2 500 error caused by duplicate email or username 2024-09-19 17:49:53 +08:00
ZhaoJiSen cbc09d84df
Merge pull request #14202 from jumpserver/pr@dev@password_rule
perf: Password rule import csv help_text
2024-09-19 16:54:52 +08:00
feng 4c957dd03b perf: Password rule import csv help_text 2024-09-19 16:51:43 +08:00
wangruidong d34b65890f fix: import account failed 2024-09-19 15:12:05 +08:00
Bai b53968ac00 delete: ansible log in logging.py 2024-09-19 15:11:31 +08:00
ZhaoJiSen f2ccb15101
Merge pull request #14198 from jumpserver/pr@dev@saml
perf: Bind user group support str
2024-09-19 12:01:20 +08:00
feng db5bf046fc perf: Bind user group support str 2024-09-19 11:58:45 +08:00
ibuler 59c87483e6 perf: filter gateway with new params 2024-09-19 11:33:02 +08:00
github-actions[bot] 26420b78f8 perf: Update Dockerfile with new base image tag 2024-09-19 11:18:04 +08:00
wangruidong e47bdc093e perf: trigger core base image build 2024-09-19 11:18:04 +08:00
wangruidong 3dde80a60a fix: Password reset is only required for AUTH_BACKEND_MODEL 2024-09-19 11:08:11 +08:00
feng e373a79d63 perf: Gateway type asset filter 2024-09-19 10:45:59 +08:00
wangruidong 744a5cd0e3 perf: Modify relative file path 2024-09-19 10:41:12 +08:00
wangruidong 37ca4a46ee perf: add clean_site_packages.sh file path to build-base-image.yml 2024-09-19 10:25:08 +08:00
wangruidong 0dc9214f98 fix: LDAP HA the login log did not record the authentication backend 2024-09-18 18:53:03 +08:00
wangruidong 513508654b fix: minio test failed 2024-09-18 18:51:25 +08:00
feng ef2b12fa0f perf: Export template with prompts 2024-09-18 18:26:38 +08:00
feng 4e719ecacd perf: TimerExecution translate 2024-09-18 15:02:17 +08:00
ibuler 755a124b50 perf: checkout repo 2024-09-14 18:32:23 +08:00
zhaojisen d6888776e7 perf: translate 2024-09-14 18:20:46 +08:00
wangruidong 29e233e715 perf: RemoteApp machine deployOption translate 2024-09-14 18:19:22 +08:00
wangruidong 99c3696d96 fix: Failed to import csv data 2024-09-14 18:17:15 +08:00
ibuler ed6de83e8c perf: workflow push with full name 2024-09-14 18:09:30 +08:00
Eric 134f1a440c perf: replay part file download 2024-09-14 18:06:05 +08:00
ibuler 7da82242fe perf: github action workflow 2024-09-14 17:47:34 +08:00
Eric 2fd50d2425 perf: update compilemessages check ci 2024-09-14 17:38:07 +08:00
fit2bot 41a3e89248
chore: using pull pull request not push event (#14164)
* perf: diff with head not dev

* chore: using pull pull request not push event

---------

Co-authored-by: ibuler <ibuler@qq.com>
2024-09-14 17:21:49 +08:00
Bai b125297c37 feat: GitHub Actions add compilemessages checked 2024-09-14 17:04:35 +08:00
ibuler 24255b69ee perf: diff with head not dev 2024-09-14 17:01:02 +08:00
ibuler 3bb51b39c4 perf: github action fetch branches 2024-09-14 16:51:25 +08:00
ibuler b54da7d3b3 perf: workflow build base image 2024-09-14 16:42:06 +08:00
ibuler 534af0abf0 perf: build workflow 2024-09-14 16:32:15 +08:00
ibuler 8b0073333b perf: change git workflow 2024-09-14 16:25:06 +08:00
ZhaoJiSen d8af2274f4
Merge pull request #14154 from jumpserver/pr@dev@koko_zh_translate
perf: KOKO zh translate
2024-09-14 15:34:27 +08:00
ibuler 3dd828d703 perf: workflow build base image 2024-09-14 15:34:20 +08:00
feng fa6b4a5b63 perf: KOKO zh translate 2024-09-14 15:32:52 +08:00
ZhaoJiSen 8bd86c77f9
Merge pull request #14151 from jumpserver/pr@dev@win_rdp_ping
fix: Windows rdp ping fail
2024-09-14 14:48:17 +08:00
feng 3828e89cf8 fix: Windows rdp ping fail 2024-09-14 14:47:14 +08:00
wangruidong e531b040ef fix: compilemessages error 2024-09-13 22:38:58 +08:00
wangruidong 3eee84a34e fix: delete ReplayStorage error 2024-09-13 19:09:21 +08:00
wangruidong ab29df5991 fix: command search input error 2024-09-13 19:05:38 +08:00
wangruidong b042f00688 fix: command search input error 2024-09-13 19:05:11 +08:00
github-actions[bot] 5beebaf51c perf: Update Dockerfile with new base image tag 2024-09-13 19:03:39 +08:00
wangruidong 50f075cc7e fix: Historical sessions download failed 2024-09-13 19:03:39 +08:00
Bai e997236159 perf: Modify gunicorn log file rotate yesterday dir 2024-09-13 18:37:13 +08:00
ZhaoJiSen c8b1d892e3
Merge pull request #14145 from jumpserver/pr@dev@account_already_exists
fix: Translate Account already exists
2024-09-13 18:33:25 +08:00
feng 9cb9e7328b fix: Translate Account already exists 2024-09-13 18:32:06 +08:00
feng 85129da942 perf: Postgresql add ssl mode 2024-09-13 17:49:14 +08:00
ZhaoJiSen 1cb00b1db4
Merge pull request #14138 from jumpserver/pr@dev@markdown_html
fix: Internal letter hyperlinks cannot be redirected
2024-09-13 11:07:08 +08:00
feng c3798bfa95 fix: Internal letter hyperlinks cannot be redirected 2024-09-13 11:05:22 +08:00
github-actions[bot] 1d280599ae perf: Update Dockerfile with new base image tag 2024-09-12 18:55:01 +08:00
feng ee8d7cdcac perf: Upgrade ansible postgresql 2024-09-12 18:55:01 +08:00
Aaron3S 1b4114fd5f perf: Optimize chen translation 2024-09-12 18:49:04 +08:00
Chenyang Shen 3c6c476f2e
Merge pull request #14135 from jumpserver/pr@dev@feat_add_some_chen_i18n
feat: add chen i18n
2024-09-12 18:41:47 +08:00
Aaron3S f19e3fedbd feat: add chen i18n 2024-09-12 18:38:16 +08:00
Bai 542e64278f perf: fix migrate adhoc playbook 2024-09-12 16:33:36 +08:00
wangruidong cd76294e81 fix: migrate ops adhoc and playbook unique_together error 2024-09-12 16:33:36 +08:00
wangruidong 4f9158b2ad fix: ldap test config msg error 2024-09-12 10:41:17 +08:00
ZhaoJiSen e319f20296
Merge pull request #14126 from jumpserver/pr@dev@third_party_user_login_failed
perf: Third-party user login failed
2024-09-12 10:23:05 +08:00
feng b00f3a851c perf: Third-party user login failed 2024-09-12 10:19:40 +08:00
wangruidong ab529fd22c fix: i18n compilemessages error 2024-09-12 10:07:12 +08:00
wangruidong c2784c44ad feat: LDAP HA 2024-09-11 18:26:11 +08:00
feng 512e727ac6 feat: Postgresql support ssl 2024-09-11 18:12:25 +08:00
wangruidong 2dd0154967 perf: modify only_myself to only_mine 2024-09-11 18:02:35 +08:00
wangruidong f55869a449 feat: Support playbook, adhoc share 2024-09-11 17:52:06 +08:00
wangruidong b6f3c23787 perf: task description translate 2024-09-11 14:57:07 +08:00
github-actions[bot] 6982ab1efc perf: Update Dockerfile with new base image tag 2024-09-10 15:54:05 +08:00
wangruidong db4d841bb0 perf: add xpack task description 2024-09-10 15:54:05 +08:00
wangruidong ef91ebb468 perf: clean expired and account is null SyncInstanceTask record 2024-09-10 15:50:11 +08:00
fit2bot 6264319c51
perf: When connected through a gateway, you can use nc to forward data (#14110)
Co-authored-by: feng <1304903146@qq.com>
Co-authored-by: Bryan <jiangjie.bai@fit2cloud.com>
2024-09-09 19:00:48 +08:00
fit2bot 1417abecfb
perf: Add task description (#14033)
Co-authored-by: ZhaoJiSen <97007455+ZhaoJiSen@users.noreply.github.com>
2024-09-09 18:54:33 +08:00
老广 bd548b3fe2 Revert "perf: update deps"
This reverts commit 76b6489636.
2024-09-09 15:33:57 +08:00
ZhaoJiSen 94cef9ea6e
Merge pull request #14106 from jumpserver/pr@dev@translate
perf: Translate
2024-09-09 14:29:04 +08:00
feng626 a338613b5a Merge branch 'dev' into pr@dev@translate 2024-09-09 14:27:38 +08:00
feng 0d833a966c perf: Translate 2024-09-09 14:15:16 +08:00
ibuler 76b6489636 perf: update deps 2024-09-09 11:39:51 +08:00
fit2bot 763fe778d5
perf: finish this feat (#14079)
* perf: basic finished

* perf: finish this feat

* perf: add datetime demo

---------

Co-authored-by: ibuler <ibuler@qq.com>
2024-09-09 11:26:24 +08:00
ibuler cf1dc79c68 perf: applet host tips 2024-09-09 10:25:01 +08:00
ibuler 7973239424 perf: support change gateway platform 2024-09-06 17:35:57 +08:00
feng 1baacd0b2c perf: Disable delete admin user 2024-09-06 15:37:12 +08:00
feng 054d385ffc perf: Acl action add notify and warn 2024-09-06 11:07:30 +08:00
wangruidong 50d3a4906a feat: Add announcement start and end dates 2024-09-06 10:54:27 +08:00
wangruidong c8b7008d42 perf: Translate 2024-09-06 10:54:12 +08:00
kebyn e94520a3fd fix: 修复非标准实现 X-Forwarded-For 时的问题 2024-09-06 10:31:58 +08:00
wangruidong 55e8e34226 fix: 500 error caused by duplicate email or username 2024-09-06 10:22:37 +08:00
wangruidong 8755ece633 perf: Translate 2024-09-05 19:24:19 +08:00
feng c545e2a3aa perf: Support SAML2, OIDC user authentication services, mapping user group field information 2024-09-04 18:42:47 +08:00
wangruidong 1068662ab1 perf: Optimize asset connection speed with es command storage 2024-09-02 13:52:23 +08:00
ZhaoJiSen 75141741a1
Merge pull request #14062 from jumpserver/pr@dev@translate
perf: Translate
2024-08-30 15:18:45 +08:00
feng 9da507bb62 perf: Translate 2024-08-30 15:16:44 +08:00
fit2bot 160293365a
perf: Regularly delete useless password change push records (#14026)
* perf: If the user Home page does not exist, push will fail

* perf: Change secret add uid parameter

* perf: Regularly delete useless password change push records

---------

Co-authored-by: feng <1304903146@qq.com>
2024-08-30 15:01:40 +08:00
wangruidong 7a19007aba perf: ldap import user error msg 2024-08-30 14:55:22 +08:00
ibuler f866b93f96 perf: refresh oracle ports if need 2024-08-29 19:06:55 +08:00
feng b9e64747ac perf: View the internal message and convert the content into markdown 2024-08-29 17:28:12 +08:00
fit2bot 25a473dc99 chore: update checkout action 2024-08-29 17:22:25 +08:00
Bai e3bf015aa9 fix: user role can't open page of password & ssh key 2024-08-29 14:44:36 +08:00
Bryan 6d3d4a08af
Update README.md (#14043)
* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md

* Update README.md
2024-08-28 17:55:56 +08:00
Bai 9554de4ea6 fix: User check password need reset 2024-08-28 15:08:24 +08:00
ZhaoJiSen 6157ff7b7d
Merge pull request #14032 from jumpserver/pr@dev@koko_translate
perf: Koko translate
2024-08-27 17:41:30 +08:00
feng 774fd176fd perf: Koko translate 2024-08-27 17:39:37 +08:00
ibuler b489db8054 perf: add a script activate user manually 2024-08-21 14:55:57 +08:00
ZhaoJiSen 6b9fa6e01f
Merge pull request #14010 from jumpserver/pr@dev@view_asset
perf: View asset mini api add domain platform field
2024-08-21 11:34:20 +08:00
ZhaoJiSen 9b59954393
Merge pull request #14011 from jumpserver/pr@dev@test_asset
perf: No permission to test asset connectivity
2024-08-21 11:33:55 +08:00
feng ecaf19563f perf: No permission to test asset connectivity 2024-08-21 11:28:39 +08:00
feng c431e96eaf perf: View asset mini api add domain platform field 2024-08-21 10:35:07 +08:00
ZhaoJiSen d86f241450
Merge pull request #14005 from jumpserver/pr@dev@translate
perf: Translate
2024-08-20 11:30:37 +08:00
feng 3252db31fe perf: Translate 2024-08-20 11:28:30 +08:00
Bai dac118dd26 perf: delete organization message 2024-08-19 16:06:37 +08:00
fit2bot 181eb621c0
perf: Remove kubernetes tree api (#13995)
* perf: Remove kubernetes tree api

* perf: Update Dockerfile with new base image tag

---------

Co-authored-by: feng <1304903146@qq.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: feng626 <57284900+feng626@users.noreply.github.com>
2024-08-19 16:04:00 +08:00
ibuler 828582333d perf: remove ansible receptcel 2024-08-19 11:16:58 +08:00
github-actions[bot] 657f7f822b perf: Update Dockerfile with new base image tag 2024-08-19 10:50:39 +08:00
ibuler 93627e4f9d perf: clean site packages 2024-08-19 10:50:39 +08:00
feng 2adb2519fa perf: Push password change and select finally use rdp to test connectivity. rdp does not support gateway 2024-08-19 10:20:33 +08:00
Bryan 56373e362b
Merge pull request #13988 from jumpserver/dev
v4.1.0
2024-08-16 18:40:35 +08:00
wangruidong 32ec48ac14 perf: Improve performance by optimizing ES index creation 2024-08-16 18:19:04 +08:00
Bai b3a0d81740 fix: job periodic task double run 2024-08-15 20:17:20 +08:00
ibuler 2b160fbbc2 revert: entrypoint.sh 2024-08-15 20:14:24 +08:00
wangruidong 60fcf5fcd3 perf: luna connect asset name set custom value 2024-08-15 19:47:56 +08:00
Bai 7c2e50435d perf: i18n for ldap user import 2024-08-15 15:50:56 +08:00
ZhaoJiSen 57f91d0973
Merge pull request #13980 from jumpserver/pr@dev@no_account_found
perf: Lina translate
2024-08-15 14:49:41 +08:00
feng 49c033e003 perf: Lina translate 2024-08-15 14:47:55 +08:00
Ewall555 6476a8fee8 perf: Translate ticket cancel button 2024-08-15 14:35:43 +08:00
wangruidong c10db2ab0f perf: LDAP import user Translate 2024-08-15 14:35:06 +08:00
wangruidong 647beffc01 fix: no accounts no send msg 2024-08-14 19:25:11 +08:00
feng ac0c6ef3d5 perf: Storage update comment failed 2024-08-14 19:18:10 +08:00
feng e13741827d fix: Domain detail asset amount mistake 2024-08-14 17:37:03 +08:00
wangruidong 29caf0154e perf: Translate batch approval 2024-08-14 17:36:23 +08:00
wangruidong fbdcc437e6 perf: ticket msg field value set truncate string length 2024-08-14 16:45:43 +08:00
feng b38e5df1aa perf: Translate 2024-08-14 16:37:57 +08:00
feng 0a39ba0a75 fix: Use only_sudo failed 2024-08-14 16:15:57 +08:00
wangruidong c56e1bdbbe fix: call get_verify_state_failed_response NotImplementedError 2024-08-13 18:51:15 +08:00
feng 6b00ba271f perf: Replace Feishu to obtain user information interface 2024-08-13 18:13:08 +08:00
wangruidong bddb1de2f8 perf: Comment translate 2024-08-13 18:04:29 +08:00
wangruidong 32ae77c42d perf: add TERMINAL_SSH_KEY_LIMIT_COUNT conf 2024-08-13 17:39:03 +08:00
feng 3b1701b1aa perf: Translate 2024-08-12 18:41:05 +08:00
feng 3b9bcc719e perf: Reset password: optimize form frame 2024-08-12 15:16:06 +08:00
feng 8e6aa4524d perf: Ip type translate 2024-08-09 17:10:11 +08:00
feng cea63e6083 perf: Setting user attributes is invalid 2024-08-09 16:53:13 +08:00
feng 5d2d8ca487 perf: Translate 2024-08-08 19:17:34 +08:00
fit2bot 81146f44f7 perf: set default version 2024-08-08 17:54:43 +08:00
fit2bot 9adaa27f6c
perf: Luna login expire message (#13917)
* perf: Luna login expire message

* perf: Login timeout open in a new window

---------

Co-authored-by: feng <1304903146@qq.com>
2024-08-08 17:54:02 +08:00
feng 01c565f93f perf: Activity log no display 2024-08-08 16:39:44 +08:00
fit2bot cb97afffab chore: remove build test 2024-08-08 16:06:51 +08:00
github-actions[bot] 1b55bf1670 perf: Update Dockerfile with new base image tag 2024-08-08 16:06:28 +08:00
fit2bot b1c68165bb perf: update check version to v1.0.3 2024-08-08 16:06:28 +08:00
wangruidong 5d3e633e83 perf: ldap import msg modify 2024-08-07 19:12:42 +08:00
Eric c863bf63b1 perf: update lina i18n 2024-08-07 17:45:55 +08:00
wangruidong c71a6ae4ba fix: ssh_key search failed 2024-08-07 17:04:38 +08:00
wangruidong 38e3d9de8b feat: Allow users to customize asset name and comment 2024-08-07 16:44:01 +08:00
Eric 0c73acd4b9 perf: support only su or sudo 2024-08-07 10:57:09 +08:00
wangruidong 581a5c73a6 perf: object storage builtin comment i18n 2024-08-06 10:44:15 +08:00
feng e1ed1d7c4c perf: Reset password remove sensitive data 2024-08-05 18:25:11 +08:00
Eric 805e7d1d5f perf: Check whether the applet is available. 2024-08-05 18:18:54 +08:00
feng 1957c2983b perf: Ticket set serial number add lock 2024-08-05 17:53:43 +08:00
Bai 6b1ceae6c5 perf: delete blank line 2024-08-05 16:29:54 +08:00
wangruidong 2a5c41dfaf feat: support configuring multiple SSH keys for users 2024-08-05 15:22:54 +08:00
wangruidong 7a38c9136e feat: Allow users to customize asset name and comment 2024-08-05 14:50:24 +08:00
ZhaoJiSen 9a3fdf76fc
Merge pull request #13876 from jumpserver/pr@dev@translate
perf: Translate
2024-08-05 14:33:41 +08:00
feng 136db61011 perf: Translate 2024-08-05 14:31:08 +08:00
ibuler 0d338f80c5 perf: ee dockerfile 2024-08-05 14:23:32 +08:00
feng bd3909ad27 perf: Third-party user login settings default organization 2024-08-02 15:52:05 +08:00
Eric 96399f8315 perf: update tinker v0.1.7 2024-08-02 14:10:03 +08:00
ibuler 4e90d17484 perf: poetry mirror 2024-08-01 18:18:08 +08:00
ibuler 13de75c41f perf: docker file poetry mirror 2024-08-01 17:37:15 +08:00
ibuler a77ebc5fee perf: pkg download
perf: resource download

perf: resource download
2024-08-01 16:15:36 +08:00
ibuler 99ce82a6a0 perf: build 2024-08-01 16:15:16 +08:00
wangruidong ec95d25704 perf: Remove applets, no longer display remote application connection methods 2024-08-01 15:59:00 +08:00
Eric 7c6e83d124 perf: reformat code 2024-07-31 15:09:53 +08:00
ibuler ad5e88f1e3 perf: display migrate log 2024-07-31 15:09:33 +08:00
wangruidong b1e958d806 fix: stop job failed 2024-07-30 18:53:16 +08:00
feng 8506ae9edd perf: When account push change secret windows only modify the type equal to password 2024-07-30 18:33:42 +08:00
wangruidong ceb2a9bb17 fix: Arbitrary File Read in Ansible Play 2024-07-30 18:19:01 +08:00
feng 8d83c953d3 perf: Support WeCom DingTalk FeiShu Lark Slack attribute mapping 2024-07-30 17:48:26 +08:00
Eric 9825f9fbd2 perf: Check if CORE_HOST should ignore SSL 2024-07-30 16:57:04 +08:00
feng 41b2ce06a8 perf: Approval process role selection supports multiple strategies 2024-07-30 16:06:01 +08:00
feng 920cfdac5c perf: Saml2 callback url miss port 2024-07-26 18:17:40 +08:00
Bai 8abf7876cc perf: graceful restart gunicorn worker timeout 30 2024-07-26 14:05:27 +08:00
wangruidong 2e625f2c33 feat: add assets amount field to platform page 2024-07-26 13:45:05 +08:00
halo 88037b2038 perf: Email service authentication username is optional 2024-07-26 11:23:15 +08:00
Bai 457021040a perf: Modifying the label matching logic of an AppletHost (random) 2024-07-25 19:04:57 +08:00
fit2bot 4887b21d35
fix: message publish_task args,kwargs can json encode (#13797)
* fix: message publish_task args,kwargs can json encode

* perf: Update Dockerfile with new base image tag

---------

Co-authored-by: wangruidong <940853815@qq.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-24 15:45:27 +08:00
fit2bot 03a66fd563
perf: Modify error message for desktop client login (#13763)
* perf: Modify error message for desktop client login

* perf: Update Dockerfile with new base image tag

---------

Co-authored-by: wangruidong <940853815@qq.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-24 10:59:54 +08:00
fit2bot ef656a8dfd
perf: change docker file build (#13761)
* perf: change docker file build

* perf: Update Dockerfile with new base image tag

---------

Co-authored-by: ibuler <ibuler@qq.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-07-23 16:38:00 +08:00
Eric 5e45129e32 perf: add luna i18n 2024-07-23 15:40:32 +08:00
feng ea64b01da6 perf: You can modify sudo permissions multiple times 2024-07-22 17:27:20 +08:00
feng c3b863c2be perf: You can modify sudo permissions multiple times 2024-07-22 17:27:20 +08:00
feng 6a7896b712 perf: Gpt3 to gpt-4o-mini 2024-07-19 11:56:07 +08:00
feng 83c1f8e4d3 perf: The gateway password contains ! Password parsing failed 2024-07-19 10:41:54 +08:00
Bai 9d3fdd37a3 perf: user authentication supports configuration redirection 2024-07-19 10:37:52 +08:00
Bai 419195895e perf: update readme 2024-07-18 19:43:38 +08:00
feng c92188887d perf: Create authorization to add template account Push account parameters 2024-07-18 19:15:46 +08:00
feng dcfc4e6e7b perf: The locked IP shows the username + translate 2024-07-17 18:10:22 +08:00
feng 836adab5d0 perf: Feishu lark support attributes settings 2024-07-17 16:59:57 +08:00
wangruidong e93227a53c fix: The asset cannot be obtained during online synchronization 2024-07-17 15:52:40 +08:00
fit2bot d6f6bb9c1b
fix: session viewset api permission validation (#13750)
* fix: session viewset api permission validation

* fix: some api permission validation

---------

Co-authored-by: Bai <baijiangjie@gmail.com>
2024-07-17 15:35:34 +08:00
feng 85825165fc perf: Translate 2024-07-17 11:37:19 +08:00
fit2bot 66047c7926
perf: Migrate (#13741)
Co-authored-by: feng <1304903146@qq.com>
2024-07-17 10:18:53 +08:00
Bai 456bcd2d3f fix: i18n error 2024-07-17 10:01:21 +08:00
Bai 259f68a806 fix: i18n error 2024-07-17 09:54:47 +08:00
feng 4e6231ab19 perf: Notification remove kael magnus 2024-07-16 19:34:18 +08:00
fit2bot d7bbfdcce6
perf: Translate (#13731)
Co-authored-by: feng <1304903146@qq.com>
2024-07-16 18:38:47 +08:00
吴小白 a0cc9e5db5 fix: deploy applet host 2024-07-16 12:49:33 +08:00
wangruidong ea6cd853de perf: 社区版移除magnus 2024-07-16 10:40:33 +08:00
fit2bot 53a388a7e0
fix: View user perms bug (#13721)
Co-authored-by: feng <1304903146@qq.com>
2024-07-15 17:50:37 +08:00
fit2bot 13b1938efb
perf: Community supports custom platforms (#13719)
Co-authored-by: feng <1304903146@qq.com>
2024-07-15 17:31:44 +08:00
ibuler 6677985e4a perf: support user email login 2024-07-15 16:23:52 +08:00
ibuler cfa1034161 perf: community add postgre support 2024-07-15 16:19:24 +08:00
ibuler 815973fb63 perf: split user model to many file 2024-07-15 10:54:17 +08:00
吴小白 92d369aaca perf: remove receptor 2024-07-12 18:38:26 +08:00
jiangweidong 281a2d9679 fix: custom sms send success but prompt fails 2024-07-12 18:37:46 +08:00
feng e9f4615caa perf: Optimize the password reset page experience for new users (the password field will be lengthened) 2024-07-12 15:17:49 +08:00
jiangweidong c0d2efa72a perf: async sms task params can json 2024-07-12 15:16:41 +08:00
gerry-fit 247f4d5c19 perf: Enterprise Edition Hide Footer Copyright Content 2024-07-11 16:10:42 +08:00
fit2bot 29c29b17d4
perf: Translate (#13686)
Co-authored-by: feng <1304903146@qq.com>
2024-07-10 19:03:19 +08:00
wangruidong 5608f7d20d fix: 定时清理任务不生效问题 2024-07-10 16:13:47 +08:00
Bai aa8ae36255 perf: README 2024-07-10 14:55:46 +08:00
feng 2292e6f2eb perf: save_passwd_change filter user source local and passwords not emtpy 2024-07-10 14:20:33 +08:00
fit2bot bf82a1c721
fix: Operator write failed (#13677)
Co-authored-by: feng <1304903146@qq.com>
2024-07-10 11:24:26 +08:00
Bryan 8ef84bbc03 Update README.md 2024-07-10 11:13:42 +08:00
fit2bot e36d51cc0b
perf: country code api (#13672)
* perf: remove notification migrations

* perf: country code api

---------

Co-authored-by: ibuler <ibuler@qq.com>
2024-07-09 19:23:41 +08:00
feng 5c1d0238e1 39.102.214.101 ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIOzDdXgVjgKrT+ZF5DXcNZqJnkjwvt0M5FbVpvbTOU/v
perf: save_passwd_change filter user source local and passwords not emtpy
2024-07-09 19:08:22 +08:00
wangruidong c6befe4c4b fix: creat linux asset protocol default value is sftp 2024-07-09 19:04:19 +08:00
Bai 5a57c296a1 feat: add db table data analyzer util 2024-07-09 18:49:51 +08:00
wangruidong 34ddfd24be fix: import role template csv failed 2024-07-09 18:15:44 +08:00
wangruidong 39051ef0fd fix: import role template csv failed 2024-07-09 17:04:59 +08:00
fit2bot ddd813241c
perf: JobExecutionViewSet add SECURITY_COMMAND_EXECUTION permission (#13662)
Co-authored-by: feng <1304903146@qq.com>
2024-07-09 16:34:15 +08:00
mmagi 60f7cbef9a fix: 主机硬件信息硬盘大小避免多次挂载重复计入 2024-07-09 15:52:15 +08:00
wangruidong 4adc981a21 perf: update date_updated when update user roles 2024-07-09 15:51:15 +08:00
mmagi c42913c15e fix: win主机硬件信息内存单位与其他主机一致;cpu信息字段与其他主机一致 2024-07-09 15:49:35 +08:00
halo bb6d60b46d perf: 优化创建子节点时锁置后 2024-07-09 15:15:06 +08:00
fit2bot afe7f03c16
perf: login style change (#13539)
* perf: login style change

* perf: login style change

* perf: login style change

---------

Co-authored-by: zhaojisen <1301338853@qq.com>
2024-07-09 15:02:37 +08:00
fit2bot ba8d3be9a6
fix: Operatelog plaintext storage AKSK (#13506)
* fix: Operatelog plaintext storage AKSK

* perf: Encrypt some field when saving operatelog

* fix: Operatelog plaintext storage AKSK

---------

Co-authored-by: jiangweidong <1053570670@qq.com>
2024-07-09 14:52:00 +08:00
Eric d14d8869ac perf: add connection options for mongodb 2024-07-09 14:00:59 +08:00
wangruidong 2f7391efc3 perf: modify migrations 2024-07-09 11:38:47 +08:00
ibuler 75fa96b29c perf: remove notification migrations 2024-07-09 11:25:49 +08:00
maninhill c56ab9bc1e chore: Update README.zh-CN.md 2024-07-09 11:11:20 +08:00
fit2bot 443e492fd4
perf: Asset type cloud add community version (#13640)
Co-authored-by: feng <1304903146@qq.com>
2024-07-09 10:59:56 +08:00
ibuler b8c223d525 perf: can set xpack disable force 2024-07-09 10:56:20 +08:00
吴小白 a509afe24b fix: FromAsCasing keywords 2024-07-09 10:35:59 +08:00
fit2bot 9654add528
perf: Translate (#13633)
Co-authored-by: feng <1304903146@qq.com>
2024-07-08 15:43:56 +08:00
Bryan d0a9409078 Update README.md 2024-07-08 14:51:07 +08:00
fit2bot 5836583490
fix: The account gather results do not have the last login time (#13625)
Co-authored-by: feng <1304903146@qq.com>
2024-07-08 11:42:24 +08:00
fit2bot 57d689bee6
perf: Translate (#13620)
Co-authored-by: feng <1304903146@qq.com>
2024-07-05 18:09:39 +08:00
ZhaoJiSen 8a3fb6bd4d
Merge pull request #13616 from jumpserver/pr@dev@translate
perf: Translate
2024-07-05 16:50:00 +08:00
feng 78bd3f581a perf: Translate 2024-07-05 16:36:55 +08:00
fit2bot d07c476507
perf: Translate (#13612)
Co-authored-by: feng <1304903146@qq.com>
2024-07-04 18:14:34 +08:00
fit2bot 50d196eda4
perf: Job api add filter options (#13610)
Co-authored-by: feng <1304903146@qq.com>
2024-07-04 16:03:51 +08:00
ibuler 823d9af91d perf: upgrade to v4, more international and more standardized. 2024-07-04 10:06:43 +08:00
Bryan 3731123369 Update README.md 2024-07-04 09:47:56 +08:00
Bryan 1a68c4b44a Update README.md 2024-07-04 09:47:56 +08:00
Bryan 0f79006b59 Update README.md 2024-07-04 09:47:56 +08:00
maninhill c95ad5a31c chore: Update README.md 2024-07-04 09:44:01 +08:00
maninhill e25a96d359 chore: Update README.md 2024-07-03 22:56:08 +08:00
maninhill 04284adc87 chore: Update README.md 2024-07-03 22:40:32 +08:00
Bryan 02fc045370
Merge pull request #13600 from jumpserver/dev
v4.0.0
2024-07-03 19:04:35 +08:00
maninhill 7ee7d50f22 chore: Update README.md 2024-07-03 18:54:56 +08:00
fit2bot 3d015398c3
perf: Luna translate (#13599)
Co-authored-by: feng <1304903146@qq.com>
2024-07-03 17:50:55 +08:00
wangruidong da8b328f80 fix: bulk delete playbook 500 error 2024-07-03 17:15:50 +08:00
fit2bot 82a6702c90
perf: Translate (#13594)
Co-authored-by: feng <1304903146@qq.com>
2024-07-03 16:50:09 +08:00
fit2bot ad267bcd35
perf: Translate (#13593)
Co-authored-by: feng <1304903146@qq.com>
Co-authored-by: feng626 <57284900+feng626@users.noreply.github.com>
2024-07-03 16:42:02 +08:00
maninhill 15dc922bca chore: Update README.md 2024-07-03 16:10:03 +08:00
Aaron3S 22405d46d6 feat: add chen translate 2024-07-03 15:54:19 +08:00
wangruidong 35b0741068 fix: modify render_to_json rbac 2024-07-03 15:53:25 +08:00
刘瑞斌 d7b8174fd0 chore: use unseq list 2024-07-03 15:35:14 +08:00
ibuler 43cfb11bca perf: tag export format use name:value style 2024-07-03 15:34:53 +08:00
wangruidong f955cebaa0 perf: Translate 2024-07-03 15:17:10 +08:00
fit2bot 5d7ec054e6
perf: Community limit (#13584)
Co-authored-by: feng <1304903146@qq.com>
2024-07-03 15:01:37 +08:00
Bryan 6088a38eed Update README.md 2024-07-03 14:51:51 +08:00
fit2bot e1a84e76bb
perf: some translation (#13585)
* perf: applet host platform

* perf: some translation

---------

Co-authored-by: ibuler <ibuler@qq.com>
2024-07-03 14:51:21 +08:00
wangruidong 19f9179e7f perf: update migrations same with v3 2024-07-03 14:46:17 +08:00
Bryan aa4a8d5b42 Update README.md 2024-07-03 14:44:28 +08:00
老广 10ba31086c Update README.md 2024-07-03 14:40:49 +08:00
fit2bot fa8312bc65
perf: Translate (#13575)
Co-authored-by: feng <1304903146@qq.com>
2024-07-02 18:30:23 +08:00
maninhill 512e727dd4 chore: Update CONTRIBUTING.md 2024-07-02 18:25:57 +08:00
wangruidong a529609275 fix: Resolve issue with update permissions preventing data import 2024-07-02 16:34:10 +08:00
fit2bot a8973330fe
fix: Account tempale cannot push params (#13571)
Co-authored-by: feng <1304903146@qq.com>
2024-07-02 16:12:27 +08:00
ibuler d42acc3848 perf: applet host platform 2024-07-02 15:15:13 +08:00
fit2bot 912cefbc85
perf: Lina LoginLogTotal translate (#13569)
Co-authored-by: feng <1304903146@qq.com>
2024-07-02 15:10:33 +08:00
feng 2bb475d0ce perf: Account push log optimization 2024-07-02 14:55:38 +08:00
ibuler 22788ff2da perf: remove org api scope 2024-07-02 14:11:16 +08:00
fit2bot 5594b25ae0
perf: Login confirm return failed (#13560)
Co-authored-by: feng <1304903146@qq.com>
2024-07-02 11:02:30 +08:00
Aaron3S 4733d89807 perf: 优化 chen 翻译 2024-07-02 10:19:36 +08:00
wangruidong c718fe1a9d perf: modify user login ACL msg 2024-07-01 19:30:42 +08:00
wangruidong 237b4a82c9 fix: handle 500 error when re-binding DingTalk user to another user 2024-07-01 18:03:47 +08:00
fit2bot 76e0cbb8ac
perf: update lion i18n (#13556)
* perf: update lion i18n

* perf: update i18n

---------

Co-authored-by: Eric <xplzv@126.com>
2024-07-01 16:22:46 +08:00
fit2bot b3a670d380
perf: Lina mfa translate (#13555)
Co-authored-by: feng <1304903146@qq.com>
Co-authored-by: feng626 <57284900+feng626@users.noreply.github.com>
2024-07-01 16:12:13 +08:00
wangruidong db243d050e fix: playbook FileNotFoundError 2024-07-01 15:51:14 +08:00
wangruidong cd2648291e perf: Translate 2024-07-01 15:15:53 +08:00
wangruidong 4a49bde1f0 perf: add compatibility for macOS environment 2024-07-01 15:02:32 +08:00
wangruidong d9754496d0 perf: add bubblewrap 2024-07-01 15:02:32 +08:00
fit2bot 6753b5fd19
perf: Translate (#13550)
Co-authored-by: feng <1304903146@qq.com>
2024-07-01 11:42:33 +08:00
fit2bot aeb320ba30
perf: Lina translate (#13548)
Co-authored-by: feng <1304903146@qq.com>
2024-07-01 10:15:06 +08:00
ibuler e712e8ccfc perf: ansible version and set user lang 2024-06-28 18:59:44 +08:00
fit2bot 1d6f827296
perf: Migrate (#13540)
Co-authored-by: feng <1304903146@qq.com>
2024-06-28 18:36:24 +08:00
ibuler 772c9b385c perf: lang setting from core 2024-06-28 16:40:25 +08:00
wangruidong f5053728e7 perf: Translate Tags 2024-06-28 15:28:57 +08:00
wangruidong f67fd29499 perf: Community update user list API to exclude specific fields 2024-06-28 14:54:07 +08:00
fit2bot 138ea35620
fix: Got perm tree 500 (#13533)
Co-authored-by: feng <1304903146@qq.com>
2024-06-28 11:39:09 +08:00
wangruidong bf56549f01 perf: Task log optimize 2024-06-28 10:25:10 +08:00
Eric 908181af64 perf: clean mp4 replay file
perf: refactor code to clean files
2024-06-27 18:12:37 +08:00
fit2bot 7b4d3c44f8
fix: Asset perm calculate failed (#13530)
Co-authored-by: feng <1304903146@qq.com>
Co-authored-by: feng626 <57284900+feng626@users.noreply.github.com>
2024-06-27 18:05:08 +08:00
feng b7a6454d65 fix: Asset perm calculate failed 2024-06-27 17:56:41 +08:00
ibuler 6d81fa7fdf perf: change default login title 2024-06-27 17:55:57 +08:00
wangruidong 0e8833cce3 perf: Translate Client connection 2024-06-27 11:27:43 +08:00
fit2bot 24d9e65532
fix: Asset 003 migrate failed (#13519)
Co-authored-by: feng <1304903146@qq.com>
2024-06-26 21:42:43 +08:00
ibuler bca9bdf619 perf: translate some word 2024-06-26 19:29:56 +08:00
fit2bot cd39e20808
perf: Applet host provider add filterset (#13517)
Co-authored-by: feng <1304903146@qq.com>
2024-06-26 19:07:28 +08:00
fit2bot 9c8680d3f4
perf: Translate (#13514)
Co-authored-by: feng <1304903146@qq.com>
2024-06-26 17:06:23 +08:00
wangruidong dd84ca8f85 fix: Virtualapp rbac config 2024-06-26 16:43:32 +08:00
Eric 96c1f689c0 perf: modify dbeave remoteapp dislay name 2024-06-26 16:19:09 +08:00
wangruidong 84855bfd7e perf: Translate Lark 2024-06-26 16:13:16 +08:00
fit2bot 40c5a218a9
perf: Translate (#13509)
Co-authored-by: feng <1304903146@qq.com>
Co-authored-by: feng626 <57284900+feng626@users.noreply.github.com>
2024-06-26 15:18:37 +08:00
wangruidong 8e87972a76 perf: Translate ticket action 2024-06-26 14:37:32 +08:00
fit2bot 3faee9b80c
perf: change some translate (#13505)
* perf: some word translate


---------

Co-authored-by: ibuler <ibuler@qq.com>
2024-06-25 19:36:35 +08:00
fit2bot 5a1389a187
perf: Translate (#13504)
Co-authored-by: feng <1304903146@qq.com>
2024-06-25 19:10:32 +08:00
Eric 565c2f493c perf: add lion i18n 2024-06-25 19:04:40 +08:00
Bai 8d48593fc4 perf: Update README 2024-06-25 16:44:00 +08:00
fit2bot b50c96fcd6
perf: Update README (#13497)
* perf: Update README

* perf: Update README

* perf: Update README

---------

Co-authored-by: Bai <baijiangjie@gmail.com>
2024-06-25 16:29:14 +08:00
ibuler 85700a2a26 perf: some word translate 2024-06-25 15:36:25 +08:00
Bryan 66615b7dd3 Update README.md 2024-06-25 15:34:31 +08:00
Bryan 2c1a1fa31e Update README.md 2024-06-25 15:34:31 +08:00
wangruidong bbc442b56e perf: Translate CanDragSelect tips 2024-06-25 15:31:30 +08:00
Bryan 1ca579f4f0 Update README.md 2024-06-25 15:01:47 +08:00
Bryan 9e3b23179c Update README.md 2024-06-25 15:01:47 +08:00
Bryan 9fd861d047 Update README.md 2024-06-25 15:01:47 +08:00
fit2bot 4abfcb27d1
perf: Update README (#13491)
* perf: Update README

* perf: Update README

* perf: Update README

* perf: Update README

* perf: Update README

---------

Co-authored-by: Bai <baijiangjie@gmail.com>
Co-authored-by: Bryan <jiangjie.bai@fit2cloud.com>
2024-06-25 11:22:38 +08:00
老广 3463761693 Update README.md 2024-06-25 10:28:14 +08:00
Eric c311adc1da chore: update mysqlclient 2.2.4 2024-06-24 20:12:09 +08:00
ibuler ee258707c8 perf: change initial passwd to ChangeMe 2024-06-24 20:11:49 +08:00
Eric 17d96669fe perf: remove pymysql 2024-06-24 20:11:23 +08:00
fit2bot 3fade107d5
perf: Translate (#13489)
Co-authored-by: feng <1304903146@qq.com>
Co-authored-by: feng626 <57284900+feng626@users.noreply.github.com>
2024-06-24 20:10:34 +08:00
wangruidong f91ec6fa6a perf: favor & disfavor trans 2024-06-24 19:38:19 +08:00
Bai dfff41e9d6 perf: Update README 2024-06-24 19:25:41 +08:00
Bai 478e81b8fa perf: Update README 2024-06-24 19:25:41 +08:00
wangruidong 9b14f2aa1f perf: ftp log has_file trans 2024-06-24 19:18:26 +08:00
Bryan 18e648af6e
Update README.md (#13481)
* Update README.md

* perf: Update README

* perf: Update README

* perf: Update README

* perf: Update README

* perf: Update README

* perf: Update README

* perf: Update README

* perf: Update README

* perf: Update README

* perf: Update README

* perf: Update README

* perf: Update README

* perf: Update README
2024-06-24 19:16:30 +08:00
老广 45bd69585a Update README.md 2024-06-24 18:24:21 +08:00
maninhill 42a0cde450 chore: Update README.md 2024-06-24 18:22:38 +08:00
Bai a9ef21ea3f fix: poetry lock 2024-06-24 17:07:34 +08:00
Bai 13d24a12db fix: i18n messages 2024-06-24 17:07:34 +08:00
wangruidong 2bd09f246d fix: raise http 400 when batch delete in component settings 2024-06-24 16:25:54 +08:00
fit2bot 23c81cf5eb
perf: Migrate asset dameng json (#13477)
Co-authored-by: feng <1304903146@qq.com>
2024-06-24 16:24:40 +08:00
Bryan e95284335e
Merge pull request #13472 from jumpserver/v4
Merge v4 to dev
2024-06-24 15:50:29 +08:00
Bai 1c7f82e65a Merge v4 to dev (Update poetry lock) 2024-06-24 15:47:13 +08:00
Bai dfde50c768 Merge v4 to dev 2024-06-24 15:43:40 +08:00
ibuler 8bfbebf29e Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-06-24 14:51:42 +08:00
ibuler 8157f9891f perf: 优化批量删除判断 2024-06-24 14:50:53 +08:00
wangruidong ad95adc833 perf: trans LDAP msg 2024-06-24 14:24:06 +08:00
ibuler f7e55c9b89 merge: with remote 2024-06-24 11:06:32 +08:00
ibuler 11b125655d perf: passkey help msg 2024-06-24 11:05:41 +08:00
fit2bot c6628a1959
perf: Translate (#13471)
Co-authored-by: feng <1304903146@qq.com>
2024-06-24 10:57:10 +08:00
fit2bot 165d030c8e
perf: ansible runner in isolated mode (#13434)
perf: use new ansible runner

perf: change lock

Co-authored-by: ibuler <ibuler@qq.com>
2024-06-24 10:21:31 +08:00
feng 9be77cf58f perf: Ansible inventory set jms 2024-06-24 10:15:05 +08:00
吴小白 887724bad4 feat: upgrade poetry.lock 2024-06-24 10:11:49 +08:00
fit2bot ae7dbbedcc
perf: Edit rbac perms (#13468)
Co-authored-by: feng <1304903146@qq.com>
Co-authored-by: feng626 <57284900+feng626@users.noreply.github.com>
2024-06-21 19:08:37 +08:00
fit2bot 407a77f61b perf: trans StopLogOutput 2024-06-21 18:05:39 +08:00
fit2bot e06f9a03d6
perf: System setting perm (#13463)
Co-authored-by: feng <1304903146@qq.com>
2024-06-20 19:19:14 +08:00
fit2bot 07edbea54e
perf: Update ah translate (#13459)
Co-authored-by: feng <1304903146@qq.com>
2024-06-20 16:56:41 +08:00
ibuler 856e501a15 Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-06-20 11:11:19 +08:00
ibuler 8cf900f9de perf: 生产授权树 2024-06-20 11:10:57 +08:00
fit2bot a54605ac79
perf: Translate (#13454)
Co-authored-by: feng <1304903146@qq.com>
2024-06-19 19:36:47 +08:00
Bryan e4ac73896f
Merge pull request #13452 from jumpserver/dev
v3.10.11-lts
2024-06-19 16:01:26 +08:00
Bai b283d88781 fix: Clone asset with accounts 2024-06-19 16:00:58 +08:00
wangruidong 92790d711e perf: Add log download button 2024-06-19 15:56:02 +08:00
gerry-fit 2977323800 perf: 登录重置密码传输进行加密 2024-06-19 14:53:50 +08:00
fit2bot 5b548d8d57
perf: Translate (#13450)
Co-authored-by: feng <1304903146@qq.com>
2024-06-19 14:48:48 +08:00
wangruidong 4a520e9e10 fix: 全局组织,添加标签报错 2024-06-19 09:27:03 +08:00
fit2bot afdf777386
perf: Translate account (#13445)
Co-authored-by: feng <1304903146@qq.com>
2024-06-18 19:39:27 +08:00
ibuler cd2af0dcf7 perf: english traslation 2024-06-18 18:47:06 +08:00
wangruidong 44f29e166c fix: 一些任务查找不到id和执行者 2024-06-18 16:52:18 +08:00
fit2bot f42113afb9
fix: Fixed the issue of user login statistics (#13440)
Co-authored-by: feng <1304903146@qq.com>
2024-06-18 14:18:02 +08:00
Bai 523468f7af fix: Add API Exception traceback log if settings.DEBUG_DEV enabled 2024-06-18 11:58:44 +08:00
Bai 9385d04812 fix: Add API Exception traceback log if settings.DEBUG_DEV enabled 2024-06-18 11:55:56 +08:00
Bai ff126f3459 fix: delete account error (DoesNotExist) 2024-06-18 11:06:40 +08:00
fit2bot 2ee435a8ec
perf: Translate (#13438)
Co-authored-by: feng <1304903146@qq.com>
2024-06-17 19:47:05 +08:00
fit2bot f3a827b76b
perf: Translate (#13437)
Co-authored-by: feng <1304903146@qq.com>
2024-06-17 19:22:45 +08:00
fit2bot 50ceca9f06
perf: Perms system settings (#13435)
Co-authored-by: feng <1304903146@qq.com>
2024-06-17 17:40:03 +08:00
Bai 8a5e86dfa7 fix: migrations assets 0003 json.loads error 2024-06-17 10:39:38 +08:00
fit2bot 6ffae48ab2
perf: Translate (#13431)
Co-authored-by: feng <1304903146@qq.com>
2024-06-14 19:15:41 +08:00
wangruidong 66cd6e95a8 fix: 获取账号改密的任务列表超时 2024-06-14 18:54:01 +08:00
wangruidong b28aec527f perf: 默认关闭作业中心 2024-06-14 18:18:35 +08:00
fit2bot 9ff78c8569
perf: Lina translate (#13427)
Co-authored-by: feng <1304903146@qq.com>
2024-06-14 15:16:00 +08:00
fit2bot d6718d7b78
perf: Device asset remove_account_enabled false (#13426)
Co-authored-by: feng <1304903146@qq.com>
2024-06-14 14:47:13 +08:00
fit2bot 32966b260a
perf: Refactor OperateLogStore separator logic for database compatibility (#13424)
Co-authored-by: feng <1304903146@qq.com>
Co-authored-by: feng626 <57284900+feng626@users.noreply.github.com>
2024-06-14 14:25:14 +08:00
feng 6c59888d77 perf: Refactor OperateLogStore separator logic for database compatibility 2024-06-14 14:09:53 +08:00
Bai 1c1d839b82 fix: i18n compilemessages 2024-06-14 09:53:08 +08:00
wangruidong 7d295cc675 perf: rbac applet modify translate 2024-06-13 18:26:10 +08:00
fit2bot 75496cbe91
perf: Account backup failed (#13420)
Co-authored-by: feng <1304903146@qq.com>
2024-06-13 18:20:00 +08:00
jiangweidong 496903dfb2 fix: 解决获取用户登录后端的session_key有两种的问题 2024-06-13 17:49:56 +08:00
wangruidong 11f6a029de perf: modify translate 2024-06-13 17:45:39 +08:00
Bai e40c66c7ed fix: select_for_update error for out join sql 2024-06-13 15:50:11 +08:00
ibuler 2a33337963 Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-06-13 13:04:07 +08:00
ibuler bd1a768743 perf: change some translation 2024-06-13 13:02:03 +08:00
wangruidong 0a0312695b fix: es使用https报错 2024-06-13 10:33:47 +08:00
fit2bot 0c0ec098ae
perf: Modify some translations (#13412)
Co-authored-by: wangruidong <940853815@qq.com>
2024-06-12 19:38:45 +08:00
fit2bot 37ad7b32e4
perf: Cloud account translate (#13413)
Co-authored-by: feng <1304903146@qq.com>
2024-06-12 19:38:07 +08:00
ibuler 2640963938 Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-06-12 19:29:14 +08:00
ibuler 6bc9181c25 fix: some bugs 2024-06-12 19:25:36 +08:00
fit2bot d8379195e6
perf: Platform automation add remove account method (#13411)
Co-authored-by: feng <1304903146@qq.com>
2024-06-12 19:23:40 +08:00
Bai 9195c658a0 perf: Update djangojs.po file 2024-06-12 18:36:04 +08:00
wangruidong 3fb261b5c8 fix: Role details - multiple instances of English in permissions list 2024-06-12 17:30:03 +08:00
ibuler aa16c3d3a1 Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-06-12 16:19:26 +08:00
ibuler 7be6cf2b73 perf: tags update 2024-06-12 16:19:16 +08:00
wangruidong 3608b025e5 fix: es8会话记录查询不到命令 2024-06-12 15:49:57 +08:00
fit2bot 60738da053
perf: Automation remove account task fail (#13406)
Co-authored-by: feng <1304903146@qq.com>
2024-06-12 15:30:52 +08:00
Aaron3S 507ad10389 feat: add some translations for chen 2024-06-12 15:27:53 +08:00
Bai 68244b2b37 perf: 更新 lock 文件 2024-06-12 14:30:37 +08:00
wangruidong 948e9ecb4b perf: 命令存储支持ES8的版本 2024-06-12 14:15:13 +08:00
wangruidong 67bc16238c perf: i18n 2024-06-12 10:25:22 +08:00
wangruidong 7ad4d9116a fix: LDAP定时同步任务设置多个通知人,消息内容分除第一个正常,其它人都不正常 2024-06-11 18:24:43 +08:00
Aaron3S db88f6c9b4 perf: 优化 chen 翻译文件 2024-06-11 18:19:30 +08:00
fit2bot 8b7f60d43e
fix: Cloud sync related issues (#13396)
Co-authored-by: feng <1304903146@qq.com>
2024-06-11 17:42:13 +08:00
wangruidong 9439035b86 fix: 账号备份,云同步定时任务不执行 2024-06-07 18:33:46 +08:00
halo 2b220d3753 perf: 去掉account序列化中params属性 2024-06-07 15:54:33 +08:00
ibuler cd1f6a9137 Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-06-06 16:56:47 +08:00
ibuler 7973d066a3 revert: asset permission real accounts serializer 2024-06-06 16:56:07 +08:00
Bai 440a7ae9cc perf: 添加配置项 FILE_UPLOAD_TEMP_DIR 2024-06-06 16:32:23 +08:00
wangruidong ad65097a8f perf: Crontab i18n 2024-06-06 14:49:56 +08:00
ibuler 1b05f56598 Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-06-05 19:34:04 +08:00
ibuler 3468f8cd40 perf: 修改授权的账号 2024-06-05 19:33:40 +08:00
Bryan 5c81e974cd
Update README.md 2024-06-05 18:00:13 +08:00
Bryan b638cf7417
Update README.md 2024-06-05 17:53:26 +08:00
Bryan 1db1961cc0
Update README.md 2024-06-05 17:25:45 +08:00
Bryan 811afdcf1a
Update README.md 2024-06-05 17:25:12 +08:00
Bryan 1f87ce2a47
Update README.md 2024-06-05 17:09:04 +08:00
Bryan 8213e38e6a
Update README.md 2024-06-05 17:01:31 +08:00
ibuler 263bcbb566 Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-06-04 19:08:51 +08:00
ibuler 050ddc88f2 perf: labels 支持颜色 2024-06-04 19:08:16 +08:00
Bai 40a4efc992 fix: 修复用户登录报错刷新浏览器后依旧报错的问题(登录超时,请重新登录) 2024-06-04 16:33:06 +08:00
feng 38e8791d9f perf: Community Edition Remove db client 2024-06-04 16:24:37 +08:00
老广 15d4fafbdb chrome: change github action 2024-06-04 16:23:25 +08:00
fit2bot deb8474c1b
feat: add oracle database web-cli connect method (#13358)
Co-authored-by: Aaron3S <chenyang@fit2cloud.com>
2024-06-04 14:51:47 +08:00
fit2bot 12740ead08
perf: ticket translate (#13357)
Co-authored-by: feng <1304903146@qq.com>
2024-06-04 11:01:33 +08:00
Bai 6322559bd7 perf: i18n updated 2024-06-03 19:15:40 +08:00
Aaron3S 6c5eb00fb6 feat: 增加 chen 翻译文件 2024-06-03 16:42:23 +08:00
feng dad2f8eb65 perf: koko translate 2024-06-03 14:29:57 +08:00
Bai c8679f48f5 perf: Update i18n 2024-06-03 11:44:16 +08:00
fit2bot 510dc1eaf2
perf: translate (#13347)
Co-authored-by: feng <1304903146@qq.com>
2024-06-03 10:26:12 +08:00
wangruidong a313753757 perf: action i18n 2024-05-31 16:34:03 +08:00
Gerry.tan 48b037ac26 feat: 支持 Dameng 数据库 2024-05-31 14:45:41 +08:00
wangruidong 53f106b30d perf: i18n 2024-05-31 14:39:56 +08:00
jiangweidong dfd133cf5a
perf: optimize user operation logs (#13221) 2024-05-31 11:05:35 +08:00
吴小白 0d27bfcfa9 perf: 添加 arm64 缺失依赖 2024-05-31 10:56:48 +08:00
jiangweidong cdfb11549e fix: 解决OAuth2可以跳过不存在用户不允许登录的规则 2024-05-31 10:43:01 +08:00
wangruidong ba6660216c perf: celery task log format 2024-05-31 10:15:11 +08:00
吴小白 3536af2051 perf: 按要求移除重复构建代码 2024-05-31 10:13:22 +08:00
fit2bot 21bb0a8162
fix: translate json (#13322)
Co-authored-by: feng <1304903146@qq.com>
2024-05-30 14:20:12 +08:00
jiangweidong d718398791
feat: refactoring sync module (#13293) 2024-05-29 18:44:32 +08:00
fit2bot 0d825927e1
perf: Optimize GitHub labels and update related workflows (#13315)
* perf: Optimize GitHub labels and update related workflows

* perf: Optimize issue template

* perf: Optimize issue template

* Update 1_bug_report.yml

* Update 1_bug_report.yml

* Update 1_bug_report.yml

* Update 1_bug_report.yml

* Update 1_bug_report.yml

* Update 2_feature_request.yml

* Update 2_feature_request.yml

* Update 3_question.yml

* Update 3_question.yml

* Update 3_question.yml

* Update 1_bug_report.yml

* Update 2_feature_request.yml

* Update 1_bug_report_cn.yml

* Update 1_bug_report_cn.yml

* Update 2_feature_request_cn.yml

* Update 1_bug_report_cn.yml

* Update 1_bug_report_cn.yml

* Update 1_bug_report_cn.yml

* Update 3_question_cn.yml

* Update 1_bug_report_cn.yml

* Update 2_feature_request_cn.yml

* Update 3_question_cn.yml

* Update 2_feature_request_cn.yml

* Update 1_bug_report.yml

* Update 1_bug_report_cn.yml

* Update 2_feature_request.yml

* Update 3_question.yml

* perf: Optimize issue template

---------

Co-authored-by: Bai <baijiangjie@gmail.com>
Co-authored-by: Bryan <jiangjie.bai@fit2cloud.com>
2024-05-29 18:15:13 +08:00
吴小白 0b65e3ffda perf: 按要求移除重复构建代码 2024-05-28 18:50:11 +08:00
feng 91a1da57e9 perf: mfa interface optimization, mobile phone number can be empty 2024-05-28 17:27:17 +08:00
Bai 4e8d7df005 fix: v2->v3 The issue of authorized accounts displaying as empty when there are more than 10,000 authorization rules. 2024-05-28 16:09:12 +08:00
Bai 5d1829b998 fix: Disable the applet connection method when all applet hosts have is_active set to False 2024-05-28 11:07:40 +08:00
Bai 75df845024 perf: Remove dependency django-rest-swagger 2024-05-28 10:34:37 +08:00
Bai c103253867 perf: perm tree search 2024-05-27 18:05:21 +08:00
ibuler f95cbd6977 merge: with remote 2024-05-27 16:46:13 +08:00
ibuler f16ec02c40 perf: 修改翻译 2024-05-27 16:43:26 +08:00
wangruidong 0ea2339ad5 perf: notification i18n 2024-05-27 15:24:31 +08:00
feng 81da9e018a fix: windows sync remove account fail and applet deploy rbac perm error and job exection log admin auditor cannot view 2024-05-27 11:41:30 +08:00
Bai 8ebdd59e00 Merge branch 'v4_bain' into v4 2024-05-27 11:35:16 +08:00
Bai c4e30737a4 perf: i18n bai 2024-05-27 11:34:53 +08:00
ibuler f127aca5f8 Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-05-27 11:20:59 +08:00
ibuler 7333c8e094 perf: 修改 json 空格数量 2024-05-27 11:20:35 +08:00
Bai a1e9382275 perf: i18n bai 2024-05-27 11:13:13 +08:00
ibuler 097a6c5c5f perf: 修改 label 为 tag 2024-05-27 11:07:36 +08:00
fit2bot 4e023057cc
perf: ticket translate (#13291)
Co-authored-by: feng <1304903146@qq.com>
2024-05-27 11:00:54 +08:00
Bryan 7f90fccc4f perf: The label matching policy is configured with a random selection publisher 2024-05-27 10:26:35 +08:00
ibuler 4034e2152c Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-05-24 18:43:07 +08:00
ibuler e8d6c6b711 merge: with remote 2024-05-24 18:42:37 +08:00
Bai 43215d27c5 perf: migrations i18n 2024-05-24 14:54:56 +08:00
Bai e20db96331 Merge branch 'v4_baisse' into v4 2024-05-24 14:42:27 +08:00
Bai 564ad40b99 perf: i18n System Settings End 2024-05-24 14:41:28 +08:00
ibuler 32ef4c79da perf: 修改翻译 2024-05-23 19:00:28 +08:00
wangruidong af4f6ebb26 perf: dashboard i18n 2024-05-23 18:23:10 +08:00
wangruidong 33b688b021 perf: modify task log i18n 2024-05-23 18:12:52 +08:00
fit2bot b179770dbf
perf: del extra translate (#13274)
Co-authored-by: feng <1304903146@qq.com>
Co-authored-by: feng626 <57284900+feng626@users.noreply.github.com>
2024-05-22 19:24:25 +08:00
Bai e7f92ec0d7 merged: Merge to v4 (bai) 2024-05-22 18:12:35 +08:00
Bai 79449a8a02 perf: i18n System Settings -> Authentication-OIDC 2024-05-22 17:51:45 +08:00
fit2bot 4ebcba81e0
perf: dates_metrics api speed (#13266)
Co-authored-by: feng <1304903146@qq.com>
2024-05-22 15:25:38 +08:00
wangruidong 5616d31888 perf: CeleryTaskExecution保存时去掉无用参数 2024-05-22 14:04:11 +08:00
fit2bot f259509ef8
fix: notification migrate file (#13269)
Co-authored-by: feng <1304903146@qq.com>
2024-05-22 10:47:55 +08:00
fit2bot 82977f9023
perf: tickets notifications add default data migrate file (#13268)
Co-authored-by: feng <1304903146@qq.com>
2024-05-21 19:24:26 +08:00
Bai 4a5205c5ac perf: i18n System Settings -> Features 2024-05-21 16:11:13 +08:00
ibuler 714b4ef7f4 merge: with remote 2024-05-21 14:47:37 +08:00
ibuler df091f0ee1 perf: 添加 terminal 的 migrate 2024-05-21 14:44:48 +08:00
wangruidong 7037cf56ec perf: i18n 2024-05-21 10:47:15 +08:00
Eric f683d195e4 perf: update lina i18n 2024-05-20 19:06:28 +08:00
Bai 5ab55b823c perf: i18n System Settings -> General,Org,Notifications 2024-05-20 18:39:57 +08:00
吴小白 0f2c769e8d
Merge pull request #13255 from jumpserver/pr@v4@fix_docker_build
fix: 修正企业镜像缺失依赖
2024-05-20 15:02:56 +08:00
吴小白 1d53f292ae fix: 修正企业镜像缺失依赖 2024-05-20 14:57:15 +08:00
fit2bot a15335cac9
perf: lina ja translate (#13252)
Co-authored-by: feng <1304903146@qq.com>
2024-05-17 18:46:30 +08:00
wangruidong f33cf07859 perf: i18n 2024-05-17 18:30:19 +08:00
fit2bot bce55421ce
perf: MenuAccountTemplates zh translate (#13250)
Co-authored-by: feng <1304903146@qq.com>
2024-05-17 17:56:09 +08:00
fit2bot c3449cd6bc
perf: account translate (#13249)
Co-authored-by: feng <1304903146@qq.com>
2024-05-17 16:47:02 +08:00
ibuler 4e903ce19b Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-05-17 16:32:08 +08:00
ibuler 90826b358c perf: 修改翻译 2024-05-17 16:31:39 +08:00
吴小白 7d46aa9892 perf: 优化发布机部署 2024-05-17 15:22:16 +08:00
ibuler 49d2bd93b7 perf: merge with remote 2024-05-17 09:59:12 +08:00
ibuler 9f103a88d6 perf: 修改 org name 2024-05-17 09:58:12 +08:00
fit2bot ce33bdc370
perf: account related translate (#13241)
Co-authored-by: feng <1304903146@qq.com>
2024-05-16 19:39:03 +08:00
fit2bot cdf1f81c8a
perf: account automation translate (#13240)
Co-authored-by: feng <1304903146@qq.com>
2024-05-16 19:12:24 +08:00
Eric 79edff5fca perf: 支持 loki log 2024-05-16 19:00:47 +08:00
Bryan 1518f792d6
Merge pull request #13236 from jumpserver/dev
v3.10.10-lts
2024-05-16 16:04:07 +08:00
fit2bot a7316bc7c1
perf: translate (#13228)
Co-authored-by: feng <1304903146@qq.com>
2024-05-15 18:43:31 +08:00
jiangweidong 09f802b00d
perf: cloud sync module adjustment (#13197)
* perf: cloud sync module adjustment

* perf: cloud sync module adjustment
2024-05-14 10:36:17 +08:00
wangruidong a644b84bb1 perf: dashboard zh,ja,zh_hant i18n 2024-05-13 18:31:54 +08:00
吴小白 b6f48111e3 feat: 更新 Dockerfile 2024-05-13 18:25:06 +08:00
wangruidong 3a6e4e7fb6 perf: file transfer boot step help tips i18n 2024-05-13 18:18:27 +08:00
wangruidong e42a98ff95 perf: celery task log css optimize 2024-05-13 18:16:36 +08:00
ibuler 8fe511cec6 perf: remove *.mo 2024-05-13 17:35:00 +08:00
Bai ffb3cd13cb perf: Delete locale dir 2024-05-13 17:26:38 +08:00
Bai b1abf8a339 perf: Merge local v4 2024-05-13 15:58:59 +08:00
ibuler 89d20c8a4d perf: 修改一些翻译 2024-05-13 15:28:11 +08:00
ibuler d66f923c0c perf: 修改翻译 2024-05-13 10:40:08 +08:00
ibuler d3c14428a1 perf: remove an or a 2024-05-13 10:35:21 +08:00
ibuler c104f85b18 perf: 修改翻译 2024-05-13 10:29:26 +08:00
fit2bot 755d8124ac
perf: account backup translate (#13198)
Co-authored-by: feng <1304903146@qq.com>
2024-05-11 19:48:15 +08:00
Bai a029cc8ed5 perf: i18n Personal Settings -> All sub menu 2024-05-11 18:55:03 +08:00
ibuler 111dfa8c29 perf: 修改大小写 2024-05-11 16:03:40 +08:00
ibuler 5f892c3afe perf: change i18n 2024-05-11 14:41:58 +08:00
fit2bot 313202fe41
perf: 合并 migrations (#13187)
* perf: 修改 Migrations

* perf: 合并 migrations

* perf: remove unuse

* perf: change to file

---------

Co-authored-by: ibuler <ibuler@qq.com>
2024-05-11 11:22:01 +08:00
Bai af1adc3baa perf: i18n Personal Settings -> All sub menu 2024-05-11 11:17:02 +08:00
ibuler be214c84d1 merge: with dev 2024-05-10 18:10:18 +08:00
fit2bot 082614e7b0
perf: A wave of migration Japan, Taiwan China font (#13188)
Co-authored-by: feng <1304903146@qq.com>
2024-05-10 15:13:40 +08:00
wangruidong 83835747c5 perf: i18n 2024-05-10 10:06:44 +08:00
Bai 2a7b48c83d perf: i18n Personal Settings -> Profile 2024-05-09 15:26:38 +08:00
ibuler a9068496d9 perf: 打算压缩 migratons 2024-05-09 11:01:01 +08:00
fit2bot 8bad88e798
perf: 优化账号相关翻译 (#13177)
Co-authored-by: feng <1304903146@qq.com>
2024-05-08 18:04:46 +08:00
吴小白 9f45eeeb1f fix: 优化构建缓存 2024-05-07 11:43:40 +08:00
吴小白 60110982f1 fix: 修正构建错误 2024-04-30 11:24:17 +08:00
ibuler 259204bfe2 Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-04-30 10:42:31 +08:00
wangruidong c55e9679db perf: dashboard i18n 2024-04-30 10:31:22 +08:00
ibuler c05a3c315a Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-04-29 15:07:25 +08:00
ibuler dbdf586f5b add i18n 2024-04-29 15:06:53 +08:00
Bai b1bd4db3e9 perf: Update poetry.lock 2024-04-29 11:47:18 +08:00
fit2bot 7806a13db5
feat: 默认数据库使用 PostgreSQL (#13088)
Co-authored-by: 吴小白 <296015668@qq.com>
Co-authored-by: Bryan <jiangjie.bai@fit2cloud.com>
2024-04-29 11:46:16 +08:00
Bai 928f564109 merge: into dev from v4: poetry lock file updated 2024-04-29 11:20:37 +08:00
Bai 328f718fe8 merge: into dev from v4: i18n file 2024-04-29 11:16:09 +08:00
Bai cb4402c610 merge: into dev from v4 2024-04-29 11:07:43 +08:00
feng626 fbc4cb9046
Revert "perf: remove ticket model" (#13145)
This reverts commit 94567b86f0.
2024-04-28 18:26:49 +08:00
feng 94567b86f0 perf: remove ticket model 2024-04-28 18:02:57 +08:00
ibuler 8aa707427f pref: remove user source choice 2024-04-28 16:01:09 +08:00
ibuler 7d64b8419f Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-04-28 14:04:55 +08:00
ibuler fad9249810 perf: 再次修改菜单 2024-04-28 14:04:28 +08:00
wangruidong bb4fbc3a1c perf: index page typo 2024-04-24 18:05:03 +08:00
ibuler d7916a62f0 perf: 修改翻译 2024-04-23 18:11:05 +08:00
ibuler da27e1b93c perf: 修改翻译 2024-04-23 14:16:21 +08:00
Bai 67277dd622 fix: 修复仪表盘会话排序数量都是 1 的问题 2024-04-22 19:42:33 +08:00
Bryan 82e7f020ea
Merge pull request #13094 from jumpserver/dev
v3.10.9 (dev to master)
2024-04-22 19:39:53 +08:00
ibuler 99b24cad00 perf: add open sans font 2024-04-22 15:08:28 +08:00
ibuler 9dbdd6ac60 perf: change i18n 2024-04-18 20:12:01 +08:00
Bryan f20b9e01ab
Merge pull request #13062 from jumpserver/dev
v3.10.8 dev to master
2024-04-18 18:01:20 +08:00
Bryan 8cf8a3701b
Merge pull request #13059 from jumpserver/dev
v3.10.8
2024-04-18 17:16:37 +08:00
ibuler f8953441e3 Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-04-17 14:09:25 +08:00
ibuler 5b41eddacc perf: 修改翻译 2024-04-17 13:49:43 +08:00
ibuler a432af1a6d perf: 修改翻译 2024-04-15 16:34:02 +08:00
吴小白 f987515b89 perf: 优化发布机日志输出 2024-04-15 12:04:26 +08:00
ibuler 2afabd65f9 Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-04-09 18:43:29 +08:00
ibuler 85cb80cbfe perf: remove gpt category 2024-04-09 18:43:06 +08:00
吴小白 8500f186f6 perf: 优化镜像构建 2024-04-08 18:52:22 +08:00
ibuler 97f60a61e0 perf: 修改翻译 2024-04-08 14:32:14 +08:00
Bryan 08ac8b0857
Update README.md 2024-04-02 15:27:28 +08:00
ibuler 255817f5c6 perf: 修改翻译 2024-04-02 14:27:18 +08:00
ibuler 19b196eb1f Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-04-01 19:28:26 +08:00
ibuler 40db6485dd perf: change i18n 2024-04-01 19:28:08 +08:00
Bryan b23e99885e
Update README.md 2024-04-01 18:47:29 +08:00
Bryan 22fbbb92da
Update README.md 2024-04-01 18:41:34 +08:00
Bryan 99c94166bb
Update README.md 2024-04-01 18:38:59 +08:00
Bryan 169254a1c7
Update README.md 2024-04-01 18:22:11 +08:00
Bryan bda6037b2a
Update README.md 2024-04-01 18:21:35 +08:00
Bryan 1cf0b15528
Update README.md 2024-04-01 18:08:47 +08:00
Bryan ff3865d1a7
Update README.md 2024-04-01 18:01:56 +08:00
Bryan 10435788bc
Update README.md 2024-04-01 17:37:11 +08:00
Bai 02750e56d9 perf: Update README.md 2024-04-01 17:09:08 +08:00
ibuler a1d53cba44 Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-03-29 19:01:01 +08:00
Bai b921ca8c9d perf: Update README.md 2024-03-29 18:46:11 +08:00
ibuler 29b38632e2 Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-03-29 15:30:31 +08:00
ibuler 56193f833f perf: change some translation 2024-03-29 15:29:04 +08:00
Bryan 2c8b977001
Update README.md 2024-03-28 19:05:42 +08:00
Bryan 4827fcf243
Update README.md 2024-03-28 19:02:39 +08:00
Bryan 9140ed6969
Update README.md 2024-03-28 18:01:16 +08:00
Bryan 24e7597c67
Update README.md 2024-03-28 17:59:37 +08:00
Bryan 833dd654b2
Update README.md 2024-03-28 17:57:02 +08:00
Bryan ae74154071
Update README.md 2024-03-28 17:52:37 +08:00
Bryan fb1631c1c7
Update README.md 2024-03-28 17:49:53 +08:00
Bryan 1c6832b9b2
Update README.md 2024-03-28 17:11:55 +08:00
Bryan 77d06037bb
Update README.md 2024-03-28 17:05:12 +08:00
Bai 136e62b97d perf: Update README.md 2024-03-28 17:02:52 +08:00
Bryan 24c36087dd
Update README.md 2024-03-28 16:33:24 +08:00
Bryan 73f9d721fe
Update README.md 2024-03-28 16:10:32 +08:00
Bryan 792f8b2d1f
Update README.md 2024-03-28 16:08:05 +08:00
Bryan 6871d194a8
Update README.md 2024-03-28 16:07:22 +08:00
Bryan 12c26e4551
Update README.md 2024-03-28 15:56:55 +08:00
ibuler 3426f650fa Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-03-28 14:40:31 +08:00
ibuler f224dc241e perf: 修改翻译 2024-03-28 14:31:27 +08:00
Bryan f6effb3c40
Update README.md 2024-03-28 14:21:02 +08:00
Bryan 6bbdcc060d
perf: Update README.md 2024-03-28 11:36:24 +08:00
Bryan 14411d8c86
Update README.md 2024-03-28 11:05:04 +08:00
Bryan cca2bfee4e
perf: Update README.md 2024-03-28 10:42:01 +08:00
Bryan c6cc68601b
perf: Update README.md 2024-03-28 10:40:48 +08:00
Bai 06f33e4bdc perf: Update README.md 2024-03-27 18:15:29 +08:00
ibuler 616b38158a Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-03-27 17:51:12 +08:00
ibuler c22f88ae42 perf: 修改翻译 2024-03-27 17:50:44 +08:00
Bai 3bf401f029 perf: Update README.md 2024-03-26 19:34:06 +08:00
Bai 0b8b74b7a4 perf: Update README.md 2024-03-26 18:48:10 +08:00
Bai e1bd0ee3d7 perf: Update README.md 2024-03-26 18:30:30 +08:00
Bai 4b0d95ed0c perf: Update README.md 2024-03-26 17:40:22 +08:00
Bai fedb146025 perf: Update README.md 2024-03-26 16:57:52 +08:00
Bai 695a5eb470 perf: Update README.md 2024-03-26 16:53:04 +08:00
ibuler f6e4d909ff Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-03-22 10:17:36 +08:00
ibuler 6c0299b05a perf: 优化语言更改 2024-03-21 19:13:00 +08:00
Bai fb02095568 perf: Remove settigns.LITE 2024-03-19 19:22:29 +08:00
Bai d5675ce498 perf: update poetry.lock 2024-03-19 18:10:02 +08:00
ibuler ccbb860de1 Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-03-19 17:54:00 +08:00
ibuler 5e104a3dd2 perf: 修改翻译 2024-03-19 17:53:29 +08:00
Bai 51890c94cc perf: 对ce、ee依赖库进行分组 2024-03-19 16:35:15 +08:00
Bai 06259a2d63 perf: 对ce、ee依赖库进行分组 2024-03-19 16:31:45 +08:00
ibuler d04ac09e82 perf: 修改 groups api 2024-03-15 19:18:49 +08:00
ibuler cae9f03892 perf: 修改 platform 翻译 2024-03-13 18:40:35 +08:00
ibuler bffcd6107c perf: 修改翻译 2024-03-12 18:47:44 +08:00
ibuler 056e0c816b perf: 修改翻译 2024-03-12 17:04:26 +08:00
ibuler ea67312877 perf: 修改翻译 2024-03-11 19:20:18 +08:00
ibuler 327cdc8604 perf: 修改翻译 2024-03-11 14:33:14 +08:00
ibuler 6f37cc4d01 merge: with remote 2024-03-07 18:36:03 +08:00
ibuler 003dd49ed6 perf: 修改翻译 2024-03-07 18:33:13 +08:00
Bai 46d57f02e7 perf: i18n settings-systemtask done. 2024-03-07 17:29:03 +08:00
Bai 30915a93e5 perf: i18n settings-tools done. 2024-03-07 16:15:09 +08:00
Bai c64480dc33 perf: i18n settings-Interface not done. 2024-03-06 17:49:42 +08:00
ibuler 4a9b1aff96 Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-03-06 17:08:31 +08:00
ibuler 542e94ec9c perf: 修改翻译 2024-03-06 17:08:24 +08:00
fit2bot 9341558f61
perf: translate (#12764)
Co-authored-by: feng <1304903146@qq.com>
2024-03-06 16:51:07 +08:00
ibuler 6ea13b2c0d perf: 修改翻译 2024-03-05 19:01:44 +08:00
ibuler e57512f4fe perf: 添加配置支持 Lite 2024-03-04 19:18:26 +08:00
ibuler 348f67f4a4 Merge branch 'v4' of github.com:jumpserver/jumpserver into v4 2024-03-04 15:46:18 +08:00
ibuler 83bdf07600 perf: 修改翻译 2024-03-04 15:42:14 +08:00
fit2bot dfe4eddbbc
perf: translate (#12746)
Co-authored-by: feng <1304903146@qq.com>
Co-authored-by: feng626 <57284900+feng626@users.noreply.github.com>
2024-03-04 14:44:19 +08:00
ibuler 1caed59f76 merge: with remote 2024-03-04 14:03:05 +08:00
Bai 6db4e88a2c perf: 更新 poetry.lock 文件 2024-03-04 11:32:04 +08:00
fit2bot 133daeb664
perf: translate (#12739)
Co-authored-by: feng <1304903146@qq.com>
2024-03-01 15:42:21 +08:00
wangruidong a4a8d1ecf0 perf: modify menu translate 2024-03-01 13:53:29 +08:00
Bryan 7ba24293d1
Merge pull request #12736 from jumpserver/pr@dev@master_fix
fix: 解决冲突
2024-02-29 16:38:43 +08:00
Bai f10114c9ed fix: 解决冲突 2024-02-29 16:37:10 +08:00
Bryan cf31cbfb07
Merge pull request #12729 from jumpserver/dev
v3.10.4
2024-02-29 16:19:59 +08:00
ibuler 88a08a74f7 perf: 修改翻译 2024-02-29 14:57:38 +08:00
feng c9e12a3027 perf: Modify some translations 2024-02-28 18:23:10 +08:00
fit2bot 82aa4a65ab
perf: account translate (#12723)
Co-authored-by: feng <1304903146@qq.com>
Co-authored-by: feng626 <57284900+feng626@users.noreply.github.com>
2024-02-28 17:32:29 +08:00
ibuler d46237f1bf merge: with remote 2024-02-28 16:32:46 +08:00
ibuler 1744f94910 perf: 修改翻译 2024-02-28 16:27:41 +08:00
Bai e308812429 perf: i18n settings-Security done. 2024-02-27 19:20:48 +08:00
fit2bot 2328ef0b0c
perf: account translate (#12719)
Co-authored-by: feng <1304903146@qq.com>
2024-02-27 19:17:40 +08:00
Bai 000c5770f2 perf: i18n settings-RemoteApp done. 2024-02-27 17:13:59 +08:00
Bai 9e1a3598ab perf: i18n settings-Components done. 2024-02-27 16:43:44 +08:00
Bai 7268f60343 perf: i18n settings-Storage done. 2024-02-27 14:59:22 +08:00
Bai c8b274031f perf: i18n settings-Auth done. 2024-02-27 11:25:42 +08:00
Bai 10394dbb1c perf: i18n settings-Auth done. 2024-02-26 16:53:40 +08:00
Bai 859bb91fc7 perf: i18n settings-Features done. 2024-02-26 15:47:05 +08:00
fit2bot 0fd0d33704
perf: i18n settings-notifications done. (#12702)
Co-authored-by: Bai <baijiangjie@gmail.com>
Co-authored-by: Bryan <jiangjie.bai@fit2cloud.com>
2024-02-23 18:09:18 +08:00
fit2bot ad0f489834
perf: translate (#12701)
Co-authored-by: feng <1304903146@qq.com>
2024-02-23 17:52:16 +08:00
fit2bot b1fa870de7
perf: 工作台相关翻译 (#12700)
Co-authored-by: feng <1304903146@qq.com>
Co-authored-by: feng626 <57284900+feng626@users.noreply.github.com>
2024-02-23 17:22:47 +08:00
Bai 7c5e2ae8ea perf: i18n settings-org done. 2024-02-23 15:17:17 +08:00
Bai c0e4065a45 perf: i18n settings-basic done. 2024-02-23 14:31:09 +08:00
fit2bot 35448eea9f
perf: 翻译 (#12690)
Co-authored-by: feng <1304903146@qq.com>
2024-02-22 17:46:12 +08:00
wangruidong 430f45a3ec perf: permissions i18n modify 2024-02-22 17:36:45 +08:00
Bai 71b6fd5326 perf: 修改翻译 2024-02-22 17:29:46 +08:00
wangruidong 251db733b2 perf: i18n modify 2024-02-22 10:30:15 +08:00
ibuler d799725b8a perf: 修改翻译 2024-02-20 19:01:32 +08:00
ibuler 9d80aed468 perf: 修改一些翻译 2024-02-06 15:51:39 +08:00
老广 96f92f0908
Merge pull request #12643 from jumpserver/pr@v4@perf_i18n
perf: 优化翻译
2024-02-05 14:18:48 +08:00
ibuler 314e4301f3 perf: 修改翻译 2024-02-05 14:13:07 +08:00
ibuler b284bb60f5 merge: with dev 2024-02-05 09:49:43 +08:00
ibuler f99396ec50 perf: 修改翻译 2024-02-04 19:31:51 +08:00
ibuler 886cf6ed1f perf: 暂存 2024-02-04 16:46:33 +08:00
wangruidong 0edad24d5d fix: 资产过期消息提示发送失败 2024-02-04 11:41:48 +08:00
ibuler 74dd6e97a2 perf: 优化翻译 2024-02-04 10:23:54 +08:00
fit2bot 46fde2f1aa
perf: 整合翻译 (#12630)
* stash

* stash

* perf: 整合翻译

* perf: 整理了一遍

---------

Co-authored-by: ibuler <ibuler@qq.com>
2024-02-01 16:02:31 +08:00
ibuler 1f1c1a9157 fix: 修复定时检测用户是否活跃任务无法执行的问题 2024-01-23 09:28:38 +00:00
feng 6c9d271ae1 fix: redis 密码有特殊字符celery beat启动失败 2024-01-22 06:18:34 +00:00
Bai 6ff852e225 perf: 修复 Count 时没有去重的问题 2024-01-22 06:16:25 +00:00
Bryan baa75dc735
Merge pull request #12566 from jumpserver/master
v3.10.2
2024-01-17 07:34:28 -04:00
Bryan 8a9f0436b8
Merge pull request #12565 from jumpserver/dev
v3.10.2
2024-01-17 07:23:30 -04:00
fit2bot e2a3c360ea
perf: 修改一次性翻译长度 (#12557)
Co-authored-by: feng <1304903146@qq.com>
2024-01-17 11:38:58 +08:00
fit2bot 9968617758
perf: 修改优化结构 (#12554)
* perf: 修改优化结构

* perf: 修改结构

---------

Co-authored-by: ibuler <ibuler@qq.com>
2024-01-17 11:08:39 +08:00
feng 1cec27ed70 perf: 添加进度条 2024-01-17 10:36:45 +08:00
feng f0dfff0625 feat: gpt translate 2024-01-16 16:19:37 +08:00
fit2bot fdaec3c959
perf: Modify i18n for settings module. (#12543)
Co-authored-by: Bai <baijiangjie@gmail.com>
2024-01-15 04:41:50 -07:00
ibuler fcb4c6a972 perf: Add sort json script 2024-01-15 17:12:13 +08:00
ibuler 513974bbed perf: remove some category 2024-01-15 16:38:16 +08:00
ibuler 00d6effd69 pref: stash 2024-01-11 18:33:52 +08:00
ibuler c06c68d5da perf: 统一翻译 2024-01-11 14:40:44 +08:00
Bryan a9620a3cbe
Merge pull request #12461 from jumpserver/master
v3.10.1
2023-12-29 11:33:05 +05:00
Bryan 769e7dc8a0
Merge pull request #12460 from jumpserver/dev
v3.10.1
2023-12-29 11:20:36 +05:00
Bryan 2a70449411
Merge pull request #12458 from jumpserver/dev
v3.10.1
2023-12-29 11:01:13 +05:00
Bryan 8df720f19e
Merge pull request #12401 from jumpserver/dev
v3.10
2023-12-21 15:14:19 +05:00
老广 dabbb45f6e
Merge pull request #12144 from jumpserver/dev
v3.9.0
2023-11-16 18:23:05 +08:00
Bryan ce24c1c3fd
Merge pull request #11914 from jumpserver/dev
v3.8.0
2023-10-19 03:37:39 -05:00
Bryan 3c54c82ce9
Merge pull request #11636 from jumpserver/dev
v3.7.0
2023-09-21 17:02:48 +08:00
1732 changed files with 171524 additions and 74750 deletions

View File

@ -8,3 +8,6 @@ celerybeat.pid
.vagrant/
apps/xpack/.git
.history/
.idea
.venv/
.env

4
.gitattributes vendored
View File

@ -1,4 +0,0 @@
*.mmdb filter=lfs diff=lfs merge=lfs -text
*.mo filter=lfs diff=lfs merge=lfs -text
*.ipdb filter=lfs diff=lfs merge=lfs -text

View File

@ -1,35 +0,0 @@
---
name: 需求建议
about: 提出针对本项目的想法和建议
title: "[Feature] 需求标题"
labels: 类型:需求
assignees:
- ibuler
- baijiangjie
---
## 注意
_针对过于简单的需求描述不予考虑。请确保提供足够的细节和信息以支持功能的开发和实现。_
## 功能名称
[在这里输入功能的名称或标题]
## 功能描述
[在这里描述该功能的详细内容,包括其作用、目的和所需的功能]
## 用户故事(可选)
[如果适用,可以提供用户故事来更好地理解该功能的使用场景和用户期望]
## 功能要求
- [要求1描述该功能的具体要求如界面设计、交互逻辑等]
- [要求2描述该功能的另一个具体要求]
- [以此类推,列出所有相关的功能要求]
## 示例或原型(可选)
[如果有的话,提供该功能的示例或原型图以更好地说明功能的实现方式]
## 优先级
[描述该功能的优先级,如高、中、低,或使用数字等其他标识]
## 备注(可选)
[在这里添加任何其他相关信息或备注]

72
.github/ISSUE_TEMPLATE/1_bug_report.yml vendored Normal file
View File

@ -0,0 +1,72 @@
name: '🐛 Bug Report'
description: 'Report an Bug'
title: '[Bug] '
labels: ['🐛 Bug']
assignees:
- baijiangjie
body:
- type: input
attributes:
label: 'Product Version'
description: The versions prior to v2.28 (inclusive) are no longer supported.
validations:
required: true
- type: checkboxes
attributes:
label: 'Product Edition'
options:
- label: 'Community Edition'
- label: 'Enterprise Edition'
- label: 'Enterprise Trial Edition'
validations:
required: true
- type: checkboxes
attributes:
label: 'Installation Method'
options:
- label: 'Online Installation (One-click command installation)'
- label: 'Offline Package Installation'
- label: 'All-in-One'
- label: '1Panel'
- label: 'Kubernetes'
- label: 'Source Code'
- type: textarea
attributes:
label: 'Environment Information'
description: Please provide a clear and concise description outlining your environment information.
validations:
required: true
- type: textarea
attributes:
label: '🐛 Bug Description'
description:
Please provide a clear and concise description of the defect. If the issue is complex, please provide detailed explanations. <br/>
Unclear descriptions will not be processed. Please ensure you provide enough detail and information to support replicating and fixing the defect.
validations:
required: true
- type: textarea
attributes:
label: 'Recurrence Steps'
description: Please provide a clear and concise description outlining how to reproduce the issue.
validations:
required: true
- type: textarea
attributes:
label: 'Expected Behavior'
description: Please provide a clear and concise description of what you expect to happen.
- type: textarea
attributes:
label: 'Additional Information'
description: Please add any additional background information about the issue here.
- type: textarea
attributes:
label: 'Attempted Solutions'
description: If you have already attempted to solve the issue, please list the solutions you have tried here.

60
.github/ISSUE_TEMPLATE/2_question.yml vendored Normal file
View File

@ -0,0 +1,60 @@
name: '🤔 Question'
description: 'Pose a question'
title: '[Question] '
labels: ['🤔 Question']
assignees:
- baijiangjie
body:
- type: input
attributes:
label: 'Product Version'
description: The versions prior to v2.28 (inclusive) are no longer supported.
validations:
required: true
- type: checkboxes
attributes:
label: 'Product Edition'
options:
- label: 'Community Edition'
- label: 'Enterprise Edition'
- label: 'Enterprise Trial Edition'
validations:
required: true
- type: checkboxes
attributes:
label: 'Installation Method'
options:
- label: 'Online Installation (One-click command installation)'
- label: 'Offline Package Installation'
- label: 'All-in-One'
- label: '1Panel'
- label: 'Kubernetes'
- label: 'Source Code'
- type: textarea
attributes:
label: 'Environment Information'
description: Please provide a clear and concise description outlining your environment information.
validations:
required: true
- type: textarea
attributes:
label: '🤔 Question Description'
description: |
Please provide a clear and concise description of the defect. If the issue is complex, please provide detailed explanations. <br/>
Unclear descriptions will not be processed.
validations:
required: true
- type: textarea
attributes:
label: 'Expected Behavior'
description: Please provide a clear and concise description of what you expect to happen.
- type: textarea
attributes:
label: 'Additional Information'
description: Please add any additional background information about the issue here.

View File

@ -0,0 +1,56 @@
name: '⭐️ Feature Request'
description: 'Suggest an idea'
title: '[Feature] '
labels: ['⭐️ Feature Request']
assignees:
- baijiangjie
- ibuler
body:
- type: input
attributes:
label: 'Product Version'
description: The versions prior to v2.28 (inclusive) are no longer supported.
validations:
required: true
- type: checkboxes
attributes:
label: 'Product Edition'
options:
- label: 'Community Edition'
- label: 'Enterprise Edition'
- label: 'Enterprise Trial Edition'
validations:
required: true
- type: checkboxes
attributes:
label: 'Installation Method'
options:
- label: 'Online Installation (One-click command installation)'
- label: 'Offline Package Installation'
- label: 'All-in-One'
- label: '1Panel'
- label: 'Kubernetes'
- label: 'Source Code'
- type: textarea
attributes:
label: '⭐️ Feature Description'
description: |
Please add a clear and concise description of the problem you aim to solve with this feature request.<br/>
Unclear descriptions will not be processed.
validations:
required: true
- type: textarea
attributes:
label: 'Proposed Solution'
description: Please provide a clear and concise description of the solution you desire.
validations:
required: true
- type: textarea
attributes:
label: 'Additional Information'
description: Please add any additional background information about the issue here.

View File

@ -0,0 +1,72 @@
name: '🐛 反馈缺陷'
description: '反馈一个缺陷'
title: '[Bug] '
labels: ['🐛 Bug']
assignees:
- baijiangjie
body:
- type: input
attributes:
label: '产品版本'
description: 不再支持 v2.28(含)之前的版本。
validations:
required: true
- type: checkboxes
attributes:
label: '版本类型'
options:
- label: '社区版'
- label: '企业版'
- label: '企业试用版'
validations:
required: true
- type: checkboxes
attributes:
label: '安装方式'
options:
- label: '在线安装 (一键命令安装)'
- label: '离线包安装'
- label: 'All-in-One'
- label: '1Panel'
- label: 'Kubernetes'
- label: '源码安装'
- type: textarea
attributes:
label: '环境信息'
description: 请提供一个清晰且简洁的描述,说明你的环境信息。
validations:
required: true
- type: textarea
attributes:
label: '🐛 缺陷描述'
description: |
请提供一个清晰且简洁的缺陷描述,如果问题比较复杂,也请详细说明。<br/>
针对不清晰的描述信息将不予处理。请确保提供足够的细节和信息,以支持对缺陷进行复现和修复。
validations:
required: true
- type: textarea
attributes:
label: '复现步骤'
description: 请提供一个清晰且简洁的描述,说明如何复现问题。
validations:
required: true
- type: textarea
attributes:
label: '期望结果'
description: 请提供一个清晰且简洁的描述,说明你期望发生什么。
- type: textarea
attributes:
label: '补充信息'
description: 在这里添加关于问题的任何其他背景信息。
- type: textarea
attributes:
label: '尝试过的解决方案'
description: 如果你已经尝试解决问题,请在此列出你尝试过的解决方案。

View File

@ -0,0 +1,61 @@
name: '🤔 问题咨询'
description: '提出一个问题'
title: '[Question] '
labels: ['🤔 Question']
assignees:
- baijiangjie
body:
- type: input
attributes:
label: '产品版本'
description: 不再支持 v2.28(含)之前的版本。
validations:
required: true
- type: checkboxes
attributes:
label: '版本类型'
options:
- label: '社区版'
- label: '企业版'
- label: '企业试用版'
validations:
required: true
- type: checkboxes
attributes:
label: '安装方式'
options:
- label: '在线安装 (一键命令安装)'
- label: '离线包安装'
- label: 'All-in-One'
- label: '1Panel'
- label: 'Kubernetes'
- label: '源码安装'
- type: textarea
attributes:
label: '环境信息'
description: 请在此详细描述你的环境信息,如操作系统、浏览器和部署架构等。
validations:
required: true
- type: textarea
attributes:
label: '🤔 问题描述'
description: |
请提供一个清晰且简洁的问题描述,如果问题比较复杂,也请详细说明。<br/>
针对不清晰的描述信息将不予处理。
validations:
required: true
- type: textarea
attributes:
label: '期望结果'
description: 请提供一个清晰且简洁的描述,说明你期望发生什么。
- type: textarea
attributes:
label: '补充信息'
description: 在这里添加关于问题的任何其他背景信息。

View File

@ -0,0 +1,56 @@
name: '⭐️ 功能需求'
description: '提出需求或建议'
title: '[Feature] '
labels: ['⭐️ Feature Request']
assignees:
- baijiangjie
- ibuler
body:
- type: input
attributes:
label: '产品版本'
description: 不再支持 v2.28(含)之前的版本。
validations:
required: true
- type: checkboxes
attributes:
label: '版本类型'
options:
- label: '社区版'
- label: '企业版'
- label: '企业试用版'
validations:
required: true
- type: checkboxes
attributes:
label: '安装方式'
options:
- label: '在线安装 (一键命令安装)'
- label: '离线包安装'
- label: 'All-in-One'
- label: '1Panel'
- label: 'Kubernetes'
- label: '源码安装'
- type: textarea
attributes:
label: '⭐️ 需求描述'
description: |
请添加一个清晰且简洁的问题描述,阐述你希望通过这个功能需求解决的问题。<br/>
针对不清晰的描述信息将不予处理。
validations:
required: true
- type: textarea
attributes:
label: '解决方案'
description: 请清晰且简洁地描述你想要的解决方案。
validations:
required: true
- type: textarea
attributes:
label: '补充信息'
description: 在这里添加关于问题的任何其他背景信息。

View File

@ -1,51 +0,0 @@
---
name: Bug 提交
about: 提交产品缺陷帮助我们更好的改进
title: "[Bug] Bug 标题"
labels: 类型:Bug
assignees:
- baijiangjie
---
## 注意
**JumpServer 版本( v2.28 之前的版本不再支持 )** <br>
_针对过于简单的 Bug 描述不予考虑。请确保提供足够的细节和信息以支持 Bug 的复现和修复。_
## 当前使用的 JumpServer 版本 (必填)
[在这里输入当前使用的 JumpServer 的版本号]
## 使用的版本类型 (必填)
- [ ] 社区版
- [ ] 企业版
- [ ] 企业试用版
## 版本安装方式 (必填)
- [ ] 在线安装 (一键命令)
- [ ] 离线安装 (下载离线包)
- [ ] All-in-One
- [ ] 1Panel 安装
- [ ] Kubernetes 安装
- [ ] 源码安装
## Bug 描述 (详细)
[在这里描述 Bug 的详细情况,包括其影响和出现的具体情况]
## 复现步骤
1. [描述如何复现 Bug 的第一步]
2. [描述如何复现 Bug 的第二步]
3. [以此类推,列出所有复现 Bug 所需的步骤]
## 期望行为
[描述 Bug 出现时期望的系统行为或结果]
## 实际行为
[描述实际上发生了什么,以及 Bug 出现的具体情况]
## 系统环境
- 操作系统:[例如Windows 10, macOS Big Sur]
- 浏览器/应用版本:[如果适用,请提供相关版本信息]
- 其他相关环境信息:[如果有其他相关环境信息,请在此处提供]
## 附加信息(可选)
[在这里添加任何其他相关信息,如截图、错误信息等]

View File

@ -1,50 +0,0 @@
---
name: 问题咨询
about: 提出针对本项目安装部署、使用及其他方面的相关问题
title: "[Question] 问题标题"
labels: 类型:提问
assignees:
- baijiangjie
---
## 注意
**请描述您的问题.** <br>
**JumpServer 版本( v2.28 之前的版本不再支持 )** <br>
_针对过于简单的 Bug 描述不予考虑。请确保提供足够的细节和信息以支持 Bug 的复现和修复。_
## 当前使用的 JumpServer 版本 (必填)
[在这里输入当前使用的 JumpServer 的版本号]
## 使用的版本类型 (必填)
- [ ] 社区版
- [ ] 企业版
- [ ] 企业试用版
## 版本安装方式 (必填)
- [ ] 在线安装 (一键命令)
- [ ] 离线安装 (下载离线包)
- [ ] All-in-One
- [ ] 1Panel 安装
- [ ] Kubernetes 安装
- [ ] 源码安装
## 问题描述 (详细)
[在这里描述你遇到的问题]
## 背景信息
- 操作系统:[例如Windows 10, macOS Big Sur]
- 浏览器/应用版本:[如果适用,请提供相关版本信息]
- 其他相关环境信息:[如果有其他相关环境信息,请在此处提供]
## 具体问题
[在这里详细描述你的问题,包括任何相关细节或错误信息]
## 尝试过的解决方法
[如果你已经尝试过解决问题,请在这里列出你已经尝试过的解决方法]
## 预期结果
[描述你期望的解决方案或结果]
## 我们的期望
[描述你希望我们提供的帮助或支持]

14
.github/dependabot.yml.bak vendored Normal file
View File

@ -0,0 +1,14 @@
version: 2
updates:
- package-ecosystem: "uv"
directory: "/"
schedule:
interval: "weekly"
day: "monday"
time: "09:30"
timezone: "Asia/Shanghai"
target-branch: dev
groups:
python-dependencies:
patterns:
- "*"

74
.github/workflows/build-base-image.yml vendored Normal file
View File

@ -0,0 +1,74 @@
name: Build and Push Base Image
on:
pull_request:
branches:
- 'dev'
- 'v*'
paths:
- poetry.lock
- pyproject.toml
- Dockerfile-base
- package.json
- go.mod
- yarn.lock
- pom.xml
- install_deps.sh
- utils/clean_site_packages.sh
types:
- opened
- synchronize
- reopened
jobs:
build-and-push:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
image: tonistiigi/binfmt:qemu-v7.0.0-28
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Extract date
id: vars
run: echo "IMAGE_TAG=$(date +'%Y%m%d_%H%M%S')" >> $GITHUB_ENV
- name: Extract repository name
id: repo
run: echo "REPO=$(basename ${{ github.repository }})" >> $GITHUB_ENV
- name: Build and push multi-arch image
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
push: true
file: Dockerfile-base
tags: jumpserver/core-base:${{ env.IMAGE_TAG }}
- name: Update Dockerfile
run: |
sed -i 's|-base:.* AS stage-build|-base:${{ env.IMAGE_TAG }} AS stage-build|' Dockerfile
- name: Commit changes
run: |
git config --global user.name 'github-actions[bot]'
git config --global user.email 'github-actions[bot]@users.noreply.github.com'
git add Dockerfile
git commit -m "perf: Update Dockerfile with new base image tag"
git push origin ${{ github.event.pull_request.head.ref }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@ -0,0 +1,46 @@
name: Build and Push Python Base Image
on:
workflow_dispatch:
inputs:
tag:
description: 'Tag to build'
required: true
default: '3.11-slim-bullseye-v1'
type: string
jobs:
build-and-push:
runs-on: ubuntu-22.04
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.ref }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
image: tonistiigi/binfmt:qemu-v7.0.0-28
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Extract repository name
id: repo
run: echo "REPO=$(basename ${{ github.repository }})" >> $GITHUB_ENV
- name: Build and push multi-arch image
uses: docker/build-push-action@v6
with:
platforms: linux/amd64,linux/arm64
push: true
file: Dockerfile-python
tags: jumpserver/core-base:python-${{ inputs.tag }}

View File

@ -0,0 +1,31 @@
name: Check I18n files CompileMessages
on:
pull_request:
branches:
- 'dev'
paths:
- 'apps/i18n/core/**/*.po'
types:
- opened
- synchronize
- reopened
jobs:
compile-messages-check:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and check compilemessages
uses: docker/build-push-action@v6
with:
platforms: linux/amd64
push: false
file: Dockerfile
target: stage-build
tags: jumpserver/core:stage-build

24
.github/workflows/discord-release.yml vendored Normal file
View File

@ -0,0 +1,24 @@
name: Publish Release to Discord
on:
release:
types: [published]
jobs:
send_discord_notification:
runs-on: ubuntu-latest
if: startsWith(github.event.release.tag_name, 'v4.')
steps:
- name: Send release notification to Discord
env:
WEBHOOK_URL: ${{ secrets.DISCORD_CHANGELOG_WEBHOOK }}
run: |
# 获取标签名称和 release body
TAG_NAME="${{ github.event.release.tag_name }}"
RELEASE_BODY="${{ github.event.release.body }}"
# 使用 jq 构建 JSON 数据,以确保安全传递
JSON_PAYLOAD=$(jq -n --arg tag "# JumpServer $TAG_NAME Released! 🚀" --arg body "$RELEASE_BODY" '{content: "\($tag)\n\($body)"}')
# 使用 curl 发送 JSON 数据
curl -X POST -H "Content-Type: application/json" -d "$JSON_PAYLOAD" "$WEBHOOK_URL"

24
.github/workflows/docs-release.yml vendored Normal file
View File

@ -0,0 +1,24 @@
name: Auto update docs changelog
on:
release:
types: [published]
jobs:
update_docs_changelog:
runs-on: ubuntu-latest
if: startsWith(github.event.release.tag_name, 'v4.')
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Update docs changelog
env:
TAG_NAME: ${{ github.event.release.tag_name }}
DOCS_TOKEN: ${{ secrets.DOCS_TOKEN }}
run: |
git config --global user.name 'BaiJiangJie'
git config --global user.email 'jiangjie.bai@fit2cloud.com'
git clone https://$DOCS_TOKEN@github.com/jumpservice/documentation.git
cd documentation/utils
bash update_changelog.sh

View File

@ -12,7 +12,9 @@ jobs:
uses: actions-cool/issues-helper@v2
with:
actions: 'close-issues'
labels: '状态:待反馈'
labels: '⏳ Pending feedback'
inactive-day: 30
body: |
You haven't provided feedback for over 30 days.
We will close this issue. If you have any further needs, you can reopen it or submit a new issue.
您超过 30 天未反馈信息,我们将关闭该 issue如有需求您可以重新打开或者提交新的 issue。

View File

@ -13,4 +13,4 @@ jobs:
if: ${{ !github.event.issue.pull_request }}
with:
actions: 'remove-labels'
labels: '状态:待处理,状态:待反馈'
labels: '🔔 Pending processing,⏳ Pending feedback'

View File

@ -13,13 +13,13 @@ jobs:
uses: actions-cool/issues-helper@v2
with:
actions: 'add-labels'
labels: '状态:待处理'
labels: '🔔 Pending processing'
- name: Remove require reply label
uses: actions-cool/issues-helper@v2
with:
actions: 'remove-labels'
labels: '状态:待反馈'
labels: '⏳ Pending feedback'
add-label-if-is-member:
runs-on: ubuntu-latest
@ -55,11 +55,11 @@ jobs:
uses: actions-cool/issues-helper@v2
with:
actions: 'add-labels'
labels: '状态:待反馈'
labels: '⏳ Pending feedback'
- name: Remove require handle label
if: contains(steps.member_names.outputs.data, github.event.comment.user.login)
uses: actions-cool/issues-helper@v2
with:
actions: 'remove-labels'
labels: '状态:待处理'
labels: '🔔 Pending processing'

View File

@ -13,4 +13,4 @@ jobs:
if: ${{ !github.event.issue.pull_request }}
with:
actions: 'add-labels'
labels: '状态:待处理'
labels: '🔔 Pending processing'

View File

@ -1,55 +0,0 @@
name: "Run Build Test"
on:
push:
paths:
- 'Dockerfile'
- 'Dockerfile-*'
- 'pyproject.toml'
- 'poetry.lock'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: docker/setup-qemu-action@v3
- uses: docker/setup-buildx-action@v3
- name: Check Dockerfile
run: |
test -f Dockerfile-ce || cp -f Dockerfile Dockerfile-ce
- name: Build CE Image
uses: docker/build-push-action@v5
with:
context: .
push: false
file: Dockerfile-ce
tags: jumpserver/core-ce:test
platforms: linux/amd64
build-args: |
APT_MIRROR=http://deb.debian.org
PIP_MIRROR=https://pypi.org/simple
PIP_JMS_MIRROR=https://pypi.org/simple
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Prepare EE Image
run: |
sed -i 's@^FROM registry.fit2cloud.com@# FROM registry.fit2cloud.com@g' Dockerfile-ee
sed -i 's@^COPY --from=build-xpack@# COPY --from=build-xpack@g' Dockerfile-ee
- name: Build EE Image
uses: docker/build-push-action@v5
with:
context: .
push: false
file: Dockerfile-ee
tags: jumpserver/core-ee:test
platforms: linux/amd64
build-args: |
APT_MIRROR=http://deb.debian.org
PIP_MIRROR=https://pypi.org/simple
PIP_JMS_MIRROR=https://pypi.org/simple
cache-from: type=gha
cache-to: type=gha,mode=max

View File

@ -0,0 +1,63 @@
name: "Run Build Test"
on:
push:
paths:
- 'Dockerfile'
- 'Dockerfile*'
- 'Dockerfile-*'
- 'pyproject.toml'
- 'poetry.lock'
jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
component: [core]
version: [v4]
steps:
- uses: actions/checkout@v4
- uses: docker/setup-buildx-action@v3
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Prepare Build
run: |
sed -i 's@^FROM registry.fit2cloud.com/jumpserver@FROM ghcr.io/jumpserver@g' Dockerfile-ee
- name: Build CE Image
uses: docker/build-push-action@v5
with:
context: .
push: true
file: Dockerfile
tags: ghcr.io/jumpserver/${{ matrix.component }}:${{ matrix.version }}-ce
platforms: linux/amd64
build-args: |
VERSION=${{ matrix.version }}
APT_MIRROR=http://deb.debian.org
PIP_MIRROR=https://pypi.org/simple
outputs: type=image,oci-mediatypes=true,compression=zstd,compression-level=3,force-compression=true
cache-from: type=gha
cache-to: type=gha,mode=max
- name: Build EE Image
uses: docker/build-push-action@v5
with:
context: .
push: false
file: Dockerfile-ee
tags: ghcr.io/jumpserver/${{ matrix.component }}:${{ matrix.version }}
platforms: linux/amd64
build-args: |
VERSION=${{ matrix.version }}
APT_MIRROR=http://deb.debian.org
PIP_MIRROR=https://pypi.org/simple
outputs: type=image,oci-mediatypes=true,compression=zstd,compression-level=3,force-compression=true
cache-from: type=gha
cache-to: type=gha,mode=max

View File

@ -10,3 +10,4 @@ jobs:
- uses: jumpserver/action-generic-handler@master
env:
GITHUB_TOKEN: ${{ secrets.PRIVATE_TOKEN }}
I18N_TOKEN: ${{ secrets.I18N_TOKEN }}

View File

@ -0,0 +1,28 @@
name: LLM Code Review
permissions:
contents: read
pull-requests: write
on:
pull_request:
types: [opened, reopened, synchronize]
jobs:
llm-code-review:
runs-on: ubuntu-latest
steps:
- uses: fit2cloud/LLM-CodeReview-Action@main
env:
GITHUB_TOKEN: ${{ secrets.FIT2CLOUDRD_LLM_CODE_REVIEW_TOKEN }}
OPENAI_API_KEY: ${{ secrets.ALIYUN_LLM_API_KEY }}
LANGUAGE: English
OPENAI_API_ENDPOINT: https://dashscope.aliyuncs.com/compatible-mode/v1
MODEL: qwen2-1.5b-instruct
PROMPT: "Please check the following code differences for any irregularities, potential issues, or optimization suggestions, and provide your answers in English."
top_p: 1
temperature: 1
# max_tokens: 10000
MAX_PATCH_LENGTH: 10000
IGNORE_PATTERNS: "/node_modules,*.md,/dist,/.github"
FILE_PATTERNS: "*.java,*.go,*.py,*.vue,*.ts,*.js,*.css,*.scss,*.html"

45
.github/workflows/translate-readme.yml vendored Normal file
View File

@ -0,0 +1,45 @@
name: Translate README
on:
workflow_dispatch:
inputs:
source_readme:
description: "Source README"
required: false
default: "./readmes/README.en.md"
target_langs:
description: "Target Languages"
required: false
default: "zh-hans,zh-hant,ja,pt-br,es,ru"
gen_dir_path:
description: "Generate Dir Name"
required: false
default: "readmes/"
push_branch:
description: "Push Branch"
required: false
default: "pr@dev@translate_readme"
prompt:
description: "AI Translate Prompt"
required: false
default: ""
gpt_mode:
description: "GPT Mode"
required: false
default: "gpt-4o-mini"
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Auto Translate
uses: jumpserver-dev/action-translate-readme@main
env:
GITHUB_TOKEN: ${{ secrets.PRIVATE_TOKEN }}
OPENAI_API_KEY: ${{ secrets.GPT_API_TOKEN }}
GPT_MODE: ${{ github.event.inputs.gpt_mode }}
SOURCE_README: ${{ github.event.inputs.source_readme }}
TARGET_LANGUAGES: ${{ github.event.inputs.target_langs }}
PUSH_BRANCH: ${{ github.event.inputs.push_branch }}
GEN_DIR_PATH: ${{ github.event.inputs.gen_dir_path }}
PROMPT: ${{ github.event.inputs.prompt }}

5
.gitignore vendored
View File

@ -44,3 +44,8 @@ data/*
test.py
.history/
.test/
*.mo
apps.iml
*.db
*.mmdb
*.ipdb

View File

@ -1,3 +1,4 @@
[settings]
line_length=120
known_first_party=common,users,assets,perms,authentication,jumpserver,notification,ops,orgs,rbac,settings,terminal,tickets

11
.prettierrc Normal file
View File

@ -0,0 +1,11 @@
{
"tabWidth": 4,
"useTabs": false,
"semi": true,
"singleQuote": true,
"trailingComma": "es5",
"bracketSpacing": true,
"arrowParens": "avoid",
"printWidth": 100,
"endOfLine": "lf"
}

2
.pylintrc Normal file
View File

@ -0,0 +1,2 @@
[MESSAGES CONTROL]
disable=missing-module-docstring,missing-class-docstring,missing-function-docstring,too-many-ancestors

View File

@ -1,5 +1,10 @@
# Contributing
As a contributor, you should agree that:
- The producer can adjust the open-source agreement to be more strict or relaxed as deemed necessary.
- Your contributed code may be used for commercial purposes, including but not limited to its cloud business operations.
## Create pull request
PR are always welcome, even if they only contain small fixes like typos or a few lines of code. If there will be a significant effort, please document it as an issue and get a discussion going before starting to work on it.

69
Dockerfile Normal file
View File

@ -0,0 +1,69 @@
FROM jumpserver/core-base:20251014_095903 AS stage-build
ARG VERSION
WORKDIR /opt/jumpserver
ADD . .
RUN echo > /opt/jumpserver/config.yml \
&& \
if [ -n "${VERSION}" ]; then \
sed -i "s@VERSION = .*@VERSION = '${VERSION}'@g" apps/jumpserver/const.py; \
fi
RUN set -ex \
&& export SECRET_KEY=$(head -c100 < /dev/urandom | base64 | tr -dc A-Za-z0-9 | head -c 48) \
&& . /opt/py3/bin/activate \
&& cd apps \
&& python manage.py compilemessages
FROM jumpserver/core-base:python-3.11-slim-bullseye-v1
ENV LANG=en_US.UTF-8 \
PATH=/opt/py3/bin:$PATH
ARG DEPENDENCIES=" \
libldap2-dev \
libx11-dev"
ARG TOOLS=" \
cron \
ca-certificates \
default-libmysqlclient-dev \
openssh-client \
sshpass \
nmap \
bubblewrap"
ARG APT_MIRROR=http://deb.debian.org
RUN set -ex \
&& sed -i "s@http://.*.debian.org@${APT_MIRROR}@g" /etc/apt/sources.list \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& apt-get update > /dev/null \
&& apt-get -y install --no-install-recommends ${DEPENDENCIES} \
&& apt-get -y install --no-install-recommends ${TOOLS} \
&& mkdir -p /root/.ssh/ \
&& echo "Host *\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile /dev/null\n\tCiphers +aes128-cbc\n\tKexAlgorithms +diffie-hellman-group1-sha1\n\tHostKeyAlgorithms +ssh-rsa" > /root/.ssh/config \
&& echo "no" | dpkg-reconfigure dash \
&& apt-get clean all \
&& rm -rf /var/lib/apt/lists/* \
&& echo "0 3 * * * root find /tmp -type f -mtime +1 -size +1M -exec rm -f {} \; && date > /tmp/clean.log" > /etc/cron.d/cleanup_tmp \
&& chmod 0644 /etc/cron.d/cleanup_tmp
COPY --from=stage-build /opt /opt
COPY --from=stage-build /usr/local/bin /usr/local/bin
COPY --from=stage-build /opt/jumpserver/apps/libs/ansible/ansible.cfg /etc/ansible/
WORKDIR /opt/jumpserver
VOLUME /opt/jumpserver/data
ENTRYPOINT ["./entrypoint.sh"]
EXPOSE 8080
STOPSIGNAL SIGQUIT
CMD ["start", "all"]

61
Dockerfile-base Normal file
View File

@ -0,0 +1,61 @@
FROM jumpserver/core-base:python-3.11-slim-bullseye-v1
ARG TARGETARCH
COPY --from=ghcr.io/astral-sh/uv:0.6.14 /uv /uvx /usr/local/bin/
# Install APT dependencies
ARG DEPENDENCIES=" \
ca-certificates \
wget \
g++ \
make \
pkg-config \
default-libmysqlclient-dev \
freetds-dev \
gettext \
libkrb5-dev \
libldap2-dev \
libsasl2-dev"
ARG APT_MIRROR=http://deb.debian.org
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=core \
--mount=type=cache,target=/var/lib/apt,sharing=locked,id=core \
set -ex \
&& rm -f /etc/apt/apt.conf.d/docker-clean \
&& echo 'Binary::apt::APT::Keep-Downloaded-Packages "true";' > /etc/apt/apt.conf.d/keep-cache \
&& sed -i "s@http://.*.debian.org@${APT_MIRROR}@g" /etc/apt/sources.list \
&& apt-get update > /dev/null \
&& apt-get -y install --no-install-recommends ${DEPENDENCIES} \
&& echo "no" | dpkg-reconfigure dash
# Install bin tools
ARG CHECK_VERSION=v1.0.5
RUN set -ex \
&& wget https://github.com/jumpserver-dev/healthcheck/releases/download/${CHECK_VERSION}/check-${CHECK_VERSION}-linux-${TARGETARCH}.tar.gz \
&& tar -xf check-${CHECK_VERSION}-linux-${TARGETARCH}.tar.gz \
&& mv check /usr/local/bin/ \
&& chown root:root /usr/local/bin/check \
&& chmod 755 /usr/local/bin/check \
&& rm -f check-${CHECK_VERSION}-linux-${TARGETARCH}.tar.gz
# Install Python dependencies
WORKDIR /opt/jumpserver
ARG PIP_MIRROR=https://pypi.org/simple
ENV POETRY_PYPI_MIRROR_URL=${PIP_MIRROR}
ENV ANSIBLE_COLLECTIONS_PATHS=/opt/py3/lib/python3.11/site-packages/ansible_collections
ENV LANG=en_US.UTF-8 \
PATH=/opt/py3/bin:$PATH
ENV UV_LINK_MODE=copy
RUN --mount=type=cache,target=/root/.cache \
--mount=type=bind,source=pyproject.toml,target=pyproject.toml \
--mount=type=bind,source=requirements/clean_site_packages.sh,target=clean_site_packages.sh \
--mount=type=bind,source=requirements/collections.yml,target=collections.yml \
--mount=type=bind,source=requirements/static_files.sh,target=utils/static_files.sh \
set -ex \
&& uv venv \
&& uv pip install -i${PIP_MIRROR} -r pyproject.toml \
&& ln -sf $(pwd)/.venv /opt/py3 \
&& bash utils/static_files.sh \
&& bash clean_site_packages.sh

View File

@ -1,136 +0,0 @@
FROM python:3.11-slim-bullseye as stage-1
ARG TARGETARCH
ARG VERSION
ENV VERSION=$VERSION
WORKDIR /opt/jumpserver
ADD . .
RUN echo > /opt/jumpserver/config.yml \
&& cd utils && bash -ixeu build.sh
FROM python:3.11-slim-bullseye as stage-2
ARG TARGETARCH
ARG BUILD_DEPENDENCIES=" \
g++ \
make \
pkg-config"
ARG DEPENDENCIES=" \
freetds-dev \
libffi-dev \
libjpeg-dev \
libkrb5-dev \
libldap2-dev \
libpq-dev \
libsasl2-dev \
libssl-dev \
libxml2-dev \
libxmlsec1-dev \
libxmlsec1-openssl \
freerdp2-dev \
libaio-dev"
ARG TOOLS=" \
ca-certificates \
curl \
default-libmysqlclient-dev \
default-mysql-client \
git \
git-lfs \
unzip \
xz-utils \
wget"
ARG APT_MIRROR=http://mirrors.ustc.edu.cn
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=core-apt \
--mount=type=cache,target=/var/lib/apt,sharing=locked,id=core-apt \
sed -i "s@http://.*.debian.org@${APT_MIRROR}@g" /etc/apt/sources.list \
&& rm -f /etc/apt/apt.conf.d/docker-clean \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& apt-get update \
&& apt-get -y install --no-install-recommends ${BUILD_DEPENDENCIES} \
&& apt-get -y install --no-install-recommends ${DEPENDENCIES} \
&& apt-get -y install --no-install-recommends ${TOOLS} \
&& echo "no" | dpkg-reconfigure dash
WORKDIR /opt/jumpserver
ARG PIP_MIRROR=https://pypi.tuna.tsinghua.edu.cn/simple
RUN --mount=type=cache,target=/root/.cache \
--mount=type=bind,source=poetry.lock,target=/opt/jumpserver/poetry.lock \
--mount=type=bind,source=pyproject.toml,target=/opt/jumpserver/pyproject.toml \
set -ex \
&& python3 -m venv /opt/py3 \
&& pip install poetry -i ${PIP_MIRROR} \
&& poetry config virtualenvs.create false \
&& . /opt/py3/bin/activate \
&& poetry install
FROM python:3.11-slim-bullseye
ARG TARGETARCH
ENV LANG=zh_CN.UTF-8 \
PATH=/opt/py3/bin:$PATH
ARG DEPENDENCIES=" \
libjpeg-dev \
libpq-dev \
libx11-dev \
freerdp2-dev \
libxmlsec1-openssl"
ARG TOOLS=" \
ca-certificates \
curl \
default-libmysqlclient-dev \
default-mysql-client \
iputils-ping \
locales \
netcat-openbsd \
nmap \
openssh-client \
patch \
sshpass \
telnet \
vim \
wget"
ARG APT_MIRROR=http://mirrors.ustc.edu.cn
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked,id=core-apt \
--mount=type=cache,target=/var/lib/apt,sharing=locked,id=core-apt \
sed -i "s@http://.*.debian.org@${APT_MIRROR}@g" /etc/apt/sources.list \
&& rm -f /etc/apt/apt.conf.d/docker-clean \
&& ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime \
&& apt-get update \
&& apt-get -y install --no-install-recommends ${DEPENDENCIES} \
&& apt-get -y install --no-install-recommends ${TOOLS} \
&& mkdir -p /root/.ssh/ \
&& echo "Host *\n\tStrictHostKeyChecking no\n\tUserKnownHostsFile /dev/null\n\tCiphers +aes128-cbc\n\tKexAlgorithms +diffie-hellman-group1-sha1\n\tHostKeyAlgorithms +ssh-rsa" > /root/.ssh/config \
&& echo "no" | dpkg-reconfigure dash \
&& echo "zh_CN.UTF-8" | dpkg-reconfigure locales \
&& sed -i "s@# export @export @g" ~/.bashrc \
&& sed -i "s@# alias @alias @g" ~/.bashrc
ARG RECEPTOR_VERSION=v1.4.5
RUN set -ex \
&& wget -O /opt/receptor.tar.gz https://github.com/ansible/receptor/releases/download/${RECEPTOR_VERSION}/receptor_${RECEPTOR_VERSION/v/}_linux_${TARGETARCH}.tar.gz \
&& tar -xf /opt/receptor.tar.gz -C /usr/local/bin/ \
&& chown root:root /usr/local/bin/receptor \
&& chmod 755 /usr/local/bin/receptor \
&& rm -f /opt/receptor.tar.gz
COPY --from=stage-2 /opt/py3 /opt/py3
COPY --from=stage-1 /opt/jumpserver/release/jumpserver /opt/jumpserver
COPY --from=stage-1 /opt/jumpserver/release/jumpserver/apps/libs/ansible/ansible.cfg /etc/ansible/
WORKDIR /opt/jumpserver
ARG VERSION
ENV VERSION=$VERSION
VOLUME /opt/jumpserver/data
EXPOSE 8080
ENTRYPOINT ["./entrypoint.sh"]

View File

@ -1,5 +1,32 @@
ARG VERSION
FROM registry.fit2cloud.com/jumpserver/xpack:${VERSION} as build-xpack
FROM registry.fit2cloud.com/jumpserver/core-ce:${VERSION}
ARG VERSION=dev
FROM registry.fit2cloud.com/jumpserver/xpack:${VERSION} AS build-xpack
FROM jumpserver/core:${VERSION}-ce
COPY --from=build-xpack /opt/xpack /opt/jumpserver/apps/xpack
ARG TOOLS=" \
g++ \
curl \
iputils-ping \
netcat-openbsd \
nmap \
telnet \
vim \
postgresql-client-13 \
wget \
poppler-utils"
RUN set -ex \
&& apt-get update \
&& apt-get -y install --no-install-recommends ${TOOLS} \
&& apt-get clean all \
&& rm -rf /var/lib/apt/lists/*
WORKDIR /opt/jumpserver
ARG PIP_MIRROR=https://pypi.org/simple
RUN set -ex \
&& uv pip install -i${PIP_MIRROR} --group xpack \
&& playwright install chromium --with-deps --only-shell

11
Dockerfile-python Normal file
View File

@ -0,0 +1,11 @@
FROM python:3.11-slim-bullseye
ARG TARGETARCH
# Install APT dependencies
ENV DEBIAN_FRONTEND=noninteractive
RUN set -eux; \
apt-get update; \
apt-get -y --no-install-recommends upgrade; \
rm -rf /var/lib/apt/lists/*
# upgrade pip and setuptools
RUN pip install --no-cache-dir --upgrade pip setuptools wheel

206
README.md
View File

@ -1,125 +1,125 @@
<p align="center">
<a href="https://jumpserver.org"><img src="https://download.jumpserver.org/images/jumpserver-logo.svg" alt="JumpServer" width="300" /></a>
</p>
<h3 align="center">广受欢迎的开源堡垒机</h3>
<div align="center">
<a name="readme-top"></a>
<a href="https://jumpserver.com" target="_blank"><img src="https://download.jumpserver.org/images/jumpserver-logo.svg" alt="JumpServer" width="300" /></a>
<p align="center">
<a href="https://www.gnu.org/licenses/gpl-3.0.html"><img src="https://img.shields.io/github/license/jumpserver/jumpserver" alt="License: GPLv3"></a>
<a href="https://hub.docker.com/u/jumpserver"><img src="https://img.shields.io/docker/pulls/jumpserver/jms_all.svg" alt="Docker pulls"></a>
<a href="https://github.com/jumpserver/jumpserver/releases/latest"><img src="https://img.shields.io/github/v/release/jumpserver/jumpserver" alt="Latest release"></a>
<a href="https://github.com/jumpserver/jumpserver"><img src="https://img.shields.io/github/stars/jumpserver/jumpserver?color=%231890FF&style=flat-square" alt="Stars"></a>
</p>
## An open-source PAM platform (Bastion Host)
[![][license-shield]][license-link]
[![][docs-shield]][docs-link]
[![][deepwiki-shield]][deepwiki-link]
[![][discord-shield]][discord-link]
[![][docker-shield]][docker-link]
[![][github-release-shield]][github-release-link]
[![][github-stars-shield]][github-stars-link]
[English](/README.md) · [中文(简体)](/readmes/README.zh-hans.md) · [中文(繁體)](/readmes/README.zh-hant.md) · [日本語](/readmes/README.ja.md) · [Português (Brasil)](/readmes/README.pt-br.md) · [Español](/readmes/README.es.md) · [Русский](/readmes/README.ru.md) · [한국어](/readmes/README.ko.md)
</div>
<br/>
## What is JumpServer?
JumpServer is an open-source Privileged Access Management (PAM) platform that provides DevOps and IT teams with on-demand and secure access to SSH, RDP, Kubernetes, Database and RemoteApp endpoints through a web browser.
<p align="center">
9 年时间,倾情投入,用心做好一款开源堡垒机。
</p>
<picture>
<source media="(prefers-color-scheme: light)" srcset="https://www.jumpserver.com/images/jumpserver-arch-light.png">
<source media="(prefers-color-scheme: dark)" srcset="https://www.jumpserver.com/images/jumpserver-arch-dark.png">
<img src="https://github.com/user-attachments/assets/dd612f3d-c958-4f84-b164-f31b75454d7f" alt="Theme-based Image">
</picture>
------------------------------
JumpServer 是广受欢迎的开源堡垒机,是符合 4A 规范的专业运维安全审计系统。
JumpServer 堡垒机帮助企业以更安全的方式管控和登录各种类型的资产,包括:
## Quickstart
- **SSH**: Linux / Unix / 网络设备 等;
- **Windows**: Web 方式连接 / 原生 RDP 连接;
- **数据库**: MySQL / MariaDB / PostgreSQL / Oracle / SQLServer / ClickHouse 等;
- **NoSQL**: Redis / MongoDB 等;
- **GPT**: ChatGPT 等;
- **云服务**: Kubernetes / VMware vSphere 等;
- **Web 站点**: 各类系统的 Web 管理后台;
- **应用**: 通过 Remote App 连接各类应用。
Prepare a clean Linux Server ( 64 bit, >= 4c8g )
## 产品特色
```sh
curl -sSL https://github.com/jumpserver/jumpserver/releases/latest/download/quick_start.sh | bash
```
- **开源**: 零门槛,线上快速获取和安装;
- **无插件**: 仅需浏览器,极致的 Web Terminal 使用体验;
- **分布式**: 支持分布式部署和横向扩展,轻松支持大规模并发访问;
- **多云支持**: 一套系统,同时管理不同云上面的资产;
- **多租户**: 一套系统,多个子公司或部门同时使用;
- **云端存储**: 审计录像云端存储,永不丢失;
Access JumpServer in your browser at `http://your-jumpserver-ip/`
- Username: `admin`
- Password: `ChangeMe`
## UI 展示
[![JumpServer Quickstart](https://github.com/user-attachments/assets/0f32f52b-9935-485e-8534-336c63389612)](https://www.youtube.com/watch?v=UlGYRbKrpgY "JumpServer Quickstart")
![UI展示](https://docs.jumpserver.org/zh/v3/img/dashboard.png)
## Screenshots
<table style="border-collapse: collapse; border: 1px solid black;">
<tr>
<td style="padding: 5px;background-color:#fff;"><img src= "https://github.com/jumpserver/jumpserver/assets/32935519/99fabe5b-0475-4a53-9116-4c370a1426c4" alt="JumpServer Console" /></td>
<td style="padding: 5px;background-color:#fff;"><img src= "https://github.com/user-attachments/assets/7c1f81af-37e8-4f07-8ac9-182895e1062e" alt="JumpServer PAM" /></td>    
</tr>
<tr>
<td style="padding: 5px;background-color:#fff;"><img src= "https://github.com/jumpserver/jumpserver/assets/32935519/a424d731-1c70-4108-a7d8-5bbf387dda9a" alt="JumpServer Audits" /></td>
<td style="padding: 5px;background-color:#fff;"><img src= "https://github.com/jumpserver/jumpserver/assets/32935519/393d2c27-a2d0-4dea-882d-00ed509e00c9" alt="JumpServer Workbench" /></td>
</tr>
<tr>
<td style="padding: 5px;background-color:#fff;"><img src= "https://github.com/user-attachments/assets/eaa41f66-8cc8-4f01-a001-0d258501f1c9" alt="JumpServer RBAC" /></td>     
<td style="padding: 5px;background-color:#fff;"><img src= "https://github.com/jumpserver/jumpserver/assets/32935519/3a2611cd-8902-49b8-b82b-2a6dac851f3e" alt="JumpServer Settings" /></td>
</tr>
<tr>
<td style="padding: 5px;background-color:#fff;"><img src= "https://github.com/jumpserver/jumpserver/assets/32935519/1e236093-31f7-4563-8eb1-e36d865f1568" alt="JumpServer SSH" /></td>
<td style="padding: 5px;background-color:#fff;"><img src= "https://github.com/jumpserver/jumpserver/assets/32935519/69373a82-f7ab-41e8-b763-bbad2ba52167" alt="JumpServer RDP" /></td>
</tr>
<tr>
<td style="padding: 5px;background-color:#fff;"><img src= "https://github.com/jumpserver/jumpserver/assets/32935519/5bed98c6-cbe8-4073-9597-d53c69dc3957" alt="JumpServer K8s" /></td>
<td style="padding: 5px;background-color:#fff;"><img src= "https://github.com/jumpserver/jumpserver/assets/32935519/b80ad654-548f-42bc-ba3d-c1cfdf1b46d6" alt="JumpServer DB" /></td>
</tr>
</table>
## 在线体验
## Components
- 环境地址:<https://demo.jumpserver.org/>
JumpServer consists of multiple key components, which collectively form the functional framework of JumpServer, providing users with comprehensive capabilities for operations management and security control.
| :warning: 注意 |
|:-----------------------------|
| 该环境仅作体验目的使用,我们会定时清理、重置数据! |
| 请勿修改体验环境用户的密码! |
| 请勿在环境中添加业务生产环境地址、用户名密码等敏感信息! |
| Project | Status | Description |
|--------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------|
| [Lina](https://github.com/jumpserver/lina) | <a href="https://github.com/jumpserver/lina/releases"><img alt="Lina release" src="https://img.shields.io/github/release/jumpserver/lina.svg" /></a> | JumpServer Web UI |
| [Luna](https://github.com/jumpserver/luna) | <a href="https://github.com/jumpserver/luna/releases"><img alt="Luna release" src="https://img.shields.io/github/release/jumpserver/luna.svg" /></a> | JumpServer Web Terminal |
| [KoKo](https://github.com/jumpserver/koko) | <a href="https://github.com/jumpserver/koko/releases"><img alt="Koko release" src="https://img.shields.io/github/release/jumpserver/koko.svg" /></a> | JumpServer Character Protocol Connector |
| [Lion](https://github.com/jumpserver/lion) | <a href="https://github.com/jumpserver/lion/releases"><img alt="Lion release" src="https://img.shields.io/github/release/jumpserver/lion.svg" /></a> | JumpServer Graphical Protocol Connector |
| [Chen](https://github.com/jumpserver/chen) | <a href="https://github.com/jumpserver/chen/releases"><img alt="Chen release" src="https://img.shields.io/github/release/jumpserver/chen.svg" /> | JumpServer Web DB |
| [Tinker](https://github.com/jumpserver/tinker) | <img alt="Tinker" src="https://img.shields.io/badge/release-private-red" /> | JumpServer Remote Application Connector (Windows) |
| [Panda](https://github.com/jumpserver/Panda) | <img alt="Panda" src="https://img.shields.io/badge/release-private-red" /> | JumpServer EE Remote Application Connector (Linux) |
| [Razor](https://github.com/jumpserver/razor) | <img alt="Chen" src="https://img.shields.io/badge/release-private-red" /> | JumpServer EE RDP Proxy Connector |
| [Magnus](https://github.com/jumpserver/magnus) | <img alt="Magnus" src="https://img.shields.io/badge/release-private-red" /> | JumpServer EE Database Proxy Connector |
| [Nec](https://github.com/jumpserver/nec) | <img alt="Nec" src="https://img.shields.io/badge/release-private-red" /> | JumpServer EE VNC Proxy Connector |
| [Facelive](https://github.com/jumpserver/facelive) | <img alt="Facelive" src="https://img.shields.io/badge/release-private-red" /> | JumpServer EE Facial Recognition |
## 快速开始
## Third-party projects
- [jumpserver-grafana-dashboard](https://github.com/acerrah/jumpserver-grafana-dashboard) JumpServer with grafana dashboard
- [快速入门](https://docs.jumpserver.org/zh/v3/quick_start/)
- [产品文档](https://docs.jumpserver.org)
- [在线学习](https://edu.fit2cloud.com/page/2635362)
- [知识库](https://kb.fit2cloud.com/categories/jumpserver)
## Contributing
## 案例研究
Welcome to submit PR to contribute. Please refer to [CONTRIBUTING.md][contributing-link] for guidelines.
- [腾讯音乐娱乐集团基于JumpServer的安全运维审计解决方案](https://blog.fit2cloud.com/?p=a04cdf0d-6704-4d18-9b40-9180baecd0e2)
- [腾讯海外游戏基于JumpServer构建游戏安全运营能力](https://blog.fit2cloud.com/?p=3704)
- [万华化学通过JumpServer管理全球化分布式IT资产并且实现与云管平台的联动](https://blog.fit2cloud.com/?p=3504)
- [雪花啤酒JumpServer堡垒机使用体会](https://blog.fit2cloud.com/?p=3412)
- [顺丰科技JumpServer 堡垒机护航顺丰科技超大规模资产安全运维](https://blog.fit2cloud.com/?p=1147)
- [沐瞳游戏通过JumpServer管控多项目分布式资产](https://blog.fit2cloud.com/?p=3213)
- [携程JumpServer 堡垒机部署与运营实战](https://blog.fit2cloud.com/?p=851)
- [大智慧JumpServer 堡垒机让“大智慧”的混合 IT 运维更智慧](https://blog.fit2cloud.com/?p=882)
- [小红书JumpServer 堡垒机大规模资产跨版本迁移之路](https://blog.fit2cloud.com/?p=516)
- [中手游JumpServer堡垒机助力中手游提升多云环境下安全运维能力](https://blog.fit2cloud.com/?p=732)
- [中通快递JumpServer主机安全运维实践](https://blog.fit2cloud.com/?p=708)
- [东方明珠JumpServer高效管控异构化、分布式云端资产](https://blog.fit2cloud.com/?p=687)
- [江苏农信JumpServer堡垒机助力行业云安全运维](https://blog.fit2cloud.com/?p=666)
## License
## 社区交流
Copyright (c) 2014-2025 FIT2CLOUD, All rights reserved.
如果您在使用过程中有任何疑问或对建议,欢迎提交 [GitHub Issue](https://github.com/jumpserver/jumpserver/issues/new/choose)。
您也可以到我们的 [社区论坛](https://bbs.fit2cloud.com/c/js/5) 当中进行交流沟通。
### 参与贡献
欢迎提交 PR 参与贡献。 参考 [CONTRIBUTING.md](https://github.com/jumpserver/jumpserver/blob/dev/CONTRIBUTING.md)
## 组件项目
| 项目 | 状态 | 描述 |
|--------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------|
| [Lina](https://github.com/jumpserver/lina) | <a href="https://github.com/jumpserver/lina/releases"><img alt="Lina release" src="https://img.shields.io/github/release/jumpserver/lina.svg" /></a> | JumpServer Web UI 项目 |
| [Luna](https://github.com/jumpserver/luna) | <a href="https://github.com/jumpserver/luna/releases"><img alt="Luna release" src="https://img.shields.io/github/release/jumpserver/luna.svg" /></a> | JumpServer Web Terminal 项目 |
| [KoKo](https://github.com/jumpserver/koko) | <a href="https://github.com/jumpserver/koko/releases"><img alt="Koko release" src="https://img.shields.io/github/release/jumpserver/koko.svg" /></a> | JumpServer 字符协议 Connector 项目 |
| [Lion](https://github.com/jumpserver/lion-release) | <a href="https://github.com/jumpserver/lion-release/releases"><img alt="Lion release" src="https://img.shields.io/github/release/jumpserver/lion-release.svg" /></a> | JumpServer 图形协议 Connector 项目,依赖 [Apache Guacamole](https://guacamole.apache.org/) |
| [Razor](https://github.com/jumpserver/razor) | <img alt="Chen" src="https://img.shields.io/badge/release-私有发布-red" /> | JumpServer RDP 代理 Connector 项目 |
| [Tinker](https://github.com/jumpserver/tinker) | <img alt="Tinker" src="https://img.shields.io/badge/release-私有发布-red" /> | JumpServer 远程应用 Connector 项目 (Windows) |
| [Panda](https://github.com/jumpserver/Panda) | <img alt="Panda" src="https://img.shields.io/badge/release-私有发布-red" /> | JumpServer 远程应用 Connector 项目 (Linux) |
| [Magnus](https://github.com/jumpserver/magnus-release) | <a href="https://github.com/jumpserver/magnus-release/releases"><img alt="Magnus release" src="https://img.shields.io/github/release/jumpserver/magnus-release.svg" /> | JumpServer 数据库代理 Connector 项目 |
| [Chen](https://github.com/jumpserver/chen-release) | <a href="https://github.com/jumpserver/chen-release/releases"><img alt="Chen release" src="https://img.shields.io/github/release/jumpserver/chen-release.svg" /> | JumpServer Web DB 项目,替代原来的 OmniDB |
| [Kael](https://github.com/jumpserver/kael) | <a href="https://github.com/jumpserver/kael/releases"><img alt="Kael release" src="https://img.shields.io/github/release/jumpserver/kael.svg" /> | JumpServer 连接 GPT 资产的组件项目 |
| [Wisp](https://github.com/jumpserver/wisp) | <a href="https://github.com/jumpserver/wisp/releases"><img alt="Magnus release" src="https://img.shields.io/github/release/jumpserver/wisp.svg" /> | JumpServer 各系统终端组件和 Core API 通信的组件项目 |
| [Clients](https://github.com/jumpserver/clients) | <a href="https://github.com/jumpserver/clients/releases"><img alt="Clients release" src="https://img.shields.io/github/release/jumpserver/clients.svg" /> | JumpServer 客户端 项目 |
| [Installer](https://github.com/jumpserver/installer) | <a href="https://github.com/jumpserver/installer/releases"><img alt="Installer release" src="https://img.shields.io/github/release/jumpserver/installer.svg" /> | JumpServer 安装包 项目 |
## 安全说明
JumpServer是一款安全产品请参考 [基本安全建议](https://docs.jumpserver.org/zh/master/install/install_security/)
进行安装部署。如果您发现安全相关问题,请直接联系我们:
- 邮箱support@fit2cloud.com
- 电话400-052-0755
## License & Copyright
Copyright (c) 2014-2024 飞致云 FIT2CLOUD, All rights reserved.
Licensed under The GNU General Public License version 3 (GPLv3) (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
Licensed under The GNU General Public License version 3 (GPLv3) (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
https://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "
AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
language governing permissions and limitations under the License.
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an " AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
<!-- JumpServer official link -->
[docs-link]: https://jumpserver.com/docs
[discord-link]: https://discord.com/invite/W6vYXmAQG2
[deepwiki-link]: https://deepwiki.com/jumpserver/jumpserver/
[contributing-link]: https://github.com/jumpserver/jumpserver/blob/dev/CONTRIBUTING.md
<!-- JumpServer Other link-->
[license-link]: https://www.gnu.org/licenses/gpl-3.0.html
[docker-link]: https://hub.docker.com/u/jumpserver
[github-release-link]: https://github.com/jumpserver/jumpserver/releases/latest
[github-stars-link]: https://github.com/jumpserver/jumpserver
[github-issues-link]: https://github.com/jumpserver/jumpserver/issues
<!-- Shield link-->
[docs-shield]: https://img.shields.io/badge/documentation-148F76
[github-release-shield]: https://img.shields.io/github/v/release/jumpserver/jumpserver
[github-stars-shield]: https://img.shields.io/github/stars/jumpserver/jumpserver?color=%231890FF&style=flat-square   
[docker-shield]: https://img.shields.io/docker/pulls/jumpserver/jms_all.svg
[license-shield]: https://img.shields.io/github/license/jumpserver/jumpserver
[deepwiki-shield]: https://img.shields.io/badge/deepwiki-devin?color=blue
[discord-shield]: https://img.shields.io/discord/1194233267294052363?style=flat&logo=discord&logoColor=%23f5f5f5&labelColor=%235462eb&color=%235462eb

View File

@ -1,94 +0,0 @@
<p align="center"><a href="https://jumpserver.org"><img src="https://download.jumpserver.org/images/jumpserver-logo.svg" alt="JumpServer" width="300" /></a></p>
<h3 align="center">Open Source Bastion Host</h3>
<p align="center">
<a href="https://www.gnu.org/licenses/gpl-3.0.html"><img src="https://img.shields.io/github/license/jumpserver/jumpserver" alt="License: GPLv3"></a>
<a href="https://shields.io/github/downloads/jumpserver/jumpserver/total"><img src="https://shields.io/github/downloads/jumpserver/jumpserver/total" alt=" release"></a>
<a href="https://hub.docker.com/u/jumpserver"><img src="https://img.shields.io/docker/pulls/jumpserver/jms_all.svg" alt="Codacy"></a>
<a href="https://github.com/jumpserver/jumpserver"><img src="https://img.shields.io/github/stars/jumpserver/jumpserver?color=%231890FF&style=flat-square" alt="Stars"></a>
</p>
JumpServer is the world's first open-source Bastion Host and is licensed under the GPLv3. It is a 4A-compliant professional operation and maintenance security audit system.
JumpServer uses Python / Django for development, follows Web 2.0 specifications, and is equipped with an industry-leading Web Terminal solution that provides a beautiful user interface and great user experience
JumpServer adopts a distributed architecture to support multi-branch deployment across multiple cross-regional areas. The central node provides APIs, and login nodes are deployed in each branch. It can be scaled horizontally without concurrency restrictions.
Change the world by taking every little step
----
### Advantages
- Open Source: huge transparency and free to access with quick installation process.
- Distributed: support large-scale concurrent access with ease.
- No Plugin required: all you need is a browser, the ultimate Web Terminal experience.
- Multi-Cloud supported: a unified system to manage assets on different clouds at the same time
- Cloud storage: audit records are stored in the cloud. Data lost no more!
- Multi-Tenant system: multiple subsidiary companies or departments access the same system simultaneously.
- Many applications supported: link to databases, windows remote applications, and Kubernetes cluster, etc.
### JumpServer Component Projects
- [Lina](https://github.com/jumpserver/lina) JumpServer Web UI
- [Luna](https://github.com/jumpserver/luna) JumpServer Web Terminal
- [KoKo](https://github.com/jumpserver/koko) JumpServer Character protocaol Connector, replace original Python Version [Coco](https://github.com/jumpserver/coco)
- [Lion](https://github.com/jumpserver/lion-release) JumpServer Graphics protocol Connectorrely on [Apache Guacamole](https://guacamole.apache.org/)
### Contribution
If you have any good ideas or helping us to fix bugs, please submit a Pull Request and accept our thanks :)
Thanks to the following contributors for making JumpServer better everyday!
<a href="https://github.com/jumpserver/jumpserver/graphs/contributors">
<img src="https://contrib.rocks/image?repo=jumpserver/jumpserver" />
</a>
<a href="https://github.com/jumpserver/koko/graphs/contributors">
<img src="https://contrib.rocks/image?repo=jumpserver/koko" />
</a>
<a href="https://github.com/jumpserver/lina/graphs/contributors">
<img src="https://contrib.rocks/image?repo=jumpserver/lina" />
</a>
<a href="https://github.com/jumpserver/luna/graphs/contributors">
<img src="https://contrib.rocks/image?repo=jumpserver/luna" />
</a>
### Thanks to
- [Apache Guacamole](https://guacamole.apache.org/) Web page connection RDP, SSH, VNC protocol equipment. JumpServer graphical connection dependent.
- [OmniDB](https://omnidb.org/) Web page connection to databases. JumpServer Web database dependent.
### JumpServer Enterprise Version
- [Apply for it](https://jinshuju.net/f/kyOYpi)
### Case Study
- [JumpServer 堡垒机护航顺丰科技超大规模资产安全运维](https://blog.fit2cloud.com/?p=1147)
- [JumpServer 堡垒机让“大智慧”的混合 IT 运维更智慧](https://blog.fit2cloud.com/?p=882)
- [携程 JumpServer 堡垒机部署与运营实战](https://blog.fit2cloud.com/?p=851)
- [小红书的JumpServer堡垒机大规模资产跨版本迁移之路](https://blog.fit2cloud.com/?p=516)
- [JumpServer堡垒机助力中手游提升多云环境下安全运维能力](https://blog.fit2cloud.com/?p=732)
- [中通快递JumpServer主机安全运维实践](https://blog.fit2cloud.com/?p=708)
- [东方明珠JumpServer高效管控异构化、分布式云端资产](https://blog.fit2cloud.com/?p=687)
- [江苏农信JumpServer堡垒机助力行业云安全运维](https://blog.fit2cloud.com/?p=666)。
### For safety instructions
JumpServer is a security product. Please refer to [Basic Security Recommendations](https://docs.jumpserver.org/zh/master/install/install_security/) for deployment and installation.
If you find a security problem, please contact us directly
- ibuler@fit2cloud.com
- support@fit2cloud.com
- 400-052-0755
### License & Copyright
Copyright (c) 2014-2024 FIT2CLOUD Tech, Inc., All rights reserved.
Licensed under The GNU General Public License version 3 (GPLv3) (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
https://www.gnu.org/licenses/gpl-3.0.htmll
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

View File

@ -5,8 +5,7 @@ JumpServer 是一款正在成长的安全产品, 请参考 [基本安全建议
如果你发现安全问题,请直接联系我们,我们携手让世界更好:
- ibuler@fit2cloud.com
- support@fit2cloud.com
- 400-052-0755
- support@lxware.hk
# Security Policy
@ -16,6 +15,5 @@ JumpServer is a security product, The installation and development should follow
All security bugs should be reported to the contact as below:
- ibuler@fit2cloud.com
- support@fit2cloud.com
- 400-052-0755
- support@lxware.hk

View File

@ -1,4 +1,6 @@
from .account import *
from .application import *
from .pam_dashboard import *
from .task import *
from .template import *
from .virtual import *

View File

@ -1,20 +1,29 @@
from django.db import transaction
from django.shortcuts import get_object_or_404
from django.utils.translation import gettext_lazy as _
from rest_framework.decorators import action
from rest_framework.generics import ListAPIView, CreateAPIView
from rest_framework.response import Response
from rest_framework.status import HTTP_200_OK
from accounts import serializers
from accounts.filters import AccountFilterSet
from accounts.const import ChangeSecretRecordStatusChoice
from accounts.filters import AccountFilterSet, NodeFilterBackend
from accounts.mixins import AccountRecordViewLogMixin
from accounts.models import Account
from accounts.models import Account, ChangeSecretRecord
from assets.const.gpt import create_or_update_chatx_resources
from assets.models import Asset, Node
from authentication.permissions import UserConfirmation, ConfirmType
from common.api.mixin import ExtraFilterFieldsMixin
from common.drf.filters import AttrRulesFilterBackend
from common.permissions import IsValidUser
from common.utils import lazyproperty, get_logger
from orgs.mixins.api import OrgBulkModelViewSet
from orgs.utils import tmp_to_root_org
from rbac.permissions import RBACPermission
logger = get_logger(__file__)
__all__ = [
'AccountViewSet', 'AccountSecretsViewSet',
'AccountHistoriesSecretAPI', 'AssetAccountBulkCreateApi',
@ -24,6 +33,7 @@ __all__ = [
class AccountViewSet(OrgBulkModelViewSet):
model = Account
search_fields = ('username', 'name', 'asset__name', 'asset__address', 'comment')
extra_filter_backends = [AttrRulesFilterBackend, NodeFilterBackend]
filterset_class = AccountFilterSet
serializer_classes = {
'default': serializers.AccountSerializer,
@ -33,9 +43,22 @@ class AccountViewSet(OrgBulkModelViewSet):
'partial_update': ['accounts.change_account'],
'su_from_accounts': 'accounts.view_account',
'clear_secret': 'accounts.change_account',
'move_to_assets': 'accounts.delete_account',
'copy_to_assets': 'accounts.add_account',
'chat': 'accounts.view_account',
}
export_as_zip = True
def get_queryset(self):
queryset = super().get_queryset()
asset_id = self.request.query_params.get('asset') or self.request.query_params.get('asset_id')
if not asset_id:
return queryset
asset = get_object_or_404(Asset, pk=asset_id)
queryset = asset.all_accounts.all()
return queryset
@action(methods=['get'], detail=False, url_path='su-from-accounts')
def su_from_accounts(self, request, *args, **kwargs):
account_id = request.query_params.get('account')
@ -58,18 +81,25 @@ class AccountViewSet(OrgBulkModelViewSet):
permission_classes=[IsValidUser]
)
def username_suggestions(self, request, *args, **kwargs):
asset_ids = request.data.get('assets', [])
raw_asset_ids = request.data.get('assets', [])
node_ids = request.data.get('nodes', [])
username = request.data.get('username', '')
accounts = Account.objects.all()
asset_ids = set(raw_asset_ids)
if node_ids:
nodes = Node.objects.filter(id__in=node_ids)
node_asset_ids = Node.get_nodes_all_assets(*nodes).values_list('id', flat=True)
asset_ids.extend(node_asset_ids)
node_asset_qs = Node.get_nodes_all_assets(*nodes).values_list('id', flat=True)
asset_ids |= {str(u) for u in node_asset_qs}
if asset_ids:
accounts = accounts.filter(asset_id__in=list(set(asset_ids)))
through = Asset.directory_services.through
ds_qs = through.objects.filter(asset_id__in=asset_ids) \
.values_list('directoryservice_id', flat=True)
asset_ids |= {str(u) for u in ds_qs}
accounts = Account.objects.filter(asset_id__in=list(asset_ids))
else:
accounts = Account.objects.all()
if username:
accounts = accounts.filter(username__icontains=username)
@ -86,6 +116,52 @@ class AccountViewSet(OrgBulkModelViewSet):
self.model.objects.filter(id__in=account_ids).update(secret=None)
return Response(status=HTTP_200_OK)
def _copy_or_move_to_assets(self, request, move=False):
account = self.get_object()
asset_ids = request.data.get('assets', [])
assets = Asset.objects.filter(id__in=asset_ids)
field_names = [
'name', 'username', 'secret_type', 'secret',
'privileged', 'is_active', 'source', 'source_id', 'comment'
]
account_data = {field: getattr(account, field) for field in field_names}
creation_results = {}
success_count = 0
for asset in assets:
account_data['asset'] = asset
creation_results[asset] = {'state': 'created'}
try:
with transaction.atomic():
self.model.objects.create(**account_data)
success_count += 1
except Exception as e:
logger.debug(f'{"Move" if move else "Copy"} to assets error: {e}')
creation_results[asset] = {'error': _('Account already exists'), 'state': 'error'}
results = [{'asset': str(asset), **res} for asset, res in creation_results.items()]
if move and success_count > 0:
account.delete()
return Response(results, status=HTTP_200_OK)
@action(methods=['post'], detail=True, url_path='move-to-assets')
def move_to_assets(self, request, *args, **kwargs):
return self._copy_or_move_to_assets(request, move=True)
@action(methods=['post'], detail=True, url_path='copy-to-assets')
def copy_to_assets(self, request, *args, **kwargs):
return self._copy_or_move_to_assets(request, move=False)
@action(methods=['get'], detail=False, url_path='chat')
def chat(self, request, *args, **kwargs):
with tmp_to_root_org():
__, account = create_or_update_chatx_resources()
serializer = self.get_serializer(account)
return Response(serializer.data)
class AccountSecretsViewSet(AccountRecordViewLogMixin, AccountViewSet):
"""
@ -124,18 +200,33 @@ class AccountHistoriesSecretAPI(ExtraFilterFieldsMixin, AccountRecordViewLogMixi
rbac_perms = {
'GET': 'accounts.view_accountsecret',
}
queryset = Account.history.model.objects.none()
@lazyproperty
def account(self) -> Account:
return get_object_or_404(Account, pk=self.kwargs.get('pk'))
def get_object(self):
return get_object_or_404(Account, pk=self.kwargs.get('pk'))
return self.account
@lazyproperty
def latest_history(self):
return self.account.history.first()
@property
def latest_change_secret_record(self) -> ChangeSecretRecord:
return self.account.changesecretrecords.filter(
status=ChangeSecretRecordStatusChoice.pending
).order_by('-date_created').first()
@staticmethod
def filter_spm_queryset(resource_ids, queryset):
return queryset.filter(history_id__in=resource_ids)
def get_queryset(self):
account = self.get_object()
account = self.account
histories = account.history.all()
latest_history = account.history.first()
latest_history = self.latest_history
if not latest_history:
return histories
if account.secret != latest_history.secret:
@ -144,3 +235,25 @@ class AccountHistoriesSecretAPI(ExtraFilterFieldsMixin, AccountRecordViewLogMixi
return histories
histories = histories.exclude(history_id=latest_history.history_id)
return histories
def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset)
queryset = list(queryset)
latest_history = self.latest_history
if not latest_history:
return queryset
latest_change_secret_record = self.latest_change_secret_record
if not latest_change_secret_record:
return queryset
if latest_change_secret_record.date_created > latest_history.history_date:
temp_history = self.model(
secret=latest_change_secret_record.new_secret,
secret_type=self.account.secret_type,
version=latest_history.version,
history_date=latest_change_secret_record.date_created,
)
queryset = [temp_history] + queryset
return queryset

View File

@ -0,0 +1,84 @@
import os
from django.conf import settings
from django.utils.translation import gettext_lazy as _, get_language
from rest_framework.decorators import action
from rest_framework.response import Response
from accounts import serializers
from accounts.models import IntegrationApplication
from audits.models import IntegrationApplicationLog
from authentication.permissions import UserConfirmation, ConfirmType
from common.exceptions import JMSException
from common.permissions import IsValidUser
from common.utils import get_request_ip
from orgs.mixins.api import OrgBulkModelViewSet
from rbac.permissions import RBACPermission
class IntegrationApplicationViewSet(OrgBulkModelViewSet):
model = IntegrationApplication
search_fields = ('name', 'comment')
serializer_classes = {
'default': serializers.IntegrationApplicationSerializer,
'get_account_secret': serializers.IntegrationAccountSecretSerializer
}
rbac_perms = {
'get_once_secret': 'accounts.change_integrationapplication',
'get_account_secret': 'accounts.view_integrationapplication'
}
def read_file(self, path):
if os.path.exists(path):
with open(path, 'r', encoding='utf-8') as file:
return file.read()
return ''
@action(
['GET'], detail=False, url_path='sdks',
permission_classes=[IsValidUser]
)
def get_sdks_info(self, request, *args, **kwargs):
code_suffix_mapper = {
'python': 'py',
'java': 'java',
'go': 'go',
'node': 'js',
'curl': 'sh',
}
sdk_language = request.query_params.get('language', 'python')
sdk_path = os.path.join(settings.APPS_DIR, 'accounts', 'demos', sdk_language)
readme_path = os.path.join(sdk_path, f'README.{get_language()}.md')
demo_path = os.path.join(sdk_path, f'demo.{code_suffix_mapper[sdk_language]}')
readme_content = self.read_file(readme_path)
demo_content = self.read_file(demo_path)
return Response(data={'readme': readme_content, 'code': demo_content})
@action(
['GET'], detail=True, url_path='secret',
permission_classes=[RBACPermission, UserConfirmation.require(ConfirmType.MFA)]
)
def get_once_secret(self, request, *args, **kwargs):
instance = self.get_object()
return Response(data={'id': instance.id, 'secret': instance.secret})
@action(['GET'], detail=False, url_path='account-secret',
permission_classes=[RBACPermission])
def get_account_secret(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.query_params)
if not serializer.is_valid():
return Response({'error': serializer.errors}, status=400)
service = request.user
account = service.get_account(**serializer.data)
if not account:
msg = _('Account not found')
raise JMSException(code='Not found', detail='%s' % msg)
asset = account.asset
IntegrationApplicationLog.objects.create(
remote_addr=get_request_ip(request), service=service.name, service_id=service.id,
account=f'{account.name}({account.username})', asset=f'{asset.name}({asset.address})',
)
return Response(data={'id': request.user.id, 'secret': account.secret})

View File

@ -0,0 +1,130 @@
# -*- coding: utf-8 -*-
#
from collections import defaultdict
from django.db.models import Count, F, Q
from django.http.response import JsonResponse
from rest_framework.views import APIView
from accounts.models import (
Account, GatherAccountsAutomation,
PushAccountAutomation, BackupAccountAutomation,
AccountRisk, IntegrationApplication, ChangeSecretAutomation
)
from assets.const import AllTypes
from common.utils.timezone import local_monday
__all__ = ['PamDashboardApi']
class PamDashboardApi(APIView):
http_method_names = ['get']
rbac_perms = {
'GET': 'rbac.view_pam',
}
@staticmethod
def get_type_to_accounts():
result = Account.objects.annotate(type=F('asset__platform__type')) \
.values('type').order_by('type').annotate(total=Count(1))
all_types_dict = dict(AllTypes.choices())
return [
{**i, 'label': all_types_dict.get(i['type'], i['type'])}
for i in result
]
@staticmethod
def get_account_risk_data(_all, query_params):
agg_map = {
'total_long_time_no_login_accounts': ('long_time_no_login_count', Q(risk='long_time_no_login')),
'total_new_found_accounts': ('new_found_count', Q(risk='new_found')),
'total_groups_changed_accounts': ('groups_changed_count', Q(risk='groups_changed')),
'total_sudoers_changed_accounts': ('sudoers_changed_count', Q(risk='sudoers_changed')),
'total_authorized_keys_changed_accounts': (
'authorized_keys_changed_count', Q(risk='authorized_keys_changed')),
'total_account_deleted_accounts': ('account_deleted_count', Q(risk='account_deleted')),
'total_password_expired_accounts': ('password_expired_count', Q(risk='password_expired')),
'total_long_time_password_accounts': ('long_time_password_count', Q(risk='long_time_password')),
'total_weak_password_accounts': ('weak_password_count', Q(risk='weak_password')),
'total_leaked_password_accounts': ('leaked_password_count', Q(risk='leaked_password')),
'total_repeated_password_accounts': ('repeated_password_count', Q(risk='repeated_password')),
}
aggregations = {
agg_key: Count('id', distinct=True, filter=agg_filter)
for param_key, (agg_key, agg_filter) in agg_map.items()
if _all or query_params.get(param_key)
}
data = {}
if aggregations:
account_stats = AccountRisk.objects.aggregate(**aggregations)
data = {param_key: account_stats.get(agg_key) for param_key, (agg_key, _) in agg_map.items() if
agg_key in account_stats}
return data
@staticmethod
def get_account_data(_all, query_params):
agg_map = {
'total_accounts': ('total_count', Count('id')),
'total_privileged_accounts': ('privileged_count', Count('id', filter=Q(privileged=True))),
'total_connectivity_ok_accounts': ('connectivity_ok_count', Count('id', filter=Q(connectivity='ok'))),
'total_secret_reset_accounts': ('secret_reset_count', Count('id', filter=Q(secret_reset=True))),
'total_valid_accounts': ('valid_count', Count('id', filter=Q(is_active=True))),
'total_week_add_accounts': ('week_add_count', Count('id', filter=Q(date_created__gte=local_monday()))),
}
aggregations = {
agg_key: agg_expr
for param_key, (agg_key, agg_expr) in agg_map.items()
if _all or query_params.get(param_key)
}
data = {}
account_stats = Account.objects.aggregate(**aggregations)
for param_key, (agg_key, __) in agg_map.items():
if agg_key in account_stats:
data[param_key] = account_stats[agg_key]
if _all or query_params.get('total_ordinary_accounts'):
if 'total_count' in account_stats and 'privileged_count' in account_stats:
data['total_ordinary_accounts'] = \
account_stats['total_count'] - account_stats['privileged_count']
return data
@staticmethod
def get_automation_counts(_all, query_params):
automation_counts = defaultdict(int)
automation_models = {
'total_count_change_secret_automation': ChangeSecretAutomation,
'total_count_gathered_account_automation': GatherAccountsAutomation,
'total_count_push_account_automation': PushAccountAutomation,
'total_count_backup_account_automation': BackupAccountAutomation,
'total_count_integration_application': IntegrationApplication,
}
for param_key, model in automation_models.items():
if _all or query_params.get(param_key):
automation_counts[param_key] = model.objects.count()
return automation_counts
def get(self, request, *args, **kwargs):
query_params = self.request.query_params
_all = query_params.get('all')
data = {}
data.update(self.get_account_data(_all, query_params))
data.update(self.get_account_risk_data(_all, query_params))
data.update(self.get_automation_counts(_all, query_params))
if _all or query_params.get('total_count_type_to_accounts'):
data.update({
'total_count_type_to_accounts': self.get_type_to_accounts(),
})
return JsonResponse(data, status=200)

View File

@ -43,6 +43,7 @@ class AccountTemplateViewSet(OrgBulkModelViewSet):
search_fields = ('username', 'name')
serializer_classes = {
'default': serializers.AccountTemplateSerializer,
'retrieve': serializers.AccountDetailTemplateSerializer,
}
rbac_perms = {
'su_from_account_templates': 'accounts.view_accounttemplate',

View File

@ -12,6 +12,8 @@ class VirtualAccountViewSet(OrgBulkModelViewSet):
filterset_fields = ('alias',)
def get_queryset(self):
if getattr(self, "swagger_fake_view", False):
return VirtualAccount.objects.none()
return VirtualAccount.get_or_init_queryset()
def get_object(self, ):

View File

@ -1,5 +1,7 @@
from .backup import *
from .base import *
from .change_secret import *
from .gather_accounts import *
from .change_secret_dashboard import *
from .check_account import *
from .gather_account import *
from .push_account import *

View File

@ -1,41 +1,36 @@
# -*- coding: utf-8 -*-
#
from rest_framework import status, viewsets
from rest_framework.response import Response
from accounts import serializers
from accounts.const import AutomationTypes
from accounts.models import (
AccountBackupAutomation, AccountBackupExecution
BackupAccountAutomation
)
from accounts.tasks import execute_account_backup_task
from common.const.choices import Trigger
from orgs.mixins.api import OrgBulkModelViewSet
from .base import AutomationExecutionViewSet
__all__ = [
'AccountBackupPlanViewSet', 'AccountBackupPlanExecutionViewSet'
'BackupAccountViewSet', 'BackupAccountExecutionViewSet'
]
class AccountBackupPlanViewSet(OrgBulkModelViewSet):
model = AccountBackupAutomation
class BackupAccountViewSet(OrgBulkModelViewSet):
model = BackupAccountAutomation
filterset_fields = ('name',)
search_fields = filterset_fields
serializer_class = serializers.AccountBackupSerializer
serializer_class = serializers.BackupAccountSerializer
class AccountBackupPlanExecutionViewSet(viewsets.ModelViewSet):
serializer_class = serializers.AccountBackupPlanExecutionSerializer
search_fields = ('trigger', 'plan__name')
filterset_fields = ('trigger', 'plan_id', 'plan__name')
http_method_names = ['get', 'post', 'options']
class BackupAccountExecutionViewSet(AutomationExecutionViewSet):
rbac_perms = (
("list", "accounts.view_backupaccountexecution"),
("retrieve", "accounts.view_backupaccountexecution"),
("create", "accounts.add_backupaccountexecution"),
("report", "accounts.view_backupaccountexecution"),
)
tp = AutomationTypes.backup_account
def get_queryset(self):
queryset = AccountBackupExecution.objects.all()
queryset = super().get_queryset()
queryset = queryset.filter(type=self.tp)
return queryset
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
pid = serializer.data.get('plan')
task = execute_account_backup_task.delay(pid=str(pid), trigger=Trigger.manual)
return Response({'task': task.id}, status=status.HTTP_201_CREATED)

View File

@ -1,8 +1,12 @@
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.utils.translation import gettext_lazy as _
from django.views.decorators.clickjacking import xframe_options_sameorigin
from rest_framework import status, mixins, viewsets
from rest_framework.decorators import action
from rest_framework.response import Response
from accounts.filters import AutomationExecutionFilterSet
from accounts.models import AutomationExecution
from accounts.tasks import execute_account_automation_task
from assets import serializers
@ -13,7 +17,7 @@ from orgs.mixins import generics
__all__ = [
'AutomationAssetsListApi', 'AutomationRemoveAssetApi',
'AutomationAddAssetApi', 'AutomationNodeAddRemoveApi',
'AutomationExecutionViewSet',
'AutomationExecutionViewSet'
]
@ -35,9 +39,11 @@ class AutomationAssetsListApi(generics.ListAPIView):
return assets
class AutomationRemoveAssetApi(generics.RetrieveUpdateAPIView):
class AutomationRemoveAssetApi(generics.UpdateAPIView):
model = BaseAutomation
queryset = BaseAutomation.objects.all()
serializer_class = serializers.UpdateAssetSerializer
http_method_names = ['patch']
def update(self, request, *args, **kwargs):
instance = self.get_object()
@ -52,9 +58,11 @@ class AutomationRemoveAssetApi(generics.RetrieveUpdateAPIView):
return Response({'msg': 'ok'})
class AutomationAddAssetApi(generics.RetrieveUpdateAPIView):
class AutomationAddAssetApi(generics.UpdateAPIView):
model = BaseAutomation
queryset = BaseAutomation.objects.all()
serializer_class = serializers.UpdateAssetSerializer
http_method_names = ['patch']
def update(self, request, *args, **kwargs):
instance = self.get_object()
@ -68,9 +76,10 @@ class AutomationAddAssetApi(generics.RetrieveUpdateAPIView):
return Response({"error": serializer.errors})
class AutomationNodeAddRemoveApi(generics.RetrieveUpdateAPIView):
class AutomationNodeAddRemoveApi(generics.UpdateAPIView):
model = BaseAutomation
serializer_class = serializers.UpdateNodeSerializer
http_method_names = ['patch']
def update(self, request, *args, **kwargs):
action_params = ['add', 'remove']
@ -97,8 +106,8 @@ class AutomationExecutionViewSet(
):
search_fields = ('trigger', 'automation__name')
filterset_fields = ('trigger', 'automation_id', 'automation__name')
filterset_class = AutomationExecutionFilterSet
serializer_class = serializers.AutomationExecutionSerializer
tp: str
def get_queryset(self):
@ -113,3 +122,10 @@ class AutomationExecutionViewSet(
pid=str(automation.pk), trigger=Trigger.manual, tp=self.tp
)
return Response({'task': task.id}, status=status.HTTP_201_CREATED)
@xframe_options_sameorigin
@action(methods=['get'], detail=True, url_path='report')
def report(self, request, *args, **kwargs):
execution = self.get_object()
report = execution.manager.gen_report()
return HttpResponse(report)

View File

@ -1,15 +1,20 @@
# -*- coding: utf-8 -*-
#
from django.db.models import Max, Q, Subquery, OuterRef
from rest_framework import status, mixins
from rest_framework.decorators import action
from rest_framework.response import Response
from accounts import serializers
from accounts.const import AutomationTypes
from accounts.filters import ChangeSecretRecordFilterSet
from accounts.models import ChangeSecretAutomation, ChangeSecretRecord
from accounts.const import (
AutomationTypes, ChangeSecretRecordStatusChoice
)
from accounts.filters import ChangeSecretRecordFilterSet, ChangeSecretStatusFilterSet
from accounts.models import ChangeSecretAutomation, ChangeSecretRecord, Account
from accounts.tasks import execute_automation_record_task
from accounts.utils import account_secret_task_status
from authentication.permissions import UserConfirmation, ConfirmType
from common.permissions import IsValidLicense
from orgs.mixins.api import OrgBulkModelViewSet, OrgGenericViewSet
from rbac.permissions import RBACPermission
from .base import (
@ -21,12 +26,13 @@ __all__ = [
'ChangeSecretAutomationViewSet', 'ChangeSecretRecordViewSet',
'ChangSecretExecutionViewSet', 'ChangSecretAssetsListApi',
'ChangSecretRemoveAssetApi', 'ChangSecretAddAssetApi',
'ChangSecretNodeAddRemoveApi'
'ChangSecretNodeAddRemoveApi', 'ChangeSecretStatusViewSet'
]
class ChangeSecretAutomationViewSet(OrgBulkModelViewSet):
model = ChangeSecretAutomation
permission_classes = [RBACPermission, IsValidLicense]
filterset_fields = ('name', 'secret_type', 'secret_strategy')
search_fields = filterset_fields
serializer_class = serializers.ChangeSecretAutomationSerializer
@ -34,7 +40,9 @@ class ChangeSecretAutomationViewSet(OrgBulkModelViewSet):
class ChangeSecretRecordViewSet(mixins.ListModelMixin, OrgGenericViewSet):
filterset_class = ChangeSecretRecordFilterSet
search_fields = ('asset__address',)
permission_classes = [RBACPermission, IsValidLicense]
search_fields = ('asset__address', 'account__username')
ordering_fields = ('date_finished',)
tp = AutomationTypes.change_secret
serializer_classes = {
'default': serializers.ChangeSecretRecordSerializer,
@ -43,6 +51,8 @@ class ChangeSecretRecordViewSet(mixins.ListModelMixin, OrgGenericViewSet):
rbac_perms = {
'execute': 'accounts.add_changesecretexecution',
'secret': 'accounts.view_changesecretrecord',
'dashboard': 'accounts.view_changesecretrecord',
'ignore_fail': 'accounts.view_changesecretrecord',
}
def get_permissions(self):
@ -53,19 +63,47 @@ class ChangeSecretRecordViewSet(mixins.ListModelMixin, OrgGenericViewSet):
]
return super().get_permissions()
def filter_queryset(self, queryset):
queryset = super().filter_queryset(queryset)
if self.action == 'dashboard':
return self.get_dashboard_queryset(queryset)
return queryset
@staticmethod
def get_dashboard_queryset(queryset):
recent_dates = queryset.values('account').annotate(
max_date_finished=Max('date_finished')
)
recent_success_accounts = queryset.filter(
account=OuterRef('account'),
date_finished=Subquery(
recent_dates.filter(account=OuterRef('account')).values('max_date_finished')[:1]
)
).filter(Q(status=ChangeSecretRecordStatusChoice.success))
failed_records = queryset.filter(
~Q(account__in=Subquery(recent_success_accounts.values('account'))),
status=ChangeSecretRecordStatusChoice.failed,
ignore_fail=False
)
return failed_records
def get_queryset(self):
return ChangeSecretRecord.objects.all()
return ChangeSecretRecord.get_valid_records()
@action(methods=['post'], detail=False, url_path='execute')
def execute(self, request, *args, **kwargs):
record_ids = request.data.get('record_ids')
records = self.get_queryset().filter(id__in=record_ids)
execution_count = records.values_list('execution_id', flat=True).distinct().count()
if execution_count != 1:
if not records.exists():
return Response(
{'detail': 'Only one execution is allowed to execute'},
{'detail': 'No valid records found'},
status=status.HTTP_400_BAD_REQUEST
)
record_ids = [str(_id) for _id in records.values_list('id', flat=True)]
task = execute_automation_record_task.delay(record_ids, self.tp)
return Response({'task': task.id}, status=status.HTTP_200_OK)
@ -75,19 +113,31 @@ class ChangeSecretRecordViewSet(mixins.ListModelMixin, OrgGenericViewSet):
serializer = self.get_serializer(instance)
return Response(serializer.data)
@action(methods=['get'], detail=False, url_path='dashboard')
def dashboard(self, request, *args, **kwargs):
return super().list(request, *args, **kwargs)
@action(methods=['patch'], detail=True, url_path='ignore-fail')
def ignore_fail(self, request, *args, **kwargs):
instance = self.get_object()
instance.ignore_fail = True
instance.save(update_fields=['ignore_fail'])
return Response(status=status.HTTP_200_OK)
class ChangSecretExecutionViewSet(AutomationExecutionViewSet):
rbac_perms = (
("list", "accounts.view_changesecretexecution"),
("retrieve", "accounts.view_changesecretexecution"),
("create", "accounts.add_changesecretexecution"),
("report", "accounts.view_changesecretexecution"),
)
permission_classes = [RBACPermission, IsValidLicense]
tp = AutomationTypes.change_secret
def get_queryset(self):
queryset = super().get_queryset()
queryset = queryset.filter(automation__type=self.tp)
queryset = queryset.filter(type=self.tp)
return queryset
@ -104,7 +154,27 @@ class ChangSecretAddAssetApi(AutomationAddAssetApi):
model = ChangeSecretAutomation
serializer_class = serializers.ChangeSecretUpdateAssetSerializer
class ChangSecretNodeAddRemoveApi(AutomationNodeAddRemoveApi):
model = ChangeSecretAutomation
serializer_class = serializers.ChangeSecretUpdateNodeSerializer
class ChangeSecretStatusViewSet(OrgBulkModelViewSet):
perm_model = ChangeSecretAutomation
filterset_class = ChangeSecretStatusFilterSet
serializer_class = serializers.ChangeSecretAccountSerializer
search_fields = ('username',)
permission_classes = [RBACPermission, IsValidLicense]
http_method_names = ["get", "delete", "options"]
def get_queryset(self):
account_ids = list(account_secret_task_status.account_ids)
return Account.objects.filter(id__in=account_ids).select_related('asset')
def bulk_destroy(self, request, *args, **kwargs):
account_ids = request.data.get('account_ids')
if isinstance(account_ids, str):
account_ids = [account_ids]
for _id in account_ids:
account_secret_task_status.clear(_id)
return Response(status=status.HTTP_200_OK)

View File

@ -0,0 +1,186 @@
# -*- coding: utf-8 -*-
#
from collections import defaultdict
from django.core.cache import cache
from django.http.response import JsonResponse
from django.utils import timezone
from rest_framework.views import APIView
from accounts.const import AutomationTypes, ChangeSecretRecordStatusChoice
from accounts.models import ChangeSecretAutomation, AutomationExecution, ChangeSecretRecord
from assets.models import Node, Asset
from common.const import Status
from common.permissions import IsValidLicense
from common.utils import lazyproperty
from common.utils.timezone import local_zero_hour, local_now
from ops.celery import app
from rbac.permissions import RBACPermission
__all__ = ['ChangeSecretDashboardApi']
class ChangeSecretDashboardApi(APIView):
http_method_names = ['get']
rbac_perms = {
'GET': 'accounts.view_changesecretautomation',
}
permission_classes = [RBACPermission, IsValidLicense]
tp = AutomationTypes.change_secret
task_name = 'accounts.tasks.automation.execute_account_automation_task'
ongoing_change_secret_cache_key = "ongoing_change_secret_cache_key"
@lazyproperty
def days(self):
count = self.request.query_params.get('days', 1)
return int(count)
@property
def days_to_datetime(self):
if self.days == 1:
return local_zero_hour()
return local_now() - timezone.timedelta(days=self.days)
def get_queryset_date_filter(self, qs, query_field='date_updated'):
return qs.filter(**{f'{query_field}__gte': self.days_to_datetime})
@lazyproperty
def date_range_list(self):
return [
(local_now() - timezone.timedelta(days=i)).date()
for i in range(self.days - 1, -1, -1)
]
def filter_by_date_range(self, queryset, field_name):
date_range_bounds = self.days_to_datetime.date(), (local_now() + timezone.timedelta(days=1)).date()
return queryset.filter(**{f'{field_name}__range': date_range_bounds})
def calculate_daily_metrics(self, queryset, date_field):
filtered_queryset = self.filter_by_date_range(queryset, date_field)
results = filtered_queryset.values_list(date_field, 'status')
status_counts = defaultdict(lambda: defaultdict(int))
for date_finished, status in results:
dt_local = timezone.localtime(date_finished)
date_str = str(dt_local.date())
if status == ChangeSecretRecordStatusChoice.failed:
status_counts[date_str]['failed'] += 1
elif status == ChangeSecretRecordStatusChoice.success:
status_counts[date_str]['success'] += 1
metrics = defaultdict(list)
for date in self.date_range_list:
date_str = str(date)
for status in ['success', 'failed']:
metrics[status].append(status_counts[date_str].get(status, 0))
return metrics
def get_daily_success_and_failure_metrics(self):
metrics = self.calculate_daily_metrics(self.change_secret_records_queryset, 'date_finished')
return metrics.get('success', []), metrics.get('failed', [])
@lazyproperty
def change_secrets_queryset(self):
return ChangeSecretAutomation.objects.all()
@lazyproperty
def change_secret_records_queryset(self):
return ChangeSecretRecord.get_valid_records()
def get_change_secret_asset_queryset(self):
qs = self.change_secrets_queryset
node_ids = qs.values_list('nodes', flat=True).distinct()
nodes = Node.objects.filter(id__in=node_ids).only('id', 'key')
node_asset_ids = Node.get_nodes_all_assets(*nodes).values_list('id', flat=True)
direct_asset_ids = qs.values_list('assets', flat=True).distinct()
asset_ids = set(list(direct_asset_ids) + list(node_asset_ids))
return Asset.objects.filter(id__in=asset_ids)
def get_filtered_counts(self, qs, field=None):
if field is None:
return qs.count()
return self.get_queryset_date_filter(qs, field).count()
def get_status_counts(self, executions):
executions = executions.filter(type=self.tp)
total, failed, success = 0, 0, 0
for status in executions.values_list('status', flat=True):
total += 1
if status in [Status.failed, Status.error]:
failed += 1
elif status == Status.success:
success += 1
return {
'total_count_change_secret_executions': total,
'total_count_success_change_secret_executions': success,
'total_count_failed_change_secret_executions': failed,
}
def get(self, request, *args, **kwargs):
query_params = self.request.query_params
data = {}
_all = query_params.get('all')
if _all or query_params.get('total_count_change_secrets'):
data['total_count_change_secrets'] = self.get_filtered_counts(
self.change_secrets_queryset
)
if _all or query_params.get('total_count_periodic_change_secrets'):
data['total_count_periodic_change_secrets'] = self.get_filtered_counts(
self.change_secrets_queryset.filter(is_periodic=True)
)
if _all or query_params.get('total_count_change_secret_assets'):
data['total_count_change_secret_assets'] = self.get_change_secret_asset_queryset().count()
if _all or query_params.get('total_count_change_secret_status'):
executions = self.get_queryset_date_filter(AutomationExecution.objects.all(), 'date_start')
data.update(self.get_status_counts(executions))
if _all or query_params.get('daily_success_and_failure_metrics'):
success, failed = self.get_daily_success_and_failure_metrics()
data.update({
'dates_metrics_date': [date.strftime('%m-%d') for date in self.date_range_list] or ['0'],
'dates_metrics_total_count_success': success,
'dates_metrics_total_count_failed': failed,
})
if _all or query_params.get('total_count_ongoing_change_secret'):
ongoing_counts = cache.get(self.ongoing_change_secret_cache_key)
if ongoing_counts is None:
execution_ids = []
inspect = app.control.inspect()
try:
active_tasks = inspect.active()
except Exception:
active_tasks = None
if active_tasks:
for tasks in active_tasks.values():
for task in tasks:
_id = task.get('id')
name = task.get('name')
tp = task.get('kwargs', {}).get('tp')
if name == self.task_name and tp == self.tp:
execution_ids.append(_id)
snapshots = AutomationExecution.objects.filter(id__in=execution_ids).values_list('snapshot', flat=True)
asset_ids = {asset for i in snapshots for asset in i.get('assets', [])}
account_ids = {account for i in snapshots for account in i.get('accounts', [])}
ongoing_counts = (len(execution_ids), len(asset_ids), len(account_ids))
data['total_count_ongoing_change_secret'] = ongoing_counts[0]
data['total_count_ongoing_change_secret_assets'] = ongoing_counts[1]
data['total_count_ongoing_change_secret_accounts'] = ongoing_counts[2]
cache.set(self.ongoing_change_secret_cache_key, ongoing_counts, 60)
else:
data['total_count_ongoing_change_secret'] = ongoing_counts[0]
data['total_count_ongoing_change_secret_assets'] = ongoing_counts[1]
data['total_count_ongoing_change_secret_accounts'] = ongoing_counts[2]
return JsonResponse(data, status=200)

View File

@ -0,0 +1,165 @@
# -*- coding: utf-8 -*-
#
from django.db.models import Q, Count
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from rest_framework.decorators import action
from rest_framework.exceptions import MethodNotAllowed
from rest_framework.response import Response
from accounts import serializers
from accounts.const import AutomationTypes
from accounts.models import (
CheckAccountAutomation,
AccountRisk,
RiskChoice,
CheckAccountEngine,
AutomationExecution,
)
from assets.models import Asset
from common.api import JMSModelViewSet
from common.permissions import IsValidLicense
from common.utils import many_get
from orgs.mixins.api import OrgBulkModelViewSet
from rbac.permissions import RBACPermission
from .base import AutomationExecutionViewSet
from ...filters import NodeFilterBackend
from ...risk_handlers import RiskHandler
__all__ = [
"CheckAccountAutomationViewSet",
"CheckAccountExecutionViewSet",
"AccountRiskViewSet",
"CheckAccountEngineViewSet",
]
class CheckAccountAutomationViewSet(OrgBulkModelViewSet):
model = CheckAccountAutomation
filterset_fields = ("name",)
search_fields = filterset_fields
permission_classes = [RBACPermission, IsValidLicense]
serializer_class = serializers.CheckAccountAutomationSerializer
class CheckAccountExecutionViewSet(AutomationExecutionViewSet):
rbac_perms = (
("list", "accounts.view_checkaccountexecution"),
("retrieve", "accounts.view_checkaccountexecution"),
("create", "accounts.add_checkaccountexecution"),
("adhoc", "accounts.add_checkaccountexecution"),
("report", "accounts.view_checkaccountexecution"),
)
ordering = ("-date_created",)
tp = AutomationTypes.check_account
permission_classes = [RBACPermission, IsValidLicense]
def get_queryset(self):
queryset = super().get_queryset()
queryset = queryset.filter(type=self.tp)
return queryset
@action(methods=["get"], detail=False, url_path="adhoc")
def adhoc(self, request, *args, **kwargs):
asset_id = request.query_params.get("asset_id")
if not asset_id:
return Response(status=400, data={"asset_id": "This field is required."})
asset = get_object_or_404(Asset, pk=asset_id)
name = "Check asset risk: {}".format(asset.name)
execution = AutomationExecution()
execution.snapshot = {
"assets": [asset_id],
"nodes": [],
"type": AutomationTypes.check_account,
"engines": "__all__",
"name": name,
}
execution.save()
execution.start()
report = execution.manager.gen_report()
return HttpResponse(report)
class AccountRiskViewSet(OrgBulkModelViewSet):
model = AccountRisk
search_fields = ["username", "asset__name"]
filterset_fields = ("risk", "status", "asset_id")
extra_filter_backends = [NodeFilterBackend]
permission_classes = [RBACPermission, IsValidLicense]
serializer_classes = {
"default": serializers.AccountRiskSerializer,
"assets": serializers.AssetRiskSerializer,
"handle": serializers.HandleRiskSerializer,
}
ordering_fields = ("asset", "risk", "status", "username", "date_created")
ordering = ("status", "asset", "date_created")
rbac_perms = {
"sync_accounts": "assets.add_accountrisk",
"assets": "accounts.view_accountrisk",
"handle": "accounts.change_accountrisk",
}
def update(self, request, *args, **kwargs):
raise MethodNotAllowed("PUT")
def create(self, request, *args, **kwargs):
raise MethodNotAllowed("POST")
@action(methods=["get"], detail=False, url_path="assets")
def assets(self, request, *args, **kwargs):
annotations = {
f"{risk[0]}_count": Count("id", filter=Q(risk=risk[0]))
for risk in RiskChoice.choices
}
queryset = (
AccountRisk.objects.select_related(
"asset", "asset__platform"
) # 使用 select_related 来优化 asset 和 asset__platform 的查询
.values(
"asset__id", "asset__name", "asset__address", "asset__platform__name"
) # 添加需要的字段
.annotate(risk_total=Count("id")) # 计算风险总数
.annotate(**annotations) # 使用上面定义的 annotations 进行计数
)
return self.get_paginated_response_from_queryset(queryset)
@action(methods=["post"], detail=False, url_path="handle")
def handle(self, request, *args, **kwargs):
s = self.get_serializer(data=request.data)
s.is_valid(raise_exception=True)
asset, username, act, risk = many_get(
s.validated_data, ("asset", "username", "action", "risk")
)
handler = RiskHandler(asset=asset, username=username, request=self.request)
try:
risk = handler.handle(act, risk)
s = serializers.AccountRiskSerializer(instance=risk)
return Response(data=s.data)
except Exception as e:
return Response(status=400, data=str(e))
class CheckAccountEngineViewSet(JMSModelViewSet):
search_fields = ("name",)
serializer_class = serializers.CheckAccountEngineSerializer
permission_classes = [RBACPermission, IsValidLicense]
perm_model = CheckAccountEngine
http_method_names = ['get', 'options']
def get_queryset(self):
if getattr(self, "swagger_fake_view", False):
return CheckAccountEngine.objects.none()
return CheckAccountEngine.get_default_engines()
def filter_queryset(self, queryset: list):
search = self.request.GET.get('search')
if search is not None:
queryset = [
item for item in queryset
if search in item['name']
]
return queryset

View File

@ -0,0 +1,131 @@
# -*- coding: utf-8 -*-
#
from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from django.views.decorators.clickjacking import xframe_options_sameorigin
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.response import Response
from accounts import serializers
from accounts.const import AutomationTypes
from accounts.filters import GatheredAccountFilterSet, NodeFilterBackend
from accounts.models import GatherAccountsAutomation, AutomationExecution, Account
from accounts.models import GatheredAccount
from assets.models import Asset
from common.const import ConfirmOrIgnore
from common.utils.http import is_true
from orgs.mixins.api import OrgBulkModelViewSet
from .base import AutomationExecutionViewSet
__all__ = [
"DiscoverAccountsAutomationViewSet",
"DiscoverAccountsExecutionViewSet",
"GatheredAccountViewSet",
]
from ...risk_handlers import RiskHandler
class DiscoverAccountsAutomationViewSet(OrgBulkModelViewSet):
model = GatherAccountsAutomation
filterset_fields = ("name",)
search_fields = filterset_fields
serializer_class = serializers.DiscoverAccountAutomationSerializer
class DiscoverAccountsExecutionViewSet(AutomationExecutionViewSet):
rbac_perms = (
("list", "accounts.view_gatheraccountsexecution"),
("retrieve", "accounts.view_gatheraccountsexecution"),
("create", "accounts.add_gatheraccountsexecution"),
("adhoc", "accounts.add_gatheraccountsexecution"),
("report", "accounts.view_gatheraccountsexecution"),
)
tp = AutomationTypes.gather_accounts
def get_queryset(self):
queryset = super().get_queryset()
queryset = queryset.filter(type=self.tp)
return queryset
@xframe_options_sameorigin
@action(methods=["get"], detail=False, url_path="adhoc")
def adhoc(self, request, *args, **kwargs):
asset_id = request.query_params.get("asset_id")
if not asset_id:
return Response(status=400, data={"asset_id": "This field is required."})
asset = get_object_or_404(Asset, pk=asset_id)
execution = AutomationExecution()
execution.snapshot = {
"assets": [asset_id],
"nodes": [],
"type": "gather_accounts",
"is_sync_account": False,
"check_risk": True,
"name": "Adhoc gather accounts: {}".format(asset.name),
}
execution.save()
execution.start()
report = execution.manager.gen_report()
return HttpResponse(report)
class GatheredAccountViewSet(OrgBulkModelViewSet):
model = GatheredAccount
search_fields = ("username",)
filterset_class = GatheredAccountFilterSet
extra_filter_backends = [NodeFilterBackend]
ordering = ("status",)
serializer_classes = {
"default": serializers.DiscoverAccountSerializer,
"status": serializers.DiscoverAccountActionSerializer,
"details": serializers.DiscoverAccountDetailsSerializer
}
rbac_perms = {
"status": "assets.change_gatheredaccount",
"details": "assets.view_gatheredaccount"
}
@action(methods=["put"], detail=False, url_path="status")
def status(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
if not serializer.is_valid():
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
validated_data = serializer.validated_data
ids = validated_data.get('ids', [])
new_status = validated_data.get('status')
updated_instances = GatheredAccount.objects.filter(id__in=ids).select_related('asset')
if new_status == ConfirmOrIgnore.confirmed:
GatheredAccount.sync_accounts(updated_instances)
updated_instances.update(present=True)
updated_instances.update(status=new_status)
return Response(status=status.HTTP_200_OK)
def perform_destroy(self, instance):
request = self.request
params = request.query_params
is_delete_remote = params.get("is_delete_remote")
is_delete_account = params.get("is_delete_account")
asset_id = params.get("asset")
username = params.get("username")
if is_true(is_delete_remote):
self._delete_remote(asset_id, username)
if is_true(is_delete_account):
account = get_object_or_404(Account, username=username, asset_id=asset_id)
account.delete()
super().perform_destroy(instance)
def _delete_remote(self, asset_id, username):
asset = get_object_or_404(Asset, pk=asset_id)
handler = RiskHandler(asset, username, request=self.request)
handler.handle_delete_remote()
@action(methods=["get"], detail=True, url_path="details")
def details(self, request, *args, **kwargs):
pk = kwargs.get('pk')
account = get_object_or_404(GatheredAccount, pk=pk)
serializer = self.get_serializer(account.detail)
return Response(data=serializer.data)

View File

@ -1,59 +0,0 @@
# -*- coding: utf-8 -*-
#
from rest_framework import status
from rest_framework.decorators import action
from rest_framework.response import Response
from accounts import serializers
from accounts.const import AutomationTypes
from accounts.filters import GatheredAccountFilterSet
from accounts.models import GatherAccountsAutomation
from accounts.models import GatheredAccount
from orgs.mixins.api import OrgBulkModelViewSet
from .base import AutomationExecutionViewSet
__all__ = [
'GatherAccountsAutomationViewSet', 'GatherAccountsExecutionViewSet',
'GatheredAccountViewSet'
]
class GatherAccountsAutomationViewSet(OrgBulkModelViewSet):
model = GatherAccountsAutomation
filterset_fields = ('name',)
search_fields = filterset_fields
serializer_class = serializers.GatherAccountAutomationSerializer
class GatherAccountsExecutionViewSet(AutomationExecutionViewSet):
rbac_perms = (
("list", "accounts.view_gatheraccountsexecution"),
("retrieve", "accounts.view_gatheraccountsexecution"),
("create", "accounts.add_gatheraccountsexecution"),
)
tp = AutomationTypes.gather_accounts
def get_queryset(self):
queryset = super().get_queryset()
queryset = queryset.filter(automation__type=self.tp)
return queryset
class GatheredAccountViewSet(OrgBulkModelViewSet):
model = GatheredAccount
search_fields = ('username',)
filterset_class = GatheredAccountFilterSet
serializer_classes = {
'default': serializers.GatheredAccountSerializer,
}
rbac_perms = {
'sync_accounts': 'assets.add_gatheredaccount',
}
@action(methods=['post'], detail=False, url_path='sync-accounts')
def sync_accounts(self, request, *args, **kwargs):
gathered_account_ids = request.data.get('gathered_account_ids')
gathered_accounts = self.model.objects.filter(id__in=gathered_account_ids)
self.model.sync_accounts(gathered_accounts)
return Response(status=status.HTTP_201_CREATED)

View File

@ -1,15 +1,16 @@
# -*- coding: utf-8 -*-
#
from rest_framework import mixins
from accounts import serializers
from accounts.const import AutomationTypes
from accounts.models import PushAccountAutomation, ChangeSecretRecord
from orgs.mixins.api import OrgBulkModelViewSet
from accounts.filters import PushAccountRecordFilterSet
from accounts.models import PushAccountAutomation, PushSecretRecord
from orgs.mixins.api import OrgBulkModelViewSet, OrgGenericViewSet
from .base import (
AutomationAssetsListApi, AutomationRemoveAssetApi, AutomationAddAssetApi,
AutomationNodeAddRemoveApi, AutomationExecutionViewSet
)
from .change_secret import ChangeSecretRecordViewSet
__all__ = [
'PushAccountAutomationViewSet', 'PushAccountAssetsListApi', 'PushAccountRemoveAssetApi',
@ -30,24 +31,28 @@ class PushAccountExecutionViewSet(AutomationExecutionViewSet):
("list", "accounts.view_pushaccountexecution"),
("retrieve", "accounts.view_pushaccountexecution"),
("create", "accounts.add_pushaccountexecution"),
("report", "accounts.view_pushaccountexecution"),
)
tp = AutomationTypes.push_account
def get_queryset(self):
queryset = super().get_queryset()
queryset = queryset.filter(automation__type=self.tp)
queryset = queryset.filter(type=self.tp)
return queryset
class PushAccountRecordViewSet(ChangeSecretRecordViewSet):
serializer_class = serializers.ChangeSecretRecordSerializer
class PushAccountRecordViewSet(mixins.ListModelMixin, OrgGenericViewSet):
filterset_class = PushAccountRecordFilterSet
search_fields = ('asset__address', 'account__username')
ordering_fields = ('date_finished',)
tp = AutomationTypes.push_account
serializer_classes = {
'default': serializers.PushSecretRecordSerializer,
}
def get_queryset(self):
return ChangeSecretRecord.objects.filter(
execution__automation__type=AutomationTypes.push_account
)
return PushSecretRecord.get_valid_records()
class PushAccountAssetsListApi(AutomationAssetsListApi):
@ -58,12 +63,10 @@ class PushAccountRemoveAssetApi(AutomationRemoveAssetApi):
model = PushAccountAutomation
serializer_class = serializers.PushAccountUpdateAssetSerializer
class PushAccountAddAssetApi(AutomationAddAssetApi):
model = PushAccountAutomation
serializer_class = serializers.PushAccountUpdateAssetSerializer
class PushAccountNodeAddRemoveApi(AutomationNodeAddRemoveApi):
model = PushAccountAutomation
serializer_class = serializers.PushAccountUpdateNodeSerializer

View File

@ -4,6 +4,7 @@ from django.apps import AppConfig
class AccountsConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'accounts'
verbose_name = 'App Accounts'
def ready(self):
from . import signal_handlers # noqa

View File

@ -3,20 +3,24 @@ import time
from collections import defaultdict, OrderedDict
from django.conf import settings
from django.db.models import F
from django.utils.translation import gettext_lazy as _
from rest_framework import serializers
from xlsxwriter import Workbook
from accounts.const import AccountBackupType
from accounts.models.automations.backup_account import AccountBackupAutomation
from accounts.models import BackupAccountAutomation, Account
from accounts.notifications import AccountBackupExecutionTaskMsg, AccountBackupByObjStorageExecutionTaskMsg
from accounts.serializers import AccountSecretSerializer
from assets.const import AllTypes
from common.const import Status
from common.utils.file import encrypt_and_compress_zip_file, zip_files
from common.utils.timezone import local_now_filename, local_now_display
from terminal.models.component.storage import ReplayStorage
from users.models import User
PATH = os.path.join(os.path.dirname(settings.BASE_DIR), 'tmp')
split_help_text = _('The account key will be split into two parts and sent')
class RecipientsNotFound(Exception):
@ -32,17 +36,26 @@ class BaseAccountHandler:
if isinstance(v, OrderedDict):
cls.unpack_data(v, data)
else:
if isinstance(v, dict):
v = v.get('label')
elif v is None:
v = ''
data[k] = v
return data
@classmethod
def get_header_fields(cls, serializer: serializers.Serializer):
try:
backup_fields = getattr(serializer, 'Meta').fields_backup
exclude_backup_fields = getattr(serializer, 'Meta').exclude_backup_fields
except AttributeError:
backup_fields = serializer.fields.keys()
exclude_backup_fields = []
backup_fields = serializer.fields.keys()
header_fields = {}
for field in backup_fields:
if field in exclude_backup_fields:
continue
v = serializer.fields[field]
if isinstance(v, serializers.Serializer):
_fields = cls.get_header_fields(v)
@ -72,9 +85,9 @@ class BaseAccountHandler:
class AssetAccountHandler(BaseAccountHandler):
@staticmethod
def get_filename(plan_name):
def get_filename(name):
filename = os.path.join(
PATH, f'{plan_name}-{local_now_filename()}-{time.time()}.xlsx'
PATH, f'{name}-{local_now_filename()}-{time.time()}.xlsx'
)
return filename
@ -115,32 +128,42 @@ class AssetAccountHandler(BaseAccountHandler):
data = AccountSecretSerializer(_accounts, many=True).data
cls.handler_secret(data, section)
data_map.update(cls.add_rows(data, header_fields, sheet_name))
print('\n\033[33m- 共备份 {} 条账号\033[0m'.format(accounts.count()))
number_of_backup_accounts = _('Number of backup accounts')
print('\033[33m- {}: {}\033[0m'.format(number_of_backup_accounts, accounts.count()))
return data_map
class AccountBackupHandler:
def __init__(self, execution):
def __init__(self, manager, execution):
self.manager = manager
self.execution = execution
self.plan_name = self.execution.plan.name
self.is_frozen = False # 任务状态冻结标志
self.name = self.execution.snapshot.get('name', '-')
def get_accounts(self):
# TODO 可以优化一下查询 在账号上做 category 的缓存 避免数据量大时连表操作
types = self.execution.snapshot.get('types', [])
self.manager.summary['total_types'] = len(types)
qs = Account.objects.filter(
asset__platform__type__in=types
).annotate(type=F('asset__platform__type'))
return qs
def create_excel(self, section='complete'):
hint = _('Generating asset related backup information files')
print(
'\n'
'\033[32m>>> 正在生成资产或应用相关备份信息文件\033[0m'
f'\033[32m>>> {hint}\033[0m'
''
)
# Print task start date
time_start = time.time()
files = []
accounts = self.execution.backup_accounts
accounts = self.get_accounts()
self.manager.summary['total_accounts'] = accounts.count()
data_map = AssetAccountHandler.create_data_map(accounts, section)
if not data_map:
return files
filename = AssetAccountHandler.get_filename(self.plan_name)
filename = AssetAccountHandler.get_filename(self.name)
wb = Workbook(filename)
for sheet, data in data_map.items():
@ -151,28 +174,30 @@ class AccountBackupHandler:
wb.close()
files.append(filename)
timedelta = round((time.time() - time_start), 2)
print('创建备份文件完成: 用时 {}s'.format(timedelta))
time_cost = _('Duration')
file_created = _('Backup file creation completed')
print('{}: {} {}s'.format(file_created, time_cost, timedelta))
return files
def send_backup_mail(self, files, recipients):
if not files:
return
recipients = User.objects.filter(id__in=list(recipients))
msg = _("Start sending backup emails")
print(
'\n'
'\033[32m>>> 开始发送备份邮件\033[0m'
f'\033[32m>>> {msg}\033[0m'
''
)
plan_name = self.plan_name
name = self.name
for user in recipients:
if not user.secret_key:
attachment_list = []
else:
attachment = os.path.join(PATH, f'{plan_name}-{local_now_filename()}-{time.time()}.zip')
attachment = os.path.join(PATH, f'{name}-{local_now_filename()}-{time.time()}.zip')
encrypt_and_compress_zip_file(attachment, user.secret_key, files)
attachment_list = [attachment, ]
AccountBackupExecutionTaskMsg(plan_name, user).publish(attachment_list)
print('邮件已发送至{}({})'.format(user, user.email))
attachment_list = [attachment]
AccountBackupExecutionTaskMsg(name, user).publish(attachment_list)
for file in files:
os.remove(file)
@ -181,73 +206,53 @@ class AccountBackupHandler:
return
recipients = ReplayStorage.objects.filter(id__in=list(recipients))
print(
'\n'
'\033[32m>>> 开始发送备份文件到sftp服务器\033[0m'
'\033[32m>>> 📃 ---> sftp \033[0m'
''
)
plan_name = self.plan_name
name = self.name
encrypt_file = _('Encrypting files using encryption password')
for rec in recipients:
attachment = os.path.join(PATH, f'{plan_name}-{local_now_filename()}-{time.time()}.zip')
attachment = os.path.join(PATH, f'{name}-{local_now_filename()}-{time.time()}.zip')
if password:
print('\033[32m>>> 使用加密密码对文件进行加密中\033[0m')
print(f'\033[32m>>> {encrypt_file}\033[0m')
encrypt_and_compress_zip_file(attachment, password, files)
else:
zip_files(attachment, files)
attachment_list = attachment
AccountBackupByObjStorageExecutionTaskMsg(plan_name, rec).publish(attachment_list)
print('备份文件将发送至{}({})'.format(rec.name, rec.id))
AccountBackupByObjStorageExecutionTaskMsg(name, rec).publish(attachment_list)
file_sent_to = _('The backup file will be sent to')
print('{}: {}({})'.format(file_sent_to, rec.name, rec.id))
for file in files:
os.remove(file)
def step_perform_task_update(self, is_success, reason):
self.execution.reason = reason[:1024]
self.execution.is_success = is_success
self.execution.save()
print('\n已完成对任务状态的更新\n')
@staticmethod
def step_finished(is_success):
if is_success:
print('任务执行成功')
else:
print('任务执行失败')
def _run(self):
is_success = False
error = '-'
try:
backup_type = self.execution.snapshot.get('backup_type', AccountBackupType.email.value)
if backup_type == AccountBackupType.email.value:
backup_type = self.execution.snapshot.get('backup_type', AccountBackupType.email)
if backup_type == AccountBackupType.email:
self.backup_by_email()
elif backup_type == AccountBackupType.object_storage.value:
elif backup_type == AccountBackupType.object_storage:
self.backup_by_obj_storage()
except Exception as e:
self.is_frozen = True
print('任务执行被异常中断')
print('下面打印发生异常的 Traceback 信息 : ')
print(e)
error = str(e)
else:
is_success = True
finally:
reason = error
self.step_perform_task_update(is_success, reason)
self.step_finished(is_success)
print(f'\033[31m>>> {error}\033[0m')
self.manager.status = Status.error
self.manager.summary['error'] = error
def backup_by_obj_storage(self):
object_id = self.execution.snapshot.get('id')
zip_encrypt_password = AccountBackupAutomation.objects.get(id=object_id).zip_encrypt_password
zip_encrypt_password = BackupAccountAutomation.objects.get(id=object_id).zip_encrypt_password
obj_recipients_part_one = self.execution.snapshot.get('obj_recipients_part_one', [])
obj_recipients_part_two = self.execution.snapshot.get('obj_recipients_part_two', [])
no_assigned_sftp_server = _('The backup task has no assigned sftp server')
if not obj_recipients_part_one and not obj_recipients_part_two:
print(
'\n'
'\033[31m>>> 该备份任务未分配sftp服务器\033[0m'
f'\033[31m>>> {no_assigned_sftp_server}\033[0m'
''
)
raise RecipientsNotFound('Not Found Recipients')
if obj_recipients_part_one and obj_recipients_part_two:
print('\033[32m>>> 账号的密钥将被拆分成前后两部分发送\033[0m')
print(f'\033[32m>>> {split_help_text}\033[0m')
files = self.create_excel(section='front')
self.send_backup_obj_storage(files, obj_recipients_part_one, zip_encrypt_password)
@ -259,17 +264,18 @@ class AccountBackupHandler:
self.send_backup_obj_storage(files, recipients, zip_encrypt_password)
def backup_by_email(self):
warn_text = _('The backup task has no assigned recipient')
recipients_part_one = self.execution.snapshot.get('recipients_part_one', [])
recipients_part_two = self.execution.snapshot.get('recipients_part_two', [])
if not recipients_part_one and not recipients_part_two:
print(
'\n'
'\033[31m>>> 该备份任务未分配收件人\033[0m'
f'\033[31m>>> {warn_text}\033[0m'
''
)
raise RecipientsNotFound('Not Found Recipients')
return
if recipients_part_one and recipients_part_two:
print('\033[32m>>> 账号的密钥将被拆分成前后两部分发送\033[0m')
print(f'\033[32m>>> {split_help_text}\033[0m')
files = self.create_excel(section='front')
self.send_backup_mail(files, recipients_part_one)
@ -281,15 +287,5 @@ class AccountBackupHandler:
self.send_backup_mail(files, recipients)
def run(self):
print('任务开始: {}'.format(local_now_display()))
time_start = time.time()
try:
self._run()
except Exception as e:
print('任务运行出现异常')
print('下面显示异常 Traceback 信息: ')
print(e)
finally:
print('\n任务结束: {}'.format(local_now_display()))
timedelta = round((time.time() - time_start), 2)
print('用时: {}s'.format(timedelta))
print('{}: {}'.format(_('Plan start'), local_now_display()))
self._run()

View File

@ -1,44 +1,30 @@
# -*- coding: utf-8 -*-
#
import time
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from assets.automations.base.manager import BaseManager
from common.utils.timezone import local_now_display
from .handlers import AccountBackupHandler
class AccountBackupManager:
def __init__(self, execution):
self.execution = execution
self.date_start = timezone.now()
self.time_start = time.time()
self.date_end = None
self.time_end = None
self.timedelta = 0
class AccountBackupManager(BaseManager):
def do_run(self):
execution = self.execution
print('\n\033[33m# 账号备份计划正在执行\033[0m')
handler = AccountBackupHandler(execution)
account_backup_execution_being_executed = _('The account backup plan is being executed')
print(f'\033[33m# {account_backup_execution_being_executed}\033[0m')
handler = AccountBackupHandler(self, execution)
handler.run()
def pre_run(self):
self.execution.date_start = self.date_start
self.execution.save()
def post_run(self):
self.time_end = time.time()
self.date_end = timezone.now()
def send_report_if_need(self):
pass
def print_summary(self):
print('\n\n' + '-' * 80)
print('计划执行结束 {}\n'.format(local_now_display()))
self.timedelta = self.time_end - self.time_start
print('用时: {}s'.format(self.timedelta))
self.execution.timedelta = self.timedelta
self.execution.save()
plan_execution_end = _('Plan execution end')
print('{} {}\n'.format(plan_execution_end, local_now_display()))
time_cost = _('Duration')
print('{}: {}s'.format(time_cost, self.duration))
def run(self):
self.pre_run()
self.do_run()
self.post_run()
def get_report_template(self):
return "accounts/backup_account_report.html"

View File

@ -1,12 +1,235 @@
from copy import deepcopy
from django.conf import settings
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from accounts.automations.methods import platform_automation_methods
from accounts.const import SSHKeyStrategy, SecretStrategy, SecretType, ChangeSecretRecordStatusChoice, \
ChangeSecretAccountStatus
from accounts.models import BaseAccountQuerySet
from accounts.utils import SecretGenerator, account_secret_task_status
from assets.automations.base.manager import BasePlaybookManager
from assets.const import HostTypes
from common.db.utils import safe_atomic_db_connection
from common.utils import get_logger
logger = get_logger(__name__)
class AccountBasePlaybookManager(BasePlaybookManager):
template_path = ''
@property
def platform_automation_methods(self):
return platform_automation_methods
class BaseChangeSecretPushManager(AccountBasePlaybookManager):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.secret_type = self.execution.snapshot.get('secret_type')
self.secret_strategy = self.execution.snapshot.get(
'secret_strategy', SecretStrategy.custom
)
self.ssh_key_change_strategy = self.execution.snapshot.get(
'ssh_key_change_strategy', SSHKeyStrategy.set_jms
)
self.account_ids = self.execution.snapshot['accounts']
self.record_map = self.execution.snapshot.get('record_map', {}) # 这个是某个失败的记录重试
self.name_record_mapper = {} # 做个映射,方便后面处理
def gen_account_inventory(self, account, asset, h, path_dir):
raise NotImplementedError
def get_ssh_params(self, secret, secret_type):
kwargs = {}
if secret_type != SecretType.SSH_KEY:
return kwargs
kwargs['strategy'] = self.ssh_key_change_strategy
kwargs['exclusive'] = 'yes' if kwargs['strategy'] == SSHKeyStrategy.set else 'no'
if kwargs['strategy'] == SSHKeyStrategy.set_jms:
kwargs['regexp'] = '.*{}$'.format(secret.split()[2].strip())
return kwargs
def get_secret(self, account):
if self.secret_strategy == SecretStrategy.custom:
new_secret = self.execution.snapshot['secret']
else:
generator = SecretGenerator(
self.secret_strategy, self.secret_type,
self.execution.snapshot.get('password_rules')
)
new_secret = generator.get_secret()
return new_secret
def get_accounts(self, privilege_account) -> BaseAccountQuerySet | None:
if not privilege_account:
print('Not privilege account')
return
asset = privilege_account.asset
accounts = asset.all_accounts.all()
accounts = accounts.filter(id__in=self.account_ids, secret_reset=True)
if self.secret_type:
accounts = accounts.filter(secret_type=self.secret_type)
if settings.CHANGE_AUTH_PLAN_SECURE_MODE_ENABLED:
accounts = accounts.filter(privileged=False).exclude(
username__in=['root', 'administrator', privilege_account.username]
)
return accounts
def handle_ssh_secret(self, secret_type, new_secret, path_dir):
private_key_path = None
if secret_type == SecretType.SSH_KEY:
private_key_path = self.generate_private_key_path(new_secret, path_dir)
new_secret = self.generate_public_key(new_secret)
return new_secret, private_key_path
def gen_inventory(self, h, account, new_secret, private_key_path, asset):
secret_type = account.secret_type
h['ssh_params'].update(self.get_ssh_params(new_secret, secret_type))
h['account'] = {
'name': account.name,
'username': account.username,
'full_username': account.full_username,
'secret_type': secret_type,
'secret': account.escape_jinja2_syntax(new_secret),
'private_key_path': private_key_path,
'become': account.get_ansible_become_auth(),
}
if asset.platform.type == 'oracle':
h['account']['mode'] = 'sysdba' if account.privileged else None
return h
def host_callback(self, host, asset=None, account=None, automation=None, path_dir=None, **kwargs):
host = super().host_callback(
host, asset=asset, account=account, automation=automation,
path_dir=path_dir, **kwargs
)
if host.get('error'):
return host
inventory_hosts = []
if asset.type == HostTypes.WINDOWS:
if self.secret_type == SecretType.SSH_KEY:
host['error'] = _("Windows does not support SSH key authentication")
return host
new_secret = self.get_secret(account)
if '>' in new_secret or '^' in new_secret:
host['error'] = _("Windows password cannot contain special characters like > ^")
return host
host['ssh_params'] = {}
accounts = self.get_accounts(account)
existing_ids = set(map(str, accounts.values_list('id', flat=True)))
missing_ids = set(map(str, self.account_ids)) - existing_ids
for account_id in missing_ids:
self.clear_account_queue_status(account_id)
error_msg = _("No pending accounts found")
if not accounts:
print(f'{asset}: {error_msg}')
return []
if asset.type == HostTypes.WINDOWS:
accounts = accounts.filter(secret_type=SecretType.PASSWORD)
for account in accounts:
h = deepcopy(host)
h['name'] += '(' + account.username + ')' # To distinguish different accounts
account_status = account_secret_task_status.get_status(account.id)
if account_status == ChangeSecretAccountStatus.PROCESSING:
h['error'] = f'Account is already being processed, skipping: {account}'
inventory_hosts.append(h)
continue
try:
h, record = self.gen_account_inventory(account, asset, h, path_dir)
h['check_conn_after_change'] = record.execution.snapshot.get('check_conn_after_change', True)
account_secret_task_status.set_status(
account.id,
ChangeSecretAccountStatus.PROCESSING,
metadata={'execution_id': self.execution.id}
)
except Exception as e:
h['error'] = str(e)
self.clear_account_queue_status(account.id)
inventory_hosts.append(h)
return inventory_hosts
@staticmethod
def save_record(record):
record.save(update_fields=['error', 'status', 'date_finished'])
@staticmethod
def clear_account_queue_status(account_id):
account_secret_task_status.clear(account_id)
def on_host_success(self, host, result):
record = self.name_record_mapper.get(host)
if not record:
return
record.status = ChangeSecretRecordStatusChoice.success.value
record.date_finished = timezone.now()
account = record.account
if not account:
print("Account not found, deleted ?")
return
account.secret = getattr(record, 'new_secret', account.secret)
account.date_updated = timezone.now()
account.date_change_secret = timezone.now()
account.change_secret_status = ChangeSecretRecordStatusChoice.success
self.summary['ok_accounts'] += 1
self.result['ok_accounts'].append(
{
"asset": str(account.asset),
"username": account.username,
}
)
super().on_host_success(host, result)
with safe_atomic_db_connection():
account.save(update_fields=['secret', 'date_updated', 'date_change_secret', 'change_secret_status'])
self.save_record(record)
self.clear_account_queue_status(account.id)
def on_host_error(self, host, error, result):
record = self.name_record_mapper.get(host)
if not record:
return
record.status = ChangeSecretRecordStatusChoice.failed.value
record.date_finished = timezone.now()
record.error = error
account = record.account
if not account:
print("Account not found, deleted ?")
return
account.date_updated = timezone.now()
account.date_change_secret = timezone.now()
account.change_secret_status = ChangeSecretRecordStatusChoice.failed
self.summary['fail_accounts'] += 1
self.result['fail_accounts'].append(
{
"asset": str(record.asset),
"username": record.account.username,
}
)
super().on_host_error(host, error, result)
with safe_atomic_db_connection():
account.save(update_fields=['change_secret_status', 'date_change_secret', 'date_updated'])
self.save_record(record)
self.clear_account_queue_status(account.id)

View File

@ -13,13 +13,14 @@
login_password: "{{ jms_account.secret }}"
login_secret_type: "{{ jms_account.secret_type }}"
login_private_key_path: "{{ jms_account.private_key_path }}"
become: "{{ custom_become | default(False) }}"
become_method: "{{ custom_become_method | default('su') }}"
become_user: "{{ custom_become_user | default('') }}"
become_password: "{{ custom_become_password | default('') }}"
become_private_key_path: "{{ custom_become_private_key_path | default(None) }}"
become: "{{ jms_custom_become | default(False) }}"
become_method: "{{ jms_custom_become_method | default('su') }}"
become_user: "{{ jms_custom_become_user | default('') }}"
become_password: "{{ jms_custom_become_password | default('') }}"
become_private_key_path: "{{ jms_custom_become_private_key_path | default(None) }}"
old_ssh_version: "{{ jms_asset.old_ssh_version | default(False) }}"
gateway_args: "{{ jms_asset.ansible_ssh_common_args | default(None) }}"
recv_timeout: "{{ params.recv_timeout | default(30) }}"
register: ping_info
delegate_to: localhost
@ -31,17 +32,20 @@
login_port: "{{ jms_asset.port }}"
login_secret_type: "{{ jms_account.secret_type }}"
login_private_key_path: "{{ jms_account.private_key_path }}"
become: "{{ custom_become | default(False) }}"
become_method: "{{ custom_become_method | default('su') }}"
become_user: "{{ custom_become_user | default('') }}"
become_password: "{{ custom_become_password | default('') }}"
become_private_key_path: "{{ custom_become_private_key_path | default(None) }}"
become: "{{ jms_custom_become | default(False) }}"
become_method: "{{ jms_custom_become_method | default('su') }}"
become_user: "{{ jms_custom_become_user | default('') }}"
become_password: "{{ jms_custom_become_password | default('') }}"
become_private_key_path: "{{ jms_custom_become_private_key_path | default(None) }}"
name: "{{ account.username }}"
password: "{{ account.secret }}"
commands: "{{ params.commands }}"
first_conn_delay_time: "{{ first_conn_delay_time | default(0.5) }}"
answers: "{{ params.answers }}"
recv_timeout: "{{ params.recv_timeout | default(30) }}"
delay_time: "{{ params.delay_time | default(2) }}"
prompt: "{{ params.prompt | default('.*') }}"
ignore_errors: true
when: ping_info is succeeded
when: ping_info is succeeded and check_conn_after_change
register: change_info
delegate_to: localhost
@ -58,4 +62,6 @@
become_private_key_path: "{{ account.become.ansible_ssh_private_key_file | default(None) }}"
old_ssh_version: "{{ jms_asset.old_ssh_version | default(False) }}"
gateway_args: "{{ jms_asset.ansible_ssh_common_args | default(None) }}"
recv_timeout: "{{ params.recv_timeout | default(30) }}"
delegate_to: localhost
when: check_conn_after_change

View File

@ -10,10 +10,30 @@ protocol: ssh
priority: 50
params:
- name: commands
type: list
type: text
label: "{{ 'Params commands label' | trans }}"
default: [ '' ]
default: ''
help_text: "{{ 'Params commands help text' | trans }}"
- name: recv_timeout
type: int
label: "{{ 'Params recv_timeout label' | trans }}"
default: 30
help_text: "{{ 'Params recv_timeout help text' | trans }}"
- name: delay_time
type: int
label: "{{ 'Params delay_time label' | trans }}"
default: 2
help_text: "{{ 'Params delay_time help text' | trans }}"
- name: prompt
type: str
label: "{{ 'Params prompt label' | trans }}"
default: '.*'
help_text: "{{ 'Params prompt help text' | trans }}"
- name: answers
type: text
label: "{{ 'Params answer label' | trans }}"
default: '.*'
help_text: "{{ 'Params answer help text' | trans }}"
i18n:
SSH account change secret:
@ -22,11 +42,91 @@ i18n:
en: 'Custom password change by SSH command line'
Params commands help text:
zh: '自定义命令中如需包含账号的 账号、密码、SSH 连接的用户密码 字段,<br />请使用 &#123;username&#125;、&#123;password&#125;、&#123;login_password&#125;格式,执行任务时会进行替换 。<br />比如针对 Cisco 主机进行改密,一般需要配置五条命令:<br />1. enable<br />2. &#123;login_password&#125;<br />3. configure terminal<br />4. username &#123;username&#125; privilege 0 password &#123;password&#125; <br />5. end'
ja: 'カスタム コマンドに SSH 接続用のアカウント番号、パスワード、ユーザー パスワード フィールドを含める必要がある場合は、<br />&#123;ユーザー名&#125;、&#123;パスワード&#125;、&#123;login_password& を使用してください。 # 125; 形式。タスクの実行時に置き換えられます。 <br />たとえば、Cisco ホストのパスワードを変更するには、通常、次の 5 つのコマンドを設定する必要があります:<br />1.enable<br />2.&#123;login_password&#125;<br />3 .ターミナルの設定<br / >4. ユーザー名 &#123;ユーザー名&#125; 権限 0 パスワード &#123;パスワード&#125; <br />5. 終了'
en: 'If the custom command needs to include the account number, password, and user password field for SSH connection,<br />Please use &#123;username&#125;, &#123;password&#125;, &#123;login_password&# 125; format, which will be replaced when executing the task. <br />For example, to change the password of a Cisco host, you generally need to configure five commands:<br />1. enable<br />2. &#123;login_password&#125;<br />3. configure terminal<br / >4. username &#123;username&#125; privilege 0 password &#123;password&#125; <br />5. end'
zh: |
请将命令中的指定位置改成特殊符号 <br />
1. 改密账号 -> {username} <br />
2. 改密密码 -> {password} <br />
3. 登录用户密码 -> {login_password} <br />
<strong>多条命令使用换行分割,</strong>执行任务时系统会根据特殊符号替换真实数据。<br />
比如针对 Cisco 主机进行改密,一般需要配置五条命令:<br />
enable <br />
{login_password} <br />
configure terminal <br />
username {username} privilege 0 password {password} <br />
end <br />
ja: |
コマンド内の指定された位置を特殊記号に変更してください。<br />
新しいパスワード(アカウント変更) -> {username} <br />
新しいパスワード(パスワード変更) -> {password} <br />
ログインユーザーパスワード -> {login_password} <br />
<strong>複数のコマンドは改行で区切り、</strong>タスクを実行するときにシステムは特殊記号を使用して実際のデータを置き換えます。<br />
例えば、Cisco機器のパスワードを変更する場合、一般的には5つのコマンドを設定する必要があります<br />
enable <br />
{login_password} <br />
configure terminal <br />
username {username} privilege 0 password {password} <br />
end <br />
en: |
Please change the specified positions in the command to special symbols. <br />
Change password account -> {username} <br />
Change password -> {password} <br />
Login user password -> {login_password} <br />
<strong>Multiple commands are separated by new lines,</strong> and when executing tasks, <br />
the system will replace the special symbols with real data. <br />
For example, to change the password for a Cisco device, you generally need to configure five commands: <br />
enable <br />
{login_password} <br />
configure terminal <br />
username {username} privilege 0 password {password} <br />
end <br />
Params commands label:
zh: '自定义命令'
ja: 'カスタムコマンド'
en: 'Custom command'
Params recv_timeout label:
zh: '超时时间'
ja: 'タイムアウト'
en: 'Timeout'
Params recv_timeout help text:
zh: '等待命令结果返回的超时时间(秒)'
ja: 'コマンドの結果を待つタイムアウト時間(秒)'
en: 'The timeout for waiting for the command result to return (Seconds)'
Params delay_time label:
zh: '延迟发送时间'
ja: '遅延送信時間'
en: 'Delayed send time'
Params delay_time help text:
zh: '每条命令延迟发送的时间间隔(秒)'
ja: '各コマンド送信の遅延間隔(秒)'
en: 'Time interval for each command delay in sending (Seconds)'
Params prompt label:
zh: '提示符'
ja: 'ヒント'
en: 'Prompt'
Params prompt help text:
zh: '终端连接后显示的提示符信息(正则表达式)'
ja: 'ターミナル接続後に表示されるプロンプト情報(正規表現)'
en: 'Prompt information displayed after terminal connection (Regular expression)'
Params answer label:
zh: '命令结果'
ja: 'コマンド結果'
en: 'Command result'
Params answer help text:
zh: |
根据结果匹配度决定是否执行下一条命令,输入框的内容和上方 “自定义命令” 内容按行一一对应(正则表达式)
ja: |
結果の一致度に基づいて次のコマンドを実行するかどうかを決定します。
入力欄の内容は、上の「カスタムコマンド」の内容と行ごとに対応しています(せいきひょうげん)
en: |
Decide whether to execute the next command based on the result match.
The input content corresponds line by line with the content
of the `Custom command` above. (Regular expression)

View File

@ -1,7 +1,7 @@
- hosts: mongodb
gather_facts: no
vars:
ansible_python_interpreter: /opt/py3/bin/python
ansible_python_interpreter: "{{ local_python_interpreter }}"
tasks:
- name: Test MongoDB connection
@ -53,3 +53,6 @@
ssl_certfile: "{{ jms_asset.secret_info.client_key | default('') }}"
connection_options:
- tlsAllowInvalidHostnames: "{{ jms_asset.spec_info.allow_invalid_cert}}"
when: check_conn_after_change
register: result
failed_when: not result.is_available

View File

@ -1,9 +1,12 @@
- hosts: mysql
gather_facts: no
vars:
ansible_python_interpreter: /opt/py3/bin/python
ansible_python_interpreter: "{{ local_python_interpreter }}"
db_name: "{{ jms_asset.spec_info.db_name }}"
check_ssl: "{{ jms_asset.spec_info.use_ssl and not jms_asset.spec_info.allow_invalid_cert }}"
ca_cert: "{{ jms_asset.secret_info.ca_cert | default('') }}"
ssl_cert: "{{ jms_asset.secret_info.client_cert | default('') }}"
ssl_key: "{{ jms_asset.secret_info.client_key | default('') }}"
tasks:
- name: Test MySQL connection
@ -13,9 +16,9 @@
login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}"
check_hostname: "{{ check_ssl if check_ssl else omit }}"
ca_cert: "{{ jms_asset.secret_info.ca_cert | default(omit) if check_ssl else omit }}"
client_cert: "{{ jms_asset.secret_info.client_cert | default(omit) if check_ssl else omit }}"
client_key: "{{ jms_asset.secret_info.client_key | default(omit) if check_ssl else omit }}"
ca_cert: "{{ ca_cert if check_ssl and ca_cert | length > 0 else omit }}"
client_cert: "{{ ssl_cert if check_ssl and ssl_cert | length > 0 else omit }}"
client_key: "{{ ssl_key if check_ssl and ssl_key | length > 0 else omit }}"
filter: version
register: db_info
@ -30,13 +33,14 @@
login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}"
check_hostname: "{{ check_ssl if check_ssl else omit }}"
ca_cert: "{{ jms_asset.secret_info.ca_cert | default(omit) if check_ssl else omit }}"
client_cert: "{{ jms_asset.secret_info.client_cert | default(omit) if check_ssl else omit }}"
client_key: "{{ jms_asset.secret_info.client_key | default(omit) if check_ssl else omit }}"
ca_cert: "{{ ca_cert if check_ssl and ca_cert | length > 0 else omit }}"
client_cert: "{{ ssl_cert if check_ssl and ssl_cert | length > 0 else omit }}"
client_key: "{{ ssl_key if check_ssl and ssl_key | length > 0 else omit }}"
name: "{{ account.username }}"
password: "{{ account.secret }}"
host: "%"
priv: "{{ account.username + '.*:USAGE' if db_name == '' else db_name + '.*:ALL' }}"
priv: "{{ omit if db_name == '' else db_name + '.*:ALL' }}"
append_privs: "{{ db_name != '' | bool }}"
ignore_errors: true
when: db_info is succeeded
@ -47,7 +51,8 @@
login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}"
check_hostname: "{{ check_ssl if check_ssl else omit }}"
ca_cert: "{{ jms_asset.secret_info.ca_cert | default(omit) if check_ssl else omit }}"
client_cert: "{{ jms_asset.secret_info.client_cert | default(omit) if check_ssl else omit }}"
client_key: "{{ jms_asset.secret_info.client_key | default(omit) if check_ssl else omit }}"
ca_cert: "{{ ca_cert if check_ssl and ca_cert | length > 0 else omit }}"
client_cert: "{{ ssl_cert if check_ssl and ssl_cert | length > 0 else omit }}"
client_key: "{{ ssl_key if check_ssl and ssl_key | length > 0 else omit }}"
filter: version
when: check_conn_after_change

View File

@ -1,7 +1,7 @@
- hosts: oracle
gather_facts: no
vars:
ansible_python_interpreter: /opt/py3/bin/python
ansible_python_interpreter: "{{ local_python_interpreter }}"
tasks:
- name: Test Oracle connection
@ -40,3 +40,4 @@
login_port: "{{ jms_asset.port }}"
login_database: "{{ jms_asset.spec_info.db_name }}"
mode: "{{ account.mode }}"
when: check_conn_after_change

View File

@ -1,7 +1,11 @@
- hosts: postgre
gather_facts: no
vars:
ansible_python_interpreter: /opt/py3/bin/python
ansible_python_interpreter: "{{ local_python_interpreter }}"
check_ssl: "{{ jms_asset.spec_info.use_ssl }}"
ca_cert: "{{ jms_asset.secret_info.ca_cert | default('') }}"
ssl_cert: "{{ jms_asset.secret_info.client_cert | default('') }}"
ssl_key: "{{ jms_asset.secret_info.client_key | default('') }}"
tasks:
- name: Test PostgreSQL connection
@ -11,6 +15,10 @@
login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}"
login_db: "{{ jms_asset.spec_info.db_name }}"
ca_cert: "{{ ca_cert if check_ssl and ca_cert | length > 0 else omit }}"
ssl_cert: "{{ ssl_cert if check_ssl and ssl_cert | length > 0 else omit }}"
ssl_key: "{{ ssl_key if check_ssl and ssl_key | length > 0 else omit }}"
ssl_mode: "{{ jms_asset.spec_info.pg_ssl_mode }}"
register: result
failed_when: not result.is_available
@ -28,6 +36,10 @@
db: "{{ jms_asset.spec_info.db_name }}"
name: "{{ account.username }}"
password: "{{ account.secret }}"
ca_cert: "{{ ca_cert if check_ssl and ca_cert | length > 0 else omit }}"
ssl_cert: "{{ ssl_cert if check_ssl and ssl_cert | length > 0 else omit }}"
ssl_key: "{{ ssl_key if check_ssl and ssl_key | length > 0 else omit }}"
ssl_mode: "{{ jms_asset.spec_info.pg_ssl_mode }}"
role_attr_flags: LOGIN
ignore_errors: true
when: result is succeeded
@ -39,3 +51,10 @@
login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}"
db: "{{ jms_asset.spec_info.db_name }}"
ca_cert: "{{ ca_cert if check_ssl and ca_cert | length > 0 else omit }}"
ssl_cert: "{{ ssl_cert if check_ssl and ssl_cert | length > 0 else omit }}"
ssl_key: "{{ ssl_key if check_ssl and ssl_key | length > 0 else omit }}"
ssl_mode: "{{ jms_asset.spec_info.pg_ssl_mode }}"
when: check_conn_after_change
register: result
failed_when: not result.is_available

View File

@ -1,16 +1,18 @@
- hosts: sqlserver
gather_facts: no
vars:
ansible_python_interpreter: /opt/py3/bin/python
ansible_python_interpreter: "{{ local_python_interpreter }}"
tasks:
- name: Test SQLServer connection
community.general.mssql_script:
mssql_script:
login_user: "{{ jms_account.username }}"
login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}"
name: '{{ jms_asset.spec_info.db_name }}'
encryption: "{{ jms_asset.encryption | default(None) }}"
tds_version: "{{ jms_asset.tds_version | default(None) }}"
script: |
SELECT @@version
register: db_info
@ -23,44 +25,53 @@
var: info
- name: Check whether SQLServer User exist
community.general.mssql_script:
mssql_script:
login_user: "{{ jms_account.username }}"
login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}"
name: '{{ jms_asset.spec_info.db_name }}'
encryption: "{{ jms_asset.encryption | default(None) }}"
tds_version: "{{ jms_asset.tds_version | default(None) }}"
script: "SELECT 1 from sys.sql_logins WHERE name='{{ account.username }}';"
when: db_info is succeeded
register: user_exist
- name: Change SQLServer password
community.general.mssql_script:
mssql_script:
login_user: "{{ jms_account.username }}"
login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}"
name: '{{ jms_asset.spec_info.db_name }}'
encryption: "{{ jms_asset.encryption | default(None) }}"
tds_version: "{{ jms_asset.tds_version | default(None) }}"
script: "ALTER LOGIN {{ account.username }} WITH PASSWORD = '{{ account.secret }}', DEFAULT_DATABASE = {{ jms_asset.spec_info.db_name }}; select @@version"
ignore_errors: true
when: user_exist.query_results[0] | length != 0
- name: Add SQLServer user
community.general.mssql_script:
mssql_script:
login_user: "{{ jms_account.username }}"
login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}"
name: '{{ jms_asset.spec_info.db_name }}'
encryption: "{{ jms_asset.encryption | default(None) }}"
tds_version: "{{ jms_asset.tds_version | default(None) }}"
script: "CREATE LOGIN {{ account.username }} WITH PASSWORD = '{{ account.secret }}', DEFAULT_DATABASE = {{ jms_asset.spec_info.db_name }}; CREATE USER {{ account.username }} FOR LOGIN {{ account.username }}; select @@version"
ignore_errors: true
when: user_exist.query_results[0] | length == 0
- name: Verify password
community.general.mssql_script:
mssql_script:
login_user: "{{ account.username }}"
login_password: "{{ account.secret }}"
login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}"
name: '{{ jms_asset.spec_info.db_name }}'
encryption: "{{ jms_asset.encryption | default(None) }}"
tds_version: "{{ jms_asset.tds_version | default(None) }}"
script: |
SELECT @@version
when: check_conn_after_change

View File

@ -9,55 +9,21 @@
database: passwd
key: "{{ account.username }}"
register: user_info
ignore_errors: yes # 忽略错误如果用户不存在时不会导致playbook失败
failed_when: false
changed_when: false
- name: "Add {{ account.username }} user"
ansible.builtin.user:
name: "{{ account.username }}"
shell: "{{ params.shell }}"
home: "{{ params.home | default('/home/' + account.username, true) }}"
groups: "{{ params.groups }}"
uid: "{{ params.uid | int if params.uid | length > 0 else omit }}"
shell: "{{ params.shell if params.shell | length > 0 else omit }}"
home: "{{ params.home if params.home | length > 0 else '/home/' + account.username }}"
group: "{{ params.group if params.group | length > 0 else omit }}"
groups: "{{ params.groups if params.groups | length > 0 else omit }}"
append: "{{ true if params.groups | length > 0 else false }}"
expires: -1
state: present
when: user_info.failed
- name: "Add {{ account.username }} group"
ansible.builtin.group:
name: "{{ account.username }}"
state: present
when: user_info.failed
- name: "Add {{ account.username }} user to group"
ansible.builtin.user:
name: "{{ account.username }}"
groups: "{{ params.groups }}"
when:
- user_info.failed
- params.groups
- name: "Change {{ account.username }} password"
ansible.builtin.user:
name: "{{ account.username }}"
password: "{{ account.secret | password_hash('des') }}"
update_password: always
ignore_errors: true
when: account.secret_type == "password"
- name: remove jumpserver ssh key
ansible.builtin.lineinfile:
dest: "{{ ssh_params.dest }}"
regexp: "{{ ssh_params.regexp }}"
state: absent
when:
- account.secret_type == "ssh_key"
- ssh_params.strategy == "set_jms"
- name: "Change {{ account.username }} SSH key"
ansible.builtin.authorized_key:
user: "{{ account.username }}"
key: "{{ account.secret }}"
exclusive: "{{ ssh_params.exclusive }}"
when: account.secret_type == "ssh_key"
when: user_info.msg is defined
- name: "Set {{ account.username }} sudo setting"
ansible.builtin.lineinfile:
@ -67,9 +33,61 @@
line: "{{ account.username + ' ALL=(ALL) NOPASSWD: ' + params.sudo }}"
validate: visudo -cf %s
when:
- user_info.failed
- user_info.msg is defined or params.modify_sudo
- params.sudo
- name: "Change {{ account.username }} password"
ansible.builtin.user:
name: "{{ account.username }}"
password: "{{ account.secret | password_hash('des') }}"
update_password: always
ignore_errors: true
register: change_secret_result
when: account.secret_type == "password"
- name: "Get home directory for {{ account.username }}"
ansible.builtin.shell: "getent passwd {{ account.username }} | cut -d: -f6"
register: home_dir
when: account.secret_type == "ssh_key"
ignore_errors: yes
- name: "Check if home directory exists for {{ account.username }}"
ansible.builtin.stat:
path: "{{ home_dir.stdout.strip() }}"
register: home_dir_stat
when: account.secret_type == "ssh_key"
ignore_errors: yes
- name: "Ensure {{ account.username }} home directory exists"
ansible.builtin.file:
path: "{{ home_dir.stdout.strip() }}"
state: directory
owner: "{{ account.username }}"
group: "{{ account.username }}"
mode: '0750'
when:
- account.secret_type == "ssh_key"
- home_dir_stat.stat.exists == false
ignore_errors: yes
- name: Remove jumpserver ssh key
ansible.builtin.lineinfile:
dest: "{{ home_dir.stdout.strip() }}/.ssh/authorized_keys"
regexp: "{{ ssh_params.regexp }}"
state: absent
when:
- account.secret_type == "ssh_key"
- ssh_params.strategy == "set_jms"
ignore_errors: yes
- name: "Change {{ account.username }} SSH key"
ansible.builtin.authorized_key:
user: "{{ account.username }}"
key: "{{ account.secret }}"
exclusive: "{{ ssh_params.exclusive }}"
register: change_secret_result
when: account.secret_type == "ssh_key"
- name: Refresh connection
ansible.builtin.meta: reset_connection
@ -79,14 +97,16 @@
login_password: "{{ account.secret }}"
login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}"
gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}"
gateway_args: "{{ jms_asset.ansible_ssh_common_args | default(None) }}"
become: "{{ account.become.ansible_become | default(False) }}"
become_method: su
become_user: "{{ account.become.ansible_user | default('') }}"
become_password: "{{ account.become.ansible_password | default('') }}"
become_private_key_path: "{{ account.become.ansible_ssh_private_key_file | default(None) }}"
old_ssh_version: "{{ jms_asset.old_ssh_version | default(False) }}"
when: account.secret_type == "password"
when:
- account.secret_type == "password"
- check_conn_after_change or change_secret_result.failed | default(false)
delegate_to: localhost
- name: "Verify {{ account.username }} SSH KEY (paramiko)"
@ -95,7 +115,9 @@
login_port: "{{ jms_asset.port }}"
login_user: "{{ account.username }}"
login_private_key_path: "{{ account.private_key_path }}"
gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}"
gateway_args: "{{ jms_asset.ansible_ssh_common_args | default(None) }}"
old_ssh_version: "{{ jms_asset.old_ssh_version | default(False) }}"
when: account.secret_type == "ssh_key"
when:
- account.secret_type == "ssh_key"
- check_conn_after_change or change_secret_result.failed | default(false)
delegate_to: localhost

View File

@ -5,6 +5,12 @@ type:
- AIX
method: change_secret
params:
- name: modify_sudo
type: bool
label: "{{ 'Modify sudo label' | trans }}"
default: False
help_text: "{{ 'Modify params sudo help text' | trans }}"
- name: sudo
type: str
label: 'Sudo'
@ -22,18 +28,35 @@ params:
default: ''
help_text: "{{ 'Params home help text' | trans }}"
- name: group
type: str
label: "{{ 'Params group label' | trans }}"
default: ''
help_text: "{{ 'Params group help text' | trans }}"
- name: groups
type: str
label: "{{ 'Params groups label' | trans }}"
default: ''
help_text: "{{ 'Params groups help text' | trans }}"
- name: uid
type: str
label: "{{ 'Params uid label' | trans }}"
default: ''
help_text: "{{ 'Params uid help text' | trans }}"
i18n:
AIX account change secret:
zh: '使用 Ansible 模块 user 执行账号改密 (DES)'
ja: 'Ansible user モジュールを使用してアカウントのパスワード変更 (DES)'
en: 'Using Ansible module user to change account secret (DES)'
Modify params sudo help text:
zh: '如果用户存在可以修改sudo权限'
ja: 'ユーザーが存在する場合、sudo権限を変更できます'
en: 'If the user exists, sudo permissions can be modified'
Params sudo help text:
zh: '使用逗号分隔多个命令,如: /bin/whoami,/sbin/ifconfig'
ja: 'コンマで区切って複数のコマンドを入力してください。例: /bin/whoami,/sbin/ifconfig'
@ -44,11 +67,26 @@ i18n:
ja: 'デフォルトのホームディレクトリ /home/{アカウントユーザ名}'
en: 'Default home directory /home/{account username}'
Params group help text:
zh: '请输入用户组(名字或数字),只能输入一个(需填写已存在的用户组)'
ja: 'ユーザー グループ (名前または番号) を入力してください。入力できるのは 1 つだけです (既存のユーザー グループを入力する必要があります)'
en: 'Please enter a user group (name or number), only one can be entered (must fill in an existing user group)'
Params groups help text:
zh: '请输入用户组,多个用户组使用逗号分隔(需填写已存在的用户组)'
ja: 'グループを入力してください。複数のグループはコンマで区切ってください(既存のグループを入力してください)'
en: 'Please enter the group. Multiple groups are separated by commas (please enter the existing group)'
Params uid help text:
zh: '请输入用户ID'
ja: 'ユーザーIDを入力してください'
en: 'Please enter the user ID'
Modify sudo label:
zh: '修改 sudo 权限'
ja: 'sudo 権限を変更'
en: 'Modify sudo'
Params home label:
zh: '家目录'
ja: 'ホームディレクトリ'
@ -59,3 +97,12 @@ i18n:
ja: 'グループ'
en: 'Groups'
Params group label:
zh: '主组'
ja: '主组'
en: 'Main group'
Params uid label:
zh: '用户ID'
ja: 'ユーザーID'
en: 'User ID'

View File

@ -9,55 +9,21 @@
database: passwd
key: "{{ account.username }}"
register: user_info
ignore_errors: yes # 忽略错误如果用户不存在时不会导致playbook失败
failed_when: false
changed_when: false
- name: "Add {{ account.username }} user"
ansible.builtin.user:
name: "{{ account.username }}"
shell: "{{ params.shell }}"
home: "{{ params.home | default('/home/' + account.username, true) }}"
groups: "{{ params.groups }}"
uid: "{{ params.uid | int if params.uid | length > 0 else omit }}"
shell: "{{ params.shell if params.shell | length > 0 else omit }}"
home: "{{ params.home if params.home | length > 0 else '/home/' + account.username }}"
group: "{{ params.group if params.group | length > 0 else omit }}"
groups: "{{ params.groups if params.groups | length > 0 else omit }}"
append: "{{ true if params.groups | length > 0 else false }}"
expires: -1
state: present
when: user_info.failed
- name: "Add {{ account.username }} group"
ansible.builtin.group:
name: "{{ account.username }}"
state: present
when: user_info.failed
- name: "Add {{ account.username }} user to group"
ansible.builtin.user:
name: "{{ account.username }}"
groups: "{{ params.groups }}"
when:
- user_info.failed
- params.groups
- name: "Change {{ account.username }} password"
ansible.builtin.user:
name: "{{ account.username }}"
password: "{{ account.secret | password_hash('sha512') }}"
update_password: always
ignore_errors: true
when: account.secret_type == "password"
- name: remove jumpserver ssh key
ansible.builtin.lineinfile:
dest: "{{ ssh_params.dest }}"
regexp: "{{ ssh_params.regexp }}"
state: absent
when:
- account.secret_type == "ssh_key"
- ssh_params.strategy == "set_jms"
- name: "Change {{ account.username }} SSH key"
ansible.builtin.authorized_key:
user: "{{ account.username }}"
key: "{{ account.secret }}"
exclusive: "{{ ssh_params.exclusive }}"
when: account.secret_type == "ssh_key"
when: user_info.msg is defined
- name: "Set {{ account.username }} sudo setting"
ansible.builtin.lineinfile:
@ -67,9 +33,61 @@
line: "{{ account.username + ' ALL=(ALL) NOPASSWD: ' + params.sudo }}"
validate: visudo -cf %s
when:
- user_info.failed
- user_info.msg is defined or params.modify_sudo
- params.sudo
- name: "Change {{ account.username }} password"
ansible.builtin.user:
name: "{{ account.username }}"
password: "{{ account.secret | password_hash('sha512') }}"
update_password: always
ignore_errors: true
register: change_secret_result
when: account.secret_type == "password"
- name: "Get home directory for {{ account.username }}"
ansible.builtin.shell: "getent passwd {{ account.username }} | cut -d: -f6"
register: home_dir
when: account.secret_type == "ssh_key"
ignore_errors: yes
- name: "Check if home directory exists for {{ account.username }}"
ansible.builtin.stat:
path: "{{ home_dir.stdout.strip() }}"
register: home_dir_stat
when: account.secret_type == "ssh_key"
ignore_errors: yes
- name: "Ensure {{ account.username }} home directory exists"
ansible.builtin.file:
path: "{{ home_dir.stdout.strip() }}"
state: directory
owner: "{{ account.username }}"
group: "{{ account.username }}"
mode: '0750'
when:
- account.secret_type == "ssh_key"
- home_dir_stat.stat.exists == false
ignore_errors: yes
- name: Remove jumpserver ssh key
ansible.builtin.lineinfile:
dest: "{{ home_dir.stdout.strip() }}/.ssh/authorized_keys"
regexp: "{{ ssh_params.regexp }}"
state: absent
when:
- account.secret_type == "ssh_key"
- ssh_params.strategy == "set_jms"
ignore_errors: yes
- name: "Change {{ account.username }} SSH key"
ansible.builtin.authorized_key:
user: "{{ account.username }}"
key: "{{ account.secret }}"
exclusive: "{{ ssh_params.exclusive }}"
register: change_secret_result
when: account.secret_type == "ssh_key"
- name: Refresh connection
ansible.builtin.meta: reset_connection
@ -79,14 +97,16 @@
login_password: "{{ account.secret }}"
login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}"
gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}"
gateway_args: "{{ jms_asset.ansible_ssh_common_args | default(None) }}"
become: "{{ account.become.ansible_become | default(False) }}"
become_method: su
become_user: "{{ account.become.ansible_user | default('') }}"
become_password: "{{ account.become.ansible_password | default('') }}"
become_private_key_path: "{{ account.become.ansible_ssh_private_key_file | default(None) }}"
old_ssh_version: "{{ jms_asset.old_ssh_version | default(False) }}"
when: account.secret_type == "password"
when:
- account.secret_type == "password"
- check_conn_after_change or change_secret_result.failed | default(false)
delegate_to: localhost
- name: "Verify {{ account.username }} SSH KEY (paramiko)"
@ -95,7 +115,9 @@
login_port: "{{ jms_asset.port }}"
login_user: "{{ account.username }}"
login_private_key_path: "{{ account.private_key_path }}"
gateway_args: "{{ jms_asset.ansible_ssh_common_args | default('') }}"
gateway_args: "{{ jms_asset.ansible_ssh_common_args | default(None) }}"
old_ssh_version: "{{ jms_asset.old_ssh_version | default(False) }}"
when: account.secret_type == "ssh_key"
when:
- account.secret_type == "ssh_key"
- check_conn_after_change or change_secret_result.failed | default(false)
delegate_to: localhost

View File

@ -6,6 +6,12 @@ type:
- linux
method: change_secret
params:
- name: modify_sudo
type: bool
label: "{{ 'Modify sudo label' | trans }}"
default: False
help_text: "{{ 'Modify params sudo help text' | trans }}"
- name: sudo
type: str
label: 'Sudo'
@ -24,18 +30,35 @@ params:
default: ''
help_text: "{{ 'Params home help text' | trans }}"
- name: group
type: str
label: "{{ 'Params group label' | trans }}"
default: ''
help_text: "{{ 'Params group help text' | trans }}"
- name: groups
type: str
label: "{{ 'Params groups label' | trans }}"
default: ''
help_text: "{{ 'Params groups help text' | trans }}"
- name: uid
type: str
label: "{{ 'Params uid label' | trans }}"
default: ''
help_text: "{{ 'Params uid help text' | trans }}"
i18n:
Posix account change secret:
zh: '使用 Ansible 模块 user 执行账号改密 (SHA512)'
ja: 'Ansible user モジュールを使用して アカウントのパスワード変更 (SHA512)'
en: 'Using Ansible module user to change account secret (SHA512)'
Modify params sudo help text:
zh: '如果用户存在可以修改sudo权限'
ja: 'ユーザーが存在する場合、sudo権限を変更できます'
en: 'If the user exists, sudo permissions can be modified'
Params sudo help text:
zh: '使用逗号分隔多个命令,如: /bin/whoami,/sbin/ifconfig'
ja: 'コンマで区切って複数のコマンドを入力してください。例: /bin/whoami,/sbin/ifconfig'
@ -46,11 +69,26 @@ i18n:
ja: 'デフォルトのホームディレクトリ /home/{アカウントユーザ名}'
en: 'Default home directory /home/{account username}'
Params group help text:
zh: '请输入用户组(名字或数字),只能输入一个(需填写已存在的用户组)'
ja: 'ユーザー グループ (名前または番号) を入力してください。入力できるのは 1 つだけです (既存のユーザー グループを入力する必要があります)'
en: 'Please enter a user group (name or number), only one can be entered (must fill in an existing user group)'
Params groups help text:
zh: '请输入用户组,多个用户组使用逗号分隔(需填写已存在的用户组)'
ja: 'グループを入力してください。複数のグループはコンマで区切ってください(既存のグループを入力してください)'
en: 'Please enter the group. Multiple groups are separated by commas (please enter the existing group)'
Params uid help text:
zh: '请输入用户ID'
ja: 'ユーザーIDを入力してください'
en: 'Please enter the user ID'
Modify sudo label:
zh: '修改 sudo 权限'
ja: 'sudo 権限を変更'
en: 'Modify sudo'
Params home label:
zh: '家目录'
ja: 'ホームディレクトリ'
@ -61,3 +99,12 @@ i18n:
ja: 'グループ'
en: 'Groups'
Params group label:
zh: '主组'
ja: '主组'
en: 'Main group'
Params uid label:
zh: '用户ID'
ja: 'ユーザーID'
en: 'User ID'

View File

@ -4,10 +4,6 @@
- name: Test privileged account
ansible.windows.win_ping:
# - name: Print variables
# debug:
# msg: "Username: {{ account.username }}, Password: {{ account.secret }}"
- name: Change password
ansible.windows.win_user:
fullname: "{{ account.username}}"
@ -28,4 +24,4 @@
vars:
ansible_user: "{{ account.username }}"
ansible_password: "{{ account.secret }}"
when: account.secret_type == "password"
when: account.secret_type == "password" and check_conn_after_change

View File

@ -8,7 +8,7 @@ type:
params:
- name: groups
type: str
label: '用户组'
label: "{{ 'Params groups label' | trans }}"
default: 'Users,Remote Desktop Users'
help_text: "{{ 'Params groups help text' | trans }}"
@ -24,3 +24,7 @@ i18n:
ja: 'グループを入力してください。複数のグループはコンマで区切ってください(既存のグループを入力してください)'
en: 'Please enter the group. Multiple groups are separated by commas (please enter the existing group)'
Params groups label:
zh: '用户组'
ja: 'グループ'
en: 'Groups'

View File

@ -0,0 +1,27 @@
- hosts: demo
gather_facts: no
tasks:
- name: Test privileged account
ansible.windows.win_ping:
- name: Change password
community.windows.win_domain_user:
name: "{{ account.username }}"
password: "{{ account.secret }}"
update_password: always
password_never_expires: yes
state: present
groups: "{{ params.groups }}"
groups_action: add
ignore_errors: true
when: account.secret_type == "password"
- name: Refresh connection
ansible.builtin.meta: reset_connection
- name: Verify password
ansible.windows.win_ping:
vars:
ansible_user: "{{ account.full_username }}"
ansible_password: "{{ account.secret }}"
when: account.secret_type == "password" and check_conn_after_change

View File

@ -0,0 +1,32 @@
id: change_secret_ad_windows
name: "{{ 'Windows account change secret' | trans }}"
version: 1
method: change_secret
category:
- ds
type:
- windows_ad
params:
- name: groups
type: str
label: "{{ 'Params groups label' | trans }}"
default: 'Users,Remote Desktop Users'
help_text: "{{ 'Params groups help text' | trans }}"
i18n:
Windows account change secret:
zh: '使用 Ansible 模块 win_domain_user 执行 Windows 账号改密'
ja: 'Ansible win_domain_user モジュールを使用して Windows アカウントのパスワード変更'
en: 'Using Ansible module win_domain_user to change Windows account secret'
Params groups help text:
zh: '请输入用户组,多个用户组使用逗号分隔(需填写已存在的用户组)'
ja: 'グループを入力してください。複数のグループはコンマで区切ってください(既存のグループを入力してください)'
en: 'Please enter the group. Multiple groups are separated by commas (please enter the existing group)'
Params groups label:
zh: '用户组'
ja: 'グループ'
en: 'Groups'

View File

@ -4,10 +4,6 @@
- name: Test privileged account
ansible.windows.win_ping:
# - name: Print variables
# debug:
# msg: "Username: {{ account.username }}, Password: {{ account.secret }}"
- name: Change password
ansible.windows.win_user:
fullname: "{{ account.username}}"
@ -25,11 +21,11 @@
- name: Verify password (pyfreerdp)
rdp_ping:
login_host: "{{ jms_asset.address }}"
login_host: "{{ jms_asset.origin_address }}"
login_port: "{{ jms_asset.protocols | selectattr('name', 'equalto', 'rdp') | map(attribute='port') | first }}"
login_user: "{{ account.username }}"
login_password: "{{ account.secret }}"
login_secret_type: "{{ account.secret_type }}"
login_private_key_path: "{{ account.private_key_path }}"
when: account.secret_type == "password"
gateway_args: "{{ jms_gateway | default({}) }}"
when: account.secret_type == "password" and check_conn_after_change
delegate_to: localhost

View File

@ -9,19 +9,24 @@ priority: 49
params:
- name: groups
type: str
label: '用户组'
label: "{{ 'Params groups label' | trans }}"
default: 'Users,Remote Desktop Users'
help_text: "{{ 'Params groups help text' | trans }}"
i18n:
Windows account change secret rdp verify:
zh: '使用 Ansible 模块 win_user 执行 Windows 账号改密 RDP 协议测试最后的可连接性'
ja: 'Ansibleモジュールwin_userはWindowsアカウントの改密RDPプロトコルテストの最後の接続性を実行する'
en: 'Using the Ansible module win_user performs Windows account encryption RDP protocol testing for final connectivity'
zh: '使用 Ansible 模块 win_user 执行 Windows 账号改密(最后使用 Python 模块 pyfreerdp 验证账号的可连接性)'
ja: 'Ansible モジュール win_user を使用して Windows アカウントのパスワードを変更します (最後に Python モジュール pyfreerdp を使用してアカウントの接続を確認します)'
en: 'Use the Ansible module win_user to change the Windows account password (finally use the Python module pyfreerdp to verify the account connectivity)'
Params groups help text:
zh: '请输入用户组,多个用户组使用逗号分隔(需填写已存在的用户组)'
ja: 'グループを入力してください。複数のグループはコンマで区切ってください(既存のグループを入力してください)'
en: 'Please enter the group. Multiple groups are separated by commas (please enter the existing group)'
Params groups label:
zh: '用户组'
ja: 'グループ'
en: 'Groups'

View File

@ -1,209 +1,57 @@
import os
import time
from copy import deepcopy
from django.conf import settings
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from xlsxwriter import Workbook
from accounts.const import AutomationTypes, SecretType, SSHKeyStrategy, SecretStrategy, ChangeSecretRecordStatusChoice
from accounts.const import (
AutomationTypes, SecretStrategy, ChangeSecretRecordStatusChoice
)
from accounts.models import ChangeSecretRecord
from accounts.notifications import ChangeSecretExecutionTaskMsg, ChangeSecretFailedMsg
from accounts.notifications import ChangeSecretExecutionTaskMsg
from accounts.serializers import ChangeSecretRecordBackUpSerializer
from assets.const import HostTypes
from common.utils import get_logger
from common.utils.file import encrypt_and_compress_zip_file
from common.utils.timezone import local_now_filename
from users.models import User
from ..base.manager import AccountBasePlaybookManager
from ...utils import SecretGenerator
from ..base.manager import BaseChangeSecretPushManager
logger = get_logger(__name__)
class ChangeSecretManager(AccountBasePlaybookManager):
class ChangeSecretManager(BaseChangeSecretPushManager):
ansible_account_prefer = ''
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.record_map = self.execution.snapshot.get('record_map', {})
self.secret_type = self.execution.snapshot.get('secret_type')
self.secret_strategy = self.execution.snapshot.get(
'secret_strategy', SecretStrategy.custom
)
self.ssh_key_change_strategy = self.execution.snapshot.get(
'ssh_key_change_strategy', SSHKeyStrategy.add
)
self.account_ids = self.execution.snapshot['accounts']
self.name_recorder_mapper = {} # 做个映射,方便后面处理
@classmethod
def method_type(cls):
return AutomationTypes.change_secret
def get_ssh_params(self, account, secret, secret_type):
kwargs = {}
if secret_type != SecretType.SSH_KEY:
return kwargs
kwargs['strategy'] = self.ssh_key_change_strategy
kwargs['exclusive'] = 'yes' if kwargs['strategy'] == SSHKeyStrategy.set else 'no'
def gen_account_inventory(self, account, asset, h, path_dir):
record = self.get_or_create_record(asset, account, h['name'])
new_secret, private_key_path = self.handle_ssh_secret(account.secret_type, record.new_secret, path_dir)
h = self.gen_inventory(h, account, new_secret, private_key_path, asset)
return h, record
if kwargs['strategy'] == SSHKeyStrategy.set_jms:
username = account.username
path = f'/{username}' if username == "root" else f'/home/{username}'
kwargs['dest'] = f'{path}/.ssh/authorized_keys'
kwargs['regexp'] = '.*{}$'.format(secret.split()[2].strip())
return kwargs
def get_or_create_record(self, asset, account, name):
asset_account_id = f'{asset.id}-{account.id}'
def secret_generator(self, secret_type):
return SecretGenerator(
self.secret_strategy, secret_type,
self.execution.snapshot.get('password_rules')
)
def get_secret(self, secret_type):
if self.secret_strategy == SecretStrategy.custom:
return self.execution.snapshot['secret']
if asset_account_id in self.record_map:
record_id = self.record_map[asset_account_id]
record = ChangeSecretRecord.objects.filter(id=record_id).first()
else:
return self.secret_generator(secret_type).get_secret()
new_secret = self.get_secret(account)
record = self.create_record(asset, account, new_secret)
def get_accounts(self, privilege_account):
if not privilege_account:
print(f'not privilege account')
return []
self.name_record_mapper[name] = record
return record
asset = privilege_account.asset
accounts = asset.accounts.all()
accounts = accounts.filter(id__in=self.account_ids)
if self.secret_type:
accounts = accounts.filter(secret_type=self.secret_type)
if settings.CHANGE_AUTH_PLAN_SECURE_MODE_ENABLED:
accounts = accounts.filter(privileged=False).exclude(
username__in=['root', 'administrator', privilege_account.username]
)
return accounts
def host_callback(
self, host, asset=None, account=None,
automation=None, path_dir=None, **kwargs
):
host = super().host_callback(
host, asset=asset, account=account, automation=automation,
path_dir=path_dir, **kwargs
def create_record(self, asset, account, new_secret):
record = ChangeSecretRecord(
asset=asset, account=account, execution=self.execution,
old_secret=account.secret, new_secret=new_secret,
comment=f'{account.username}@{asset.address}'
)
if host.get('error'):
return host
accounts = self.get_accounts(account)
if not accounts:
print('没有发现待处理的账号: %s 用户ID: %s 类型: %s' % (
asset.name, self.account_ids, self.secret_type
))
return []
records = []
inventory_hosts = []
if asset.type == HostTypes.WINDOWS and self.secret_type == SecretType.SSH_KEY:
print(f'Windows {asset} does not support ssh key push')
return inventory_hosts
host['ssh_params'] = {}
for account in accounts:
h = deepcopy(host)
secret_type = account.secret_type
h['name'] += '(' + account.username + ')'
if self.secret_type is None:
new_secret = account.secret
else:
new_secret = self.get_secret(secret_type)
if new_secret is None:
print(f'new_secret is None, account: {account}')
continue
asset_account_id = f'{asset.id}-{account.id}'
if asset_account_id not in self.record_map:
recorder = ChangeSecretRecord(
asset=asset, account=account, execution=self.execution,
old_secret=account.secret, new_secret=new_secret,
)
records.append(recorder)
else:
record_id = self.record_map[asset_account_id]
try:
recorder = ChangeSecretRecord.objects.get(id=record_id)
except ChangeSecretRecord.DoesNotExist:
print(f"Record {record_id} not found")
continue
self.name_recorder_mapper[h['name']] = recorder
private_key_path = None
if secret_type == SecretType.SSH_KEY:
private_key_path = self.generate_private_key_path(new_secret, path_dir)
new_secret = self.generate_public_key(new_secret)
h['ssh_params'].update(self.get_ssh_params(account, new_secret, secret_type))
h['account'] = {
'name': account.name,
'username': account.username,
'secret_type': secret_type,
'secret': account.escape_jinja2_syntax(new_secret),
'private_key_path': private_key_path,
'become': account.get_ansible_become_auth(),
}
if asset.platform.type == 'oracle':
h['account']['mode'] = 'sysdba' if account.privileged else None
inventory_hosts.append(h)
ChangeSecretRecord.objects.bulk_create(records)
return inventory_hosts
def on_host_success(self, host, result):
recorder = self.name_recorder_mapper.get(host)
if not recorder:
return
recorder.status = ChangeSecretRecordStatusChoice.success.value
recorder.date_finished = timezone.now()
account = recorder.account
if not account:
print("Account not found, deleted ?")
return
account.secret = recorder.new_secret
account.date_updated = timezone.now()
max_retries = 3
retry_count = 0
while retry_count < max_retries:
try:
recorder.save()
account.save(update_fields=['secret', 'version', 'date_updated'])
break
except Exception as e:
retry_count += 1
if retry_count == max_retries:
self.on_host_error(host, str(e), result)
else:
print(f'retry {retry_count} times for {host} recorder save error: {e}')
time.sleep(1)
def on_host_error(self, host, error, result):
recorder = self.name_recorder_mapper.get(host)
if not recorder:
return
recorder.status = ChangeSecretRecordStatusChoice.failed.value
recorder.date_finished = timezone.now()
recorder.error = error
try:
recorder.save()
except Exception as e:
print(f"\033[31m Save {host} recorder error: {e} \033[0m\n")
def on_runner_failed(self, runner, e):
logger.error("Account error: ", e)
return record
def check_secret(self):
if self.secret_strategy == SecretStrategy.custom \
@ -213,59 +61,50 @@ class ChangeSecretManager(AccountBasePlaybookManager):
return True
@staticmethod
def get_summary(recorders):
def get_summary(records):
total, succeed, failed = 0, 0, 0
for recorder in recorders:
if recorder.status == ChangeSecretRecordStatusChoice.success.value:
for record in records:
if record.status == ChangeSecretRecordStatusChoice.success.value:
succeed += 1
else:
failed += 1
total += 1
summary = _('Success: %s, Failed: %s, Total: %s') % (succeed, failed, total)
return summary
def run(self, *args, **kwargs):
def print_summary(self):
records = list(self.name_record_mapper.values())
summary = self.get_summary(records)
print('\n\n' + '-' * 80)
plan_execution_end = _('Plan execution end')
print('{} {}\n'.format(plan_execution_end, local_now_filename()))
time_cost = _('Duration')
print('{}: {}s'.format(time_cost, self.duration))
print(summary)
def send_report_if_need(self, *args, **kwargs):
if self.secret_type and not self.check_secret():
return
super().run(*args, **kwargs)
recorders = list(self.name_recorder_mapper.values())
summary = self.get_summary(recorders)
print(summary, end='')
records = list(self.name_record_mapper.values())
if self.record_map:
return
failed_recorders = [
r for r in recorders
if r.status == ChangeSecretRecordStatusChoice.failed.value
]
recipients = self.execution.recipients
recipients = User.objects.filter(id__in=list(recipients.keys()))
if not recipients:
return
if failed_recorders:
name = self.execution.snapshot.get('name')
execution_id = str(self.execution.id)
_ids = [r.id for r in failed_recorders]
asset_account_errors = ChangeSecretRecord.objects.filter(
id__in=_ids).values_list('asset__name', 'account__username', 'error')
for user in recipients:
ChangeSecretFailedMsg(name, execution_id, user, asset_account_errors).publish()
if not recorders:
if not records:
return
self.send_recorder_mail(recipients, recorders, summary)
summary = self.get_summary(records)
self.send_record_mail(recipients, records, summary)
def send_recorder_mail(self, recipients, recorders, summary):
def send_record_mail(self, recipients, records, summary):
name = self.execution.snapshot['name']
path = os.path.join(os.path.dirname(settings.BASE_DIR), 'tmp')
filename = os.path.join(path, f'{name}-{local_now_filename()}-{time.time()}.xlsx')
if not self.create_file(recorders, filename):
if not self.create_file(records, filename):
return
for user in recipients:
@ -278,9 +117,9 @@ class ChangeSecretManager(AccountBasePlaybookManager):
os.remove(filename)
@staticmethod
def create_file(recorders, filename):
def create_file(records, filename):
serializer_cls = ChangeSecretRecordBackUpSerializer
serializer = serializer_cls(recorders, many=True)
serializer = serializer_cls(records, many=True)
header = [str(v.label) for v in serializer.child.fields.values()]
rows = [[str(i) for i in row.values()] for row in serializer.data]
@ -295,3 +134,6 @@ class ChangeSecretManager(AccountBasePlaybookManager):
ws.write_string(row_index, col_index, col_data)
wb.close()
return True
def get_report_template(self):
return "accounts/change_secret_report.html"

View File

@ -0,0 +1,78 @@
#!/usr/bin/env python
#
import re
import sqlite3
import sys
def is_weak_password(password):
if len(password) < 8:
return True
# 判断是否只有一种字符类型
if password.isdigit() or password.isalpha():
return True
# 判断是否只包含数字或字母
if password.islower() or password.isupper():
return True
# 判断是否包含常见弱密码
common_passwords = ["123456", "password", "12345678", "qwerty", "abc123"]
if password.lower() in common_passwords:
return True
# 正则表达式判断字符多样性(数字、字母、特殊字符)
if (
not re.search(r"[A-Za-z]", password)
or not re.search(r"[0-9]", password)
or not re.search(r"[\W_]", password)
):
return True
return False
def parse_it(fname):
count = 0
lines = []
with open(fname, 'rb') as f:
for line in f:
try:
line = line.decode().strip()
except UnicodeDecodeError:
continue
if len(line) > 32:
continue
if is_weak_password(line):
continue
lines.append(line)
count += 0
print(line)
return lines
def insert_to_db(lines):
conn = sqlite3.connect('./leak_passwords.db')
cursor = conn.cursor()
create_table_sql = '''
CREATE TABLE IF NOT EXISTS passwords (
id INTEGER PRIMARY KEY AUTOINCREMENT,
password CHAR(32)
)
'''
create_index_sql = 'CREATE INDEX IF NOT EXISTS idx_password ON passwords(password)'
cursor.execute(create_table_sql)
cursor.execute(create_index_sql)
for line in lines:
cursor.execute('INSERT INTO passwords (password) VALUES (?)', [line])
conn.commit()
if __name__ == '__main__':
filename = sys.argv[1]
lines = parse_it(filename)
insert_to_db(lines)

View File

@ -0,0 +1,292 @@
import hashlib
import os
import re
import sqlite3
import uuid
from django.conf import settings
from django.utils import timezone
from django.utils.translation import gettext_lazy as _
from accounts.models import Account, AccountRisk, RiskChoice
from assets.automations.base.manager import BaseManager
from common.const import ConfirmOrIgnore
from common.decorators import bulk_create_decorator, bulk_update_decorator
from settings.models import LeakPasswords
# 已设置手动 finish
@bulk_create_decorator(AccountRisk)
def create_risk(data):
return AccountRisk(**data)
# 已设置手动 finish
@bulk_update_decorator(AccountRisk, update_fields=["details", "status"])
def update_risk(risk):
return risk
class BaseCheckHandler:
risk = ''
def __init__(self, assets):
self.assets = assets
def check(self, account):
pass
def clean(self):
pass
class CheckSecretHandler(BaseCheckHandler):
risk = RiskChoice.weak_password
@staticmethod
def is_weak_password(password):
# 判断密码长度
if len(password) < 8:
return True
# 判断是否只有一种字符类型
if password.isdigit() or password.isalpha():
return True
# 判断是否只包含数字或字母
if password.islower() or password.isupper():
return True
# 判断是否包含常见弱密码
common_passwords = ["123456", "password", "12345678", "qwerty", "abc123"]
if password.lower() in common_passwords:
return True
# 正则表达式判断字符多样性(数字、字母、特殊字符)
if (
not re.search(r"[A-Za-z]", password)
or not re.search(r"[0-9]", password)
or not re.search(r"[\W_]", password)
):
return True
return False
def check(self, account):
if not account.secret:
return False
return self.is_weak_password(account.secret)
class CheckRepeatHandler(BaseCheckHandler):
risk = RiskChoice.repeated_password
def __init__(self, assets):
super().__init__(assets)
self.path, self.conn, self.cursor = self.init_repeat_check_db()
self.add_password_for_check_repeat()
@staticmethod
def init_repeat_check_db():
path = os.path.join('/tmp', 'accounts_' + str(uuid.uuid4()) + '.db')
sql = """
CREATE TABLE IF NOT EXISTS accounts (
id INTEGER PRIMARY KEY AUTOINCREMENT,
digest CHAR(32)
)
"""
index = "CREATE INDEX IF NOT EXISTS idx_digest ON accounts(digest)"
conn = sqlite3.connect(path)
cursor = conn.cursor()
cursor.execute(sql)
cursor.execute(index)
return path, conn, cursor
def check(self, account):
if not account.secret:
return False
digest = self.digest(account.secret)
sql = 'SELECT COUNT(*) FROM accounts WHERE digest = ?'
self.cursor.execute(sql, [digest])
result = self.cursor.fetchone()
if not result:
return False
return result[0] > 1
@staticmethod
def digest(secret):
return hashlib.md5(secret.encode()).hexdigest()
def add_password_for_check_repeat(self):
accounts = Account.objects.all().only('id', '_secret', 'secret_type')
sql = "INSERT INTO accounts (digest) VALUES (?)"
for account in accounts:
secret = account.secret
if not secret:
continue
digest = self.digest(secret)
self.cursor.execute(sql, [digest])
self.conn.commit()
def clean(self):
self.cursor.close()
self.conn.close()
os.remove(self.path)
class CheckLeakHandler(BaseCheckHandler):
risk = RiskChoice.leaked_password
def __init__(self, *args):
super().__init__(*args)
self.conn, self.cursor = self.init_leak_password_db()
@staticmethod
def init_leak_password_db():
db_path = os.path.join(
settings.APPS_DIR, 'accounts', 'automations',
'check_account', 'leak_passwords.db'
)
if settings.LEAK_PASSWORD_DB_PATH and os.path.isfile(settings.LEAK_PASSWORD_DB_PATH):
db_path = settings.LEAK_PASSWORD_DB_PATH
db_conn = sqlite3.connect(db_path)
db_cursor = db_conn.cursor()
return db_conn, db_cursor
def check(self, account):
if not account.secret:
return False
is_exist = LeakPasswords.objects.using('sqlite').filter(password=account.secret).exists()
return is_exist
def clean(self):
self.cursor.close()
self.conn.close()
class CheckAccountManager(BaseManager):
batch_size = 100
tmpl = 'Checked the status of account %s: %s'
def __init__(self, execution):
super().__init__(execution)
self.assets = []
self.batch_risks = []
self.handlers = []
def add_risk(self, risk, account):
self.summary[risk] += 1
self.result[risk].append({
'asset': str(account.asset), 'username': account.username,
})
risk_obj = {'account': account, 'risk': risk}
self.batch_risks.append(risk_obj)
def commit_risks(self, assets):
account_risks = AccountRisk.objects.filter(asset__in=assets)
ori_risk_map = {}
for risk in account_risks:
key = f'{risk.account_id}_{risk.risk}'
ori_risk_map[key] = risk
now = timezone.now().isoformat()
for d in self.batch_risks:
account = d["account"]
key = f'{account.id}_{d["risk"]}'
origin_risk = ori_risk_map.get(key)
if origin_risk and origin_risk.status != ConfirmOrIgnore.pending:
details = origin_risk.details or []
details.append({"datetime": now, 'type': 'refind'})
if len(details) > 10:
details = [*details[:5], *details[-5:]]
origin_risk.details = details
origin_risk.status = ConfirmOrIgnore.pending
update_risk(origin_risk)
else:
create_risk({
"account": account,
"asset": account.asset,
"username": account.username,
"risk": d["risk"],
"details": [{"datetime": now, 'type': 'init'}],
})
create_risk.finish()
update_risk.finish()
def pre_run(self):
super().pre_run()
self.assets = self.execution.get_all_assets()
def batch_check(self, handler):
print("Engine: {}".format(handler.__class__.__name__))
for i in range(0, len(self.assets), self.batch_size):
_assets = self.assets[i: i + self.batch_size]
accounts = Account.objects.filter(asset__in=_assets)
print("Start to check accounts: {}".format(len(accounts)))
for account in accounts:
error = handler.check(account)
msg = handler.risk if error else 'ok'
print("Check: {} => {}".format(account, msg))
if not error:
AccountRisk.objects.filter(
asset=account.asset,
username=account.username,
risk=handler.risk
).delete()
continue
self.add_risk(handler.risk, account)
self.commit_risks(_assets)
def do_run(self, *args, **kwargs):
engines = self.execution.snapshot.get("engines", [])
if engines == '__all__':
engines = ['check_account_secret', 'check_account_repeat', 'check_account_leak']
for engine in engines:
if engine == "check_account_secret":
handler = CheckSecretHandler(self.assets)
elif engine == "check_account_repeat":
handler = CheckRepeatHandler(self.assets)
elif engine == "check_account_leak":
handler = CheckLeakHandler(self.assets)
else:
print("Unknown engine: {}".format(engine))
continue
self.handlers.append(handler)
self.batch_check(handler)
def post_run(self):
super().post_run()
for handler in self.handlers:
handler.clean()
def get_report_subject(self):
return _("Check account report of {}").format(self.execution.id)
def get_report_template(self):
return "accounts/check_account_report.html"
def print_summary(self):
tmpl = _("---\nSummary: \nok: {}, weak password: {}, leaked password: {}, "
"repeated password: {}, no secret: {}, using time: {}s").format(
self.summary["ok"],
self.summary[RiskChoice.weak_password],
self.summary[RiskChoice.leaked_password],
self.summary[RiskChoice.repeated_password],
self.summary["no_secret"],
self.duration
)
print(tmpl)

View File

@ -1,6 +1,7 @@
from .backup_account.manager import AccountBackupManager
from .change_secret.manager import ChangeSecretManager
from .gather_accounts.manager import GatherAccountsManager
from .check_account.manager import CheckAccountManager
from .gather_account.manager import GatherAccountsManager
from .push_account.manager import PushAccountManager
from .remove_account.manager import RemoveAccountManager
from .verify_account.manager import VerifyAccountManager
@ -16,8 +17,8 @@ class ExecutionManager:
AutomationTypes.remove_account: RemoveAccountManager,
AutomationTypes.gather_accounts: GatherAccountsManager,
AutomationTypes.verify_gateway_account: VerifyGatewayAccountManager,
# TODO 后期迁移到自动化策略中
'backup_account': AccountBackupManager,
AutomationTypes.check_account: CheckAccountManager,
AutomationTypes.backup_account: AccountBackupManager,
}
def __init__(self, execution):
@ -26,3 +27,6 @@ class ExecutionManager:
def run(self, *args, **kwargs):
return self._runner.run(*args, **kwargs)
def __getattr__(self, item):
return getattr(self._runner, item)

View File

@ -1,7 +1,7 @@
- hosts: mongodb
gather_facts: no
vars:
ansible_python_interpreter: /opt/py3/bin/python
ansible_python_interpreter: "{{ local_python_interpreter }}"
tasks:
- name: Get info
@ -15,7 +15,7 @@
ssl_ca_certs: "{{ jms_asset.secret_info.ca_cert | default('') }}"
ssl_certfile: "{{ jms_asset.secret_info.client_key | default('') }}"
connection_options:
- tlsAllowInvalidHostnames: "{{ jms_asset.spec_info.allow_invalid_cert}}"
- tlsAllowInvalidHostnames: "{{ jms_asset.spec_info.allow_invalid_cert }}"
filter: users
register: db_info

View File

@ -1,8 +1,11 @@
- hosts: mysql
gather_facts: no
vars:
ansible_python_interpreter: /opt/py3/bin/python
ansible_python_interpreter: "{{ local_python_interpreter }}"
check_ssl: "{{ jms_asset.spec_info.use_ssl and not jms_asset.spec_info.allow_invalid_cert }}"
ca_cert: "{{ jms_asset.secret_info.ca_cert | default('') }}"
ssl_cert: "{{ jms_asset.secret_info.client_cert | default('') }}"
ssl_key: "{{ jms_asset.secret_info.client_key | default('') }}"
tasks:
- name: Get info
@ -12,9 +15,9 @@
login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}"
check_hostname: "{{ check_ssl if check_ssl else omit }}"
ca_cert: "{{ jms_asset.secret_info.ca_cert | default(omit) if check_ssl else omit }}"
client_cert: "{{ jms_asset.secret_info.client_cert | default(omit) if check_ssl else omit }}"
client_key: "{{ jms_asset.secret_info.client_key | default(omit) if check_ssl else omit }}"
ca_cert: "{{ ca_cert if check_ssl and ca_cert | length > 0 else omit }}"
client_cert: "{{ ssl_cert if check_ssl and ssl_cert | length > 0 else omit }}"
client_key: "{{ ssl_key if check_ssl and ssl_key | length > 0 else omit }}"
filter: users
register: db_info

View File

@ -1,7 +1,7 @@
- hosts: oralce
gather_facts: no
vars:
ansible_python_interpreter: /opt/py3/bin/python
ansible_python_interpreter: "{{ local_python_interpreter }}"
tasks:
- name: Get info

View File

@ -0,0 +1,30 @@
- hosts: postgresql
gather_facts: no
vars:
ansible_python_interpreter: "{{ local_python_interpreter }}"
check_ssl: "{{ jms_asset.spec_info.use_ssl }}"
ca_cert: "{{ jms_asset.secret_info.ca_cert | default('') }}"
ssl_cert: "{{ jms_asset.secret_info.client_cert | default('') }}"
ssl_key: "{{ jms_asset.secret_info.client_key | default('') }}"
tasks:
- name: Get info
community.postgresql.postgresql_info:
login_user: "{{ jms_account.username }}"
login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}"
login_db: "{{ jms_asset.spec_info.db_name }}"
ca_cert: "{{ ca_cert if check_ssl and ca_cert | length > 0 else omit }}"
ssl_cert: "{{ ssl_cert if check_ssl and ssl_cert | length > 0 else omit }}"
ssl_key: "{{ ssl_key if check_ssl and ssl_key | length > 0 else omit }}"
ssl_mode: "{{ jms_asset.spec_info.pg_ssl_mode }}"
filter: "roles"
register: db_info
- name: Define info by set_fact
set_fact:
info: "{{ db_info.roles }}"
- debug:
var: info

View File

@ -0,0 +1,45 @@
- hosts: sqlserver
gather_facts: no
vars:
ansible_python_interpreter: "{{ local_python_interpreter }}"
tasks:
- name: Test SQLServer connection
mssql_script:
login_user: "{{ jms_account.username }}"
login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}"
name: '{{ jms_asset.spec_info.db_name }}'
encryption: "{{ jms_asset.encryption | default(None) }}"
tds_version: "{{ jms_asset.tds_version | default(None) }}"
script: |
SELECT
l.name,
l.modify_date,
l.is_disabled,
l.create_date,
l.default_database_name,
LOGINPROPERTY(name, 'DaysUntilExpiration') AS days_until_expiration,
MAX(s.login_time) AS last_login_time
FROM
sys.sql_logins l
LEFT JOIN
sys.dm_exec_sessions s
ON
l.name = s.login_name
WHERE
s.is_user_process = 1 OR s.login_name IS NULL
GROUP BY
l.name, l.create_date, l.modify_date, l.is_disabled, l.default_database_name
ORDER BY
last_login_time DESC;
output: dict
register: db_info
- name: Define info by set_fact
set_fact:
info: "{{ db_info.query_results_dict }}"
- debug:
var: info

View File

@ -0,0 +1,10 @@
id: gather_accounts_sqlserver
name: "{{ 'SQLServer account gather' | trans }}"
category: database
type:
- sqlserver
method: gather_accounts
i18n:
SQLServer account gather:
zh: SQLServer 账号收集
ja: SQLServer アカウントの収集

View File

@ -0,0 +1,270 @@
from datetime import datetime
from django.utils import timezone
__all__ = ['GatherAccountsFilter']
def parse_date(date_str, default=None):
if not date_str:
return default
if date_str in ['Never', 'null']:
return default
formats = [
'%Y/%m/%d %H:%M:%S',
'%Y-%m-%dT%H:%M:%S',
'%Y-%m-%d %H:%M:%S',
'%d-%m-%Y %H:%M:%S',
'%Y/%m/%d',
'%d-%m-%Y',
]
for fmt in formats:
try:
dt = datetime.strptime(date_str, fmt)
return timezone.make_aware(dt, timezone.get_current_timezone())
except ValueError:
continue
return default
class GatherAccountsFilter:
def __init__(self, tp):
self.tp = tp
@staticmethod
def mysql_filter(info):
result = {}
for host, user_dict in info.items():
for username, user_info in user_dict.items():
password_last_changed = parse_date(user_info.get('password_last_changed'))
password_lifetime = user_info.get('password_lifetime')
user = {
'username': username,
'date_password_change': password_last_changed,
'date_password_expired': password_last_changed + timezone.timedelta(
days=password_lifetime) if password_last_changed and password_lifetime else None,
'date_last_login': None,
'groups': '',
}
result[username] = user
return result
@staticmethod
def postgresql_filter(info):
result = {}
for username, user_info in info.items():
user = {
'username': username,
'date_password_change': None,
'date_password_expired': parse_date(user_info.get('valid_until')),
'date_last_login': None,
'groups': '',
}
detail = {
'can_login': user_info.get('canlogin'),
'superuser': user_info.get('superuser'),
}
user['detail'] = detail
result[username] = user
return result
@staticmethod
def sqlserver_filter(info):
if not info:
return {}
result = {}
for user_info in info[0][0]:
days_until_expiration = user_info.get('days_until_expiration')
date_password_expired = timezone.now() + timezone.timedelta(
days=int(days_until_expiration)) if days_until_expiration else None
user = {
'username': user_info.get('name', ''),
'date_password_change': parse_date(user_info.get('modify_date')),
'date_password_expired': date_password_expired,
'date_last_login': parse_date(user_info.get('last_login_time')),
'groups': '',
}
detail = {
'create_date': user_info.get('create_date', ''),
'is_disabled': user_info.get('is_disabled', ''),
'default_database_name': user_info.get('default_database_name', ''),
}
user['detail'] = detail
result[user['username']] = user
return result
@staticmethod
def oracle_filter(info):
result = {}
for default_tablespace, users in info.items():
for username, user_info in users.items():
user = {
'username': username,
'date_password_change': parse_date(user_info.get('password_change_date')),
'date_password_expired': parse_date(user_info.get('expiry_date')),
'date_last_login': parse_date(user_info.get('last_login')),
'groups': '',
}
detail = {
'uid': user_info.get('user_id', ''),
'create_date': user_info.get('created', ''),
'account_status': user_info.get('account_status', ''),
'default_tablespace': default_tablespace,
'roles': user_info.get('roles', []),
'privileges': user_info.get('privileges', []),
}
user['detail'] = detail
result[user['username']] = user
return result
@staticmethod
def posix_filter(info):
user_groups = info.pop('user_groups', [])
username_groups = {}
for line in user_groups:
if ':' not in line:
continue
username, groups = line.split(':', 1)
username_groups[username.strip()] = groups.strip()
user_sudo = info.pop('user_sudo', [])
username_sudo = {}
for line in user_sudo:
if ':' not in line:
continue
username, sudo = line.split(':', 1)
if not sudo.strip():
continue
username_sudo[username.strip()] = sudo.strip()
last_login = info.pop('last_login', '')
user_last_login = {}
for line in last_login:
if not line.strip() or ' ' not in line:
continue
username, login = line.split(' ', 1)
user_last_login[username] = login.split()
user_authorized = info.pop('user_authorized', [])
username_authorized = {}
for line in user_authorized:
if ':' not in line:
continue
username, authorized = line.split(':', 1)
username_authorized[username.strip()] = authorized.strip()
passwd_date = info.pop('passwd_date', [])
username_password_date = {}
for line in passwd_date:
if ':' not in line:
continue
username, password_date = line.split(':', 1)
username_password_date[username.strip()] = password_date.strip().split()
result = {}
users = info.pop('users', '')
for username in users:
if not username:
continue
user = dict()
login = user_last_login.get(username) or ''
if login and len(login) == 3:
user['address_last_login'] = login[0][:32]
try:
login_date = timezone.datetime.fromisoformat(login[1])
user['date_last_login'] = login_date
except ValueError:
pass
start_date = timezone.make_aware(timezone.datetime(1970, 1, 1))
_password_date = username_password_date.get(username) or ''
if _password_date and len(_password_date) == 2:
if _password_date[0]:
user['date_password_change'] = start_date + timezone.timedelta(days=int(_password_date[0]))
if _password_date[1]:
user['date_password_expired'] = start_date + timezone.timedelta(days=int(_password_date[1]))
detail = {
'groups': username_groups.get(username) or '',
'sudoers': username_sudo.get(username) or '',
'authorized_keys': username_authorized.get(username) or ''
}
user['detail'] = detail
result[username] = user
return result
@staticmethod
def windows_filter(info):
result = {}
for user_details in info['user_details']:
user_info = {}
lines = user_details['stdout_lines']
for line in lines:
if not line.strip():
continue
parts = line.split(' ', 1)
if len(parts) == 2:
key, value = parts
user_info[key.strip()] = value.strip()
detail = {'groups': user_info.get('Global Group memberships', ''), }
username = user_info.get('User name')
if not username:
continue
result[username] = {
'username': username,
'date_password_change': parse_date(user_info.get('Password last set')),
'date_password_expired': parse_date(user_info.get('Password expires')),
'date_last_login': parse_date(user_info.get('Last logon')),
'groups': detail,
}
return result
@staticmethod
def windows_ad_filter(info):
result = {}
for user_info in info['user_details']:
detail = {'groups': user_info.get('GlobalGroupMemberships', ''), }
username = user_info.get('SamAccountName')
if not username:
continue
result[username] = {
'username': username,
'date_password_change': parse_date(user_info.get('PasswordLastSet')),
'date_password_expired': parse_date(user_info.get('PasswordExpires')),
'date_last_login': parse_date(user_info.get('LastLogonDate')),
'groups': detail,
}
return result
@staticmethod
def mongodb_filter(info):
result = {}
for db, users in info.items():
for username, user_info in users.items():
user = {
'username': username,
'date_password_change': None,
'date_password_expired': None,
'date_last_login': None,
'groups': '',
}
result['detail'] = {'db': db, 'roles': user_info.get('roles', [])}
result[username] = user
return result
def run(self, method_id_meta_mapper, info):
run_method_name = None
for k, v in method_id_meta_mapper.items():
if self.tp not in v['type']:
continue
run_method_name = k.replace(f'{v["method"]}_', '')
if not run_method_name:
return info
if hasattr(self, f'{run_method_name}_filter'):
return getattr(self, f'{run_method_name}_filter')(info)
return info

View File

@ -0,0 +1,61 @@
- hosts: demo
gather_facts: no
tasks:
- name: Get users
ansible.builtin.shell:
cmd: >
getent passwd | awk -F: '$7 !~ /(false|nologin|true|sync)$/' | grep -v '^$' | awk -F":" '{ print $1 }'
register: users
- name: Gather posix account last login
ansible.builtin.shell: |
for user in {{ users.stdout_lines | join(" ") }}; do
last -wi --time-format iso -n 1 ${user} | awk '{ print $1,$3,$4, $NF }' | head -1 | awk 'NF'
done
register: last_login
- name: Get user password change date and expiry
ansible.builtin.shell: |
for user in {{ users.stdout_lines | join(" ") }}; do
k=$(getent shadow $user | awk -F: '{ print $3, $5 }')
echo "$user:$k"
done
register: passwd_date
- name: Get user groups
ansible.builtin.shell: |
for user in {{ users.stdout_lines | join(" ") }}; do
echo "$(groups $user)" | sed 's@ : @:@g'
done
register: user_groups
- name: Get sudoers
ansible.builtin.shell: |
for user in {{ users.stdout_lines | join(" ") }}; do
echo "$user: $(grep "^$user " /etc/sudoers | tr '\n' ';' || echo '')"
done
register: user_sudo
- name: Get authorized keys
ansible.builtin.shell: |
for user in {{ users.stdout_lines | join(" ") }}; do
home=$(getent passwd $user | cut -d: -f6)
echo -n "$user:"
if [ -f "${home}/.ssh/authorized_keys" ]; then
cat ${home}/.ssh/authorized_keys | tr '\n' ';'
fi
echo
done
register: user_authorized
- set_fact:
info:
users: "{{ users.stdout_lines }}"
last_login: "{{ last_login.stdout_lines }}"
user_groups: "{{ user_groups.stdout_lines }}"
user_sudo: "{{ user_sudo.stdout_lines }}"
user_authorized: "{{ user_authorized.stdout_lines }}"
passwd_date: "{{ passwd_date.stdout_lines }}"
- debug:
var: info

View File

@ -0,0 +1,33 @@
- hosts: demo
gather_facts: no
tasks:
- name: Run net user command to get all users
win_shell: net user
register: user_list_output
failed_when: false
- name: Parse all users from net user command
set_fact:
all_users: >-
{%- set users = [] -%}
{%- for line in user_list_output.stdout_lines -%}
{%- if loop.index > 4 and line.strip() != "" and not line.startswith("The command completed") -%}
{%- for user in line.split() -%}
{%- set _ = users.append(user) -%}
{%- endfor -%}
{%- endif -%}
{%- endfor -%}
{{ users }}
- name: Run net user command for each user to get details
win_shell: net user {{ item }}
loop: "{{ all_users }}"
register: user_details
ignore_errors: yes
- set_fact:
info:
user_details: "{{ user_details.results }}"
- debug:
var: info

View File

@ -2,10 +2,13 @@ id: gather_accounts_windows
name: "{{ 'Windows account gather' | trans }}"
version: 1
method: gather_accounts
category: host
category:
- host
type:
- windows
i18n:
Windows account gather:
zh: 使用命令 net user 收集 Windows 账号

View File

@ -0,0 +1,74 @@
- hosts: demo
gather_facts: no
tasks:
- name: Import ActiveDirectory module
win_shell: Import-Module ActiveDirectory
args:
warn: false
- name: Get the SamAccountName list of all AD users
win_shell: |
Import-Module ActiveDirectory
Get-ADUser -Filter * | Select-Object -ExpandProperty SamAccountName
register: ad_user_list
- name: Set the all_users variable
set_fact:
all_users: "{{ ad_user_list.stdout_lines }}"
- name: Get detailed information for each user
win_shell: |
Import-Module ActiveDirectory
$user = Get-ADUser -Identity {{ item }} -Properties Name, SamAccountName, Enabled, LastLogonDate, PasswordLastSet, msDS-UserPasswordExpiryTimeComputed, MemberOf
$globalGroups = @()
if ($user.MemberOf) {
$globalGroups = $user.MemberOf | ForEach-Object {
try {
$group = Get-ADGroup $_ -ErrorAction Stop
if ($group.GroupScope -eq 'Global') { $group.Name }
} catch {
}
}
}
$passwordExpiry = $null
$expiryRaw = $user.'msDS-UserPasswordExpiryTimeComputed'
if ($expiryRaw) {
try {
$passwordExpiry = [datetime]::FromFileTime($expiryRaw)
} catch {
$passwordExpiry = $null
}
}
$output = [PSCustomObject]@{
Name = $user.Name
SamAccountName = $user.SamAccountName
Enabled = $user.Enabled
LastLogonDate = if ($user.LastLogonDate) { $user.LastLogonDate.ToString("yyyy-MM-dd HH:mm:ss") } else { $null }
PasswordLastSet = if ($user.PasswordLastSet) { $user.PasswordLastSet.ToString("yyyy-MM-dd HH:mm:ss") } else { $null }
PasswordExpires = if ($passwordExpiry) { $passwordExpiry.ToString("yyyy-MM-dd HH:mm:ss") } else { $null }
GlobalGroupMemberships = $globalGroups
}
$output | ConvertTo-Json -Depth 3
loop: "{{ all_users }}"
register: ad_user_details
ignore_errors: yes
- set_fact:
info:
user_details: >-
{{
ad_user_details.results
| selectattr('rc', 'equalto', 0)
| map(attribute='stdout')
| select('truthy')
| map('from_json')
}}
- debug:
var: info

View File

@ -0,0 +1,15 @@
id: gather_accounts_windows_ad
name: "{{ 'Windows account gather' | trans }}"
version: 1
method: gather_accounts
category:
- ds
type:
- windows_ad
i18n:
Windows account gather:
zh: 使用命令 Get-ADUser 收集 Windows 账号
ja: コマンド Get-ADUser を使用して Windows アカウントを収集する
en: Using command Get-ADUser to gather accounts

View File

@ -0,0 +1,415 @@
import time
from collections import defaultdict
from django.utils import timezone
from accounts.const import AutomationTypes
from accounts.models import GatheredAccount, Account, AccountRisk, RiskChoice
from common.const import ConfirmOrIgnore
from common.decorators import bulk_create_decorator, bulk_update_decorator
from common.utils import get_logger
from common.utils.strings import get_text_diff
from orgs.utils import tmp_to_org
from .filter import GatherAccountsFilter
from ..base.manager import AccountBasePlaybookManager
logger = get_logger(__name__)
risk_items = [
"authorized_keys",
"sudoers",
"groups",
]
common_risk_items = [
"address_last_login",
"date_last_login",
"date_password_change",
"date_password_expired",
"detail"
]
diff_items = risk_items + common_risk_items
@bulk_create_decorator(AccountRisk)
def _create_risk(data):
return AccountRisk(**data)
@bulk_update_decorator(AccountRisk, update_fields=["details"])
def _update_risk(account):
return account
def format_datetime(value):
if isinstance(value, timezone.datetime):
return value.strftime("%Y-%m-%d %H:%M:%S")
return value
def get_items_diff(ori_account, d):
if hasattr(ori_account, "_diff"):
return ori_account._diff
diff = {}
for item in diff_items:
get_item_diff(item, ori_account, d, diff)
ori_account._diff = diff
return diff
def get_item_diff(item, ori_account, d, diff):
detail = getattr(ori_account, 'detail', {})
new_detail = d.get('detail', {})
ori = getattr(ori_account, item, None) or detail.get(item)
new = d.get(item, "") or new_detail.get(item)
if not ori and not new:
return
ori = format_datetime(ori)
new = format_datetime(new)
if new != ori:
diff[item] = get_text_diff(str(ori), str(new))
class AnalyseAccountRisk:
long_time = timezone.timedelta(days=90)
datetime_check_items = [
{"field": "date_last_login", "risk": "long_time_no_login", "delta": long_time},
{
"field": "date_password_change",
"risk": RiskChoice.long_time_password,
"delta": long_time,
},
{
"field": "date_password_expired",
"risk": "password_expired",
"delta": timezone.timedelta(seconds=1),
},
]
def __init__(self, check_risk=True):
self.check_risk = check_risk
self.now = timezone.now()
self.pending_add_risks = []
def _analyse_item_changed(self, ori_ga, d):
diff = get_items_diff(ori_ga, d)
if not diff:
return
risks = []
for k, v in diff.items():
if k not in risk_items:
continue
risks.append(
dict(
asset_id=str(ori_ga.asset_id),
username=ori_ga.username,
gathered_account=ori_ga,
risk=k + "_changed",
detail={"diff": v},
)
)
self.save_or_update_risks(risks)
def _analyse_datetime_changed(self, ori_account, d, asset, username):
basic = {"asset_id": str(asset.id), "username": username}
risks = []
for item in self.datetime_check_items:
field = item["field"]
risk = item["risk"]
delta = item["delta"]
date = d.get(field)
if not date:
continue
# 服务器收集的时间和数据库时间一致,不进行比较,无法检测风险 不太对,先注释
# pre_date = ori_account and getattr(ori_account, field)
# if pre_date == date:
# continue
if date and date < timezone.now() - delta:
risks.append(
dict(**basic, risk=risk, detail={"date": date.isoformat()})
)
self.save_or_update_risks(risks)
def save_or_update_risks(self, risks):
# 提前取出来,避免每次都查数据库
asset_ids = {r["asset_id"] for r in risks}
assets_risks = AccountRisk.objects.filter(asset_id__in=asset_ids)
assets_risks = {f"{r.asset_id}_{r.username}_{r.risk}": r for r in assets_risks}
for d in risks:
detail = d.pop("detail", {})
detail["datetime"] = self.now.isoformat()
key = f"{d['asset_id']}_{d['username']}_{d['risk']}"
found = assets_risks.get(key)
if not found:
_create_risk(dict(**d, details=[detail]))
continue
found.details.append(detail)
_update_risk(found)
def lost_accounts(self, asset, lost_users):
if not self.check_risk:
return
for user in lost_users:
_create_risk(
dict(
asset_id=str(asset.id),
username=user,
risk=RiskChoice.account_deleted,
details=[{"datetime": self.now.isoformat()}],
)
)
def analyse_risk(self, asset, ga, d, sys_found):
if not self.check_risk:
return
if ga:
self._analyse_item_changed(ga, d)
if not sys_found:
basic = {"asset": asset, "username": d["username"], 'gathered_account': ga}
_create_risk(
dict(
**basic,
risk=RiskChoice.new_found,
details=[{"datetime": self.now.isoformat()}],
)
)
self._analyse_datetime_changed(ga, d, asset, d["username"])
class GatherAccountsManager(AccountBasePlaybookManager):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.host_asset_mapper = {}
self.asset_account_info = {}
self.asset_usernames_mapper = defaultdict(set)
self.ori_asset_usernames = defaultdict(set)
self.ori_gathered_usernames = defaultdict(set)
self.ori_gathered_accounts_mapper = dict()
self.is_sync_account = self.execution.snapshot.get("is_sync_account")
self.check_risk = self.execution.snapshot.get("check_risk", False)
@classmethod
def method_type(cls):
return AutomationTypes.gather_accounts
def host_callback(self, host, asset=None, **kwargs):
super().host_callback(host, asset=asset, **kwargs)
self.host_asset_mapper[host["name"]] = asset
return host
def _filter_success_result(self, tp, result):
result = GatherAccountsFilter(tp).run(self.method_id_meta_mapper, result)
return result
@staticmethod
def _get_nested_info(data, *keys):
for key in keys:
data = data.get(key, {})
if not data:
break
return data
def _collect_asset_account_info(self, asset, info):
result = self._filter_success_result(asset.type, info)
accounts = []
for username, info in result.items():
self.asset_usernames_mapper[str(asset.id)].add(username)
d = {"asset": asset, "username": username, "remote_present": True, **info}
accounts.append(d)
self.asset_account_info[asset] = accounts
def on_host_success(self, host, result):
super().on_host_success(host, result)
info = self._get_nested_info(result, "debug", "res", "info")
asset = self.host_asset_mapper.get(host)
if asset and info:
self._collect_asset_account_info(asset, info)
else:
print(f"\033[31m Not found {host} info \033[0m\n")
def prefetch_origin_account_usernames(self):
"""
提起查出来避免每次 sql 查询
:return:
"""
assets = self.asset_usernames_mapper.keys()
accounts = Account.objects.filter(asset__in=assets).values_list(
"asset", "username"
)
for asset_id, username in accounts:
self.ori_asset_usernames[str(asset_id)].add(username)
ga_accounts = GatheredAccount.objects.filter(asset__in=assets)
for account in ga_accounts:
self.ori_gathered_usernames[str(account.asset_id)].add(account.username)
key = "{}_{}".format(account.asset_id, account.username)
self.ori_gathered_accounts_mapper[key] = account
def update_gather_accounts_status(self, asset):
"""
远端账号收集中的账号vault 中的账号
要根据账号新增见啥标识 收集账号的状态, 让管理员关注
远端账号 -> 收集账号 -> 特权账号
"""
remote_users = self.asset_usernames_mapper[str(asset.id)]
ori_users = self.ori_asset_usernames[str(asset.id)]
ori_ga_users = self.ori_gathered_usernames[str(asset.id)]
queryset = GatheredAccount.objects.filter(asset=asset).exclude(
status=ConfirmOrIgnore.ignored
)
# 远端账号 比 收集账号多的
# 新增创建,不用处理状态
new_found_users = remote_users - ori_ga_users
if new_found_users:
self.summary["new_accounts"] += len(new_found_users)
for username in new_found_users:
self.result["new_accounts"].append(
{
"asset": str(asset),
"username": username,
}
)
# 远端上 比 收集账号少的
# 标识 remote_present=False, 标记为待处理
# 远端资产上不存在的,标识为待处理,需要管理员介入
lost_users = ori_ga_users - remote_users
if lost_users:
queryset.filter(username__in=lost_users).update(
status=ConfirmOrIgnore.pending, remote_present=False
)
self.summary["lost_accounts"] += len(lost_users)
for username in lost_users:
self.result["lost_accounts"].append(
{
"asset": str(asset),
"username": username,
}
)
risk_analyser = AnalyseAccountRisk(self.check_risk)
risk_analyser.lost_accounts(asset, lost_users)
# 收集的账号 比 账号列表多的, 有可能是账号中删掉了, 但这时候状态已经是 confirm 了
# 标识状态为 待处理, 让管理员去确认
ga_added_users = ori_ga_users - ori_users
if ga_added_users:
queryset.filter(username__in=ga_added_users).update(status=ConfirmOrIgnore.pending)
# 收集的账号 比 账号列表少的
# 这个好像不不用对比,原始情况就这样
# 远端账号 比 账号列表少的
# 创建收集账号,标识 remote_present=False, 状态待处理
# 远端账号 比 账号列表多的
# 正常情况, 不用处理,因为远端账号会创建到收集账号,收集账号再去对比
# 不过这个好像也处理一下 status因为已存在这是状态应该是确认
(
queryset.filter(username__in=ori_users)
.exclude(status=ConfirmOrIgnore.confirmed)
.update(status=ConfirmOrIgnore.confirmed)
)
# 远端存在的账号,标识为已存在
(
queryset.filter(username__in=remote_users, remote_present=False).update(
remote_present=True
)
)
# 资产上没有的,标识为为存在
(
queryset.exclude(username__in=ori_users)
.filter(present=True)
.update(present=False)
)
(
queryset.filter(username__in=ori_users)
.filter(present=False)
.update(present=True)
)
@bulk_create_decorator(GatheredAccount)
def create_gathered_account(self, d):
ga = GatheredAccount()
for k, v in d.items():
setattr(ga, k, v)
return ga
@bulk_update_decorator(GatheredAccount, update_fields=common_risk_items)
def update_gathered_account(self, ori_account, d):
diff = get_items_diff(ori_account, d)
if not diff:
return
for k in diff:
if k not in common_risk_items:
continue
v = d.get(k)
setattr(ori_account, k, v)
return ori_account
def do_run(self, *args, **kwargs):
super().do_run(*args, **kwargs)
self.prefetch_origin_account_usernames()
risk_analyser = AnalyseAccountRisk(self.check_risk)
for asset, accounts_data in self.asset_account_info.items():
ori_users = self.ori_asset_usernames[str(asset.id)]
need_analyser_gather_account = []
with tmp_to_org(asset.org_id):
for d in accounts_data:
username = d["username"]
ori_account = self.ori_gathered_accounts_mapper.get(
"{}_{}".format(asset.id, username)
)
if not ori_account:
ga = self.create_gathered_account(d)
else:
ga = ori_account
self.update_gathered_account(ori_account, d)
ori_found = username in ori_users
need_analyser_gather_account.append((asset, ga, d, ori_found))
# 这里顺序不能调整risk 外键关联了 gathered_account 主键 id所以在创建 risk 需要保证 gathered_account 已经创建完成
self.create_gathered_account.finish()
self.update_gathered_account.finish()
for analysis_data in need_analyser_gather_account:
risk_analyser.analyse_risk(*analysis_data)
self.update_gather_accounts_status(asset)
if not self.is_sync_account:
continue
gathered_accounts = GatheredAccount.objects.filter(asset=asset)
GatheredAccount.sync_accounts(gathered_accounts)
GatheredAccount.objects.filter(
asset=asset, username__in=ori_users, present=False
).update(
present=True
)
# 因为有 bulk create, bulk update, 所以这里需要 sleep 一下,等待数据同步
_update_risk.finish()
_create_risk.finish()
time.sleep(0.5)
def get_report_template(self):
return "accounts/gather_account_report.html"

View File

@ -1,22 +0,0 @@
- hosts: postgresql
gather_facts: no
vars:
ansible_python_interpreter: /opt/py3/bin/python
tasks:
- name: Get info
community.postgresql.postgresql_info:
login_user: "{{ jms_account.username }}"
login_password: "{{ jms_account.secret }}"
login_host: "{{ jms_asset.address }}"
login_port: "{{ jms_asset.port }}"
login_db: "{{ jms_asset.spec_info.db_name }}"
filter: "roles"
register: db_info
- name: Define info by set_fact
set_fact:
info: "{{ db_info.roles }}"
- debug:
var: info

Some files were not shown because too many files have changed in this diff Show More