0%

批量禁用Confluence用户

近期想清理一批Confluence中离职的用户,以便于能释放一些License出来,却发现官方似乎没有提供批量清理的功能。官方的REST API中也没有提供禁用用户的接口,只好学习下Selenium,自己写个脚本来清理了。

在Confluence中,如果要释放占用的license数量,有两种方法:

  • 禁用用户
  • 将用户所在的组全部移除

一般情况下,禁用用户就可以释放license数量了,但如果用户同时处于多个用户目录,比如用户在Confluence内部认证和外部LDAP中都存在,此时就只好将用户所在的组全部移除。

临时学习了下Selenium,写了段代码如下,用Confluence 7.11.0和Chrome 88环境下测试了下是可用的:

直接访问gist: https://gist.github.com/knktc/b7e558ba77973f04f4c580d6ecbe91ba

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env python3

"""
A simple script to Bulk disable Confluence users with Selenium
Tested with Confluence 7.11.0 and Chrome 88

@author:knktc
@contact:me@knktc.com
@create:2021-02-16 09:12
"""

import time
from selenium import webdriver
from urllib.parse import urljoin


# conf
CONF = {
'base_url': 'https://YOUR_CONFLUENCE_BASE_URL',
'c_username': 'YOUR_ADMIN_USERNAME',
'c_password': 'YOUR_ADMIN_PASSWORD',
}
USERS = [
'USERNAME_1',
'USERNAME_2',
'USERNAME_3',
]


class BulkUserOperator:
def __init__(self, conf: dict):
self.browser = webdriver.Chrome()
self.conf = conf
self.base_url = conf['base_url']

def __exit__(self, exc_type, exc_val, exc_tb):
self.browser.close()

def login(self):
""" login with username and password """
browser = self.browser
username = self.conf['c_username']
password = self.conf['c_password']

# login for the first time
browser.get(urljoin(self.base_url, '/admin/viewgeneralconfig.action'))
browser.find_element_by_id('os_username').send_keys(username)
browser.find_element_by_id('os_password').send_keys(password)
browser.find_element_by_id('loginButton').click()
time.sleep(2)

# ensure admin login
browser.find_element_by_id('password').send_keys(password)
browser.find_element_by_id('authenticateButton').click()
time.sleep(2)

def disable_user(self, username: str):
""" disable user by username """
browser = self.browser

# go to disable user page
url = urljoin(self.base_url, f'/admin/users/deactivateuser.action?username={username}')
browser.get(url)

try:
elem = browser.find_element_by_id('confirm')
elem.click()
except:
time.sleep(2)
return False, 'no such user'

time.sleep(2)
return True, None

def remove_groups(self, username: str):
""" remove all groups """
browser = self.browser

# go to group edit page
url = urljoin(self.base_url, f'/admin/users/editusergroups-start.action?username={username}')
browser.get(url)

try:
browser.find_element_by_id('editusergroups-selectnone').click()
time.sleep(1)
browser.find_element_by_id('save-btn1').click()
except:
time.sleep(2)
return False, 'no such user'

time.sleep(2)
return True, None


def main():
"""
main process

"""
operator = BulkUserOperator(CONF)
operator.login()

for user in USERS:
status, msg = operator.disable_user(user)
if status:
status, msg = operator.remove_groups(user)
if status:
print(f'user [{user}] has been disabled and all groups removed')
else:
print(f'user [{user}] has been disabled but remove groups failed')
else:
print(f'user: [{user}] not exists')
continue


if __name__ == '__main__':
main()
如果我的文字帮到了您,那么可不可以请我喝罐可乐?