Compare commits
17 Commits
use-python
...
webapp-adm
Author | SHA1 | Date | |
---|---|---|---|
2e97a42720 | |||
145a4e4352 | |||
debee2fd7b | |||
a95dfca22f | |||
aff40b21b0 | |||
420c02a0fa | |||
30f07c076f | |||
20896cbbc2 | |||
8381c1b700 | |||
e3338ba61e | |||
76f300984d | |||
d055b4dd8e | |||
e49df89f29 | |||
b835ddde91 | |||
c755fbdb99 | |||
3026d1ce87 | |||
0634ec9ef4 |
12
LICENSE.txt
Normal file
12
LICENSE.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
Copyright (C) 2019 Kopano and its licensors
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify it under the terms of the
|
||||||
|
GNU Affero General Public License as published by the Free Software Foundation, either version
|
||||||
|
3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||||
|
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License along with this program.
|
||||||
|
If not, see http://www.gnu.org/licenses/.
|
27
README.md
Normal file
27
README.md
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# WebApp tools
|
||||||
|
|
||||||
|
WebApp tools repository can be found [here](https://stash.kopano.io/projects/KSC/repos/webapp-tools/) and consist of various sub-projects:
|
||||||
|
|
||||||
|
## WebApp_Admin
|
||||||
|
|
||||||
|
A CLI tool that can be used to manage WebApp user settings, signatures, S/MIME certificates and more.
|
||||||
|
More info [here](https://stash.kopano.io/projects/KSC/repos/webapp-tools/browse/webapp_admin/README.md).
|
||||||
|
|
||||||
|
## Files_Admin
|
||||||
|
|
||||||
|
A CLI tool to inject files accounts into a user settings. More info [here](https://stash.kopano.io/projects/KSC/repos/webapp-tools/browse/files_admin/README.md).
|
||||||
|
|
||||||
|
## Manage_recipients
|
||||||
|
|
||||||
|
A simple script to manage the recipient history list for a user. More info [here](https://stash.kopano.io/projects/KSC/repos/webapp-tools/browse/manage_recipients/readme.md).
|
||||||
|
|
||||||
|
# How to contribute
|
||||||
|
|
||||||
|
1) Clone the repository from `https://stash.kopano.io/` or `https://github.com/Kopano-mirror/webapp_tools`.
|
||||||
|
2) Commit and sign your work (git commit -s).
|
||||||
|
3) Upload commits to a git store of your choosing, or export the series as a patchset using git format-patch.
|
||||||
|
4) Send the patch(es) or git link to `contributing @ kopano .io` and we will consider the submission.
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
All software found in this repostory and sub-projects are licensed under GNU Affero General Public License v3 unless stated otherwise. A copy of this license can be found in the main directory of this project and in every sub-project.
|
12
files_admin/LICENSE.txt
Normal file
12
files_admin/LICENSE.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
Copyright (C) 2019 Kopano and its licensors
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify it under the terms of the
|
||||||
|
GNU Affero General Public License as published by the Free Software Foundation, either version
|
||||||
|
3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||||
|
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License along with this program.
|
||||||
|
If not, see http://www.gnu.org/licenses/.
|
@ -19,4 +19,8 @@ Use the username and password provided in the config file
|
|||||||
# Dependencies
|
# Dependencies
|
||||||
|
|
||||||
- python-kopano
|
- python-kopano
|
||||||
- python-mapi
|
- python-mapi
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
licensed under GNU Affero General Public License v3.
|
@ -54,11 +54,11 @@ def files(options):
|
|||||||
files = options.file.split(',')
|
files = options.file.split(',')
|
||||||
for file in files:
|
for file in files:
|
||||||
configfile = ConfigObj(file)
|
configfile = ConfigObj(file)
|
||||||
if configfile['setting']['use_zarafa_credentials']:
|
if configfile['setting'].as_bool('use_zarafa_credentials'):
|
||||||
username = configfile['setting']['default_user']
|
|
||||||
else:
|
|
||||||
username = options.user
|
username = options.user
|
||||||
password = encode(configfile['setting']['default_password'])
|
else:
|
||||||
|
username = configfile['setting'].get('default_user', 'does not matter')
|
||||||
|
password = encode(configfile['setting'].get('default_password', 'does not matter'))
|
||||||
backendoptions = {
|
backendoptions = {
|
||||||
'ftp': {"backend_features": {
|
'ftp': {"backend_features": {
|
||||||
"Streaming": "true", }},
|
"Streaming": "true", }},
|
||||||
@ -93,6 +93,7 @@ def files(options):
|
|||||||
address = configfile['setting']['server_address']
|
address = configfile['setting']['server_address']
|
||||||
ssl = configfile['setting']['server_ssl']
|
ssl = configfile['setting']['server_ssl']
|
||||||
id = str(uuid.uuid4())
|
id = str(uuid.uuid4())
|
||||||
|
|
||||||
filesjson['accounts'][id] = {
|
filesjson['accounts'][id] = {
|
||||||
"status": "ok",
|
"status": "ok",
|
||||||
"backend_config": {
|
"backend_config": {
|
||||||
@ -101,7 +102,7 @@ def files(options):
|
|||||||
"server_address": encode(address).decode('utf-8'),
|
"server_address": encode(address).decode('utf-8'),
|
||||||
"server_ssl": ssl,
|
"server_ssl": ssl,
|
||||||
"current_account_id": encode('d4cacda458a2a26c301f2b7d75ada530').decode('utf-8'),
|
"current_account_id": encode('d4cacda458a2a26c301f2b7d75ada530').decode('utf-8'),
|
||||||
"use_zarafa_credentials": configfile['setting']['use_zarafa_credentials'],
|
"use_zarafa_credentials": configfile['setting'].as_bool('use_zarafa_credentials'),
|
||||||
"user": encode(username).decode('utf-8'),
|
"user": encode(username).decode('utf-8'),
|
||||||
"password": password.decode('utf-8'),
|
"password": password.decode('utf-8'),
|
||||||
"server_port": encode(port).decode('utf-8')
|
"server_port": encode(port).decode('utf-8')
|
||||||
|
13
files_admin/ftp.cfg
Normal file
13
files_admin/ftp.cfg
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
[setting]
|
||||||
|
|
||||||
|
name = FTP server
|
||||||
|
type = FTP
|
||||||
|
workgroup =
|
||||||
|
server_path = /srv/ftp
|
||||||
|
server_address = 10.10.11.9
|
||||||
|
server_ssl = false
|
||||||
|
use_zarafa_credentials = false
|
||||||
|
server_port = 21
|
||||||
|
default_user = ftpuser
|
||||||
|
default_password = ftpuser
|
||||||
|
server_pasv = false
|
@ -4,7 +4,7 @@ name = Samba share
|
|||||||
type = SMB
|
type = SMB
|
||||||
workgroup = zarafa
|
workgroup = zarafa
|
||||||
server_path = files
|
server_path = files
|
||||||
server_address = 192.168.1.230
|
server_address = 10.10.11.9
|
||||||
server_ssl = false
|
server_ssl = false
|
||||||
use_zarafa_credentials = true
|
use_zarafa_credentials = true
|
||||||
server_port = 80
|
server_port = 80
|
||||||
|
12
manage_recipients/LICENSE.txt
Normal file
12
manage_recipients/LICENSE.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
Copyright (C) 2019 Kopano and its licensors
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify it under the terms of the
|
||||||
|
GNU Affero General Public License as published by the Free Software Foundation, either version
|
||||||
|
3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||||
|
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License along with this program.
|
||||||
|
If not, see http://www.gnu.org/licenses/.
|
@ -11,24 +11,28 @@ Manage recipients in webapp
|
|||||||
python remove_recipients.py --user <user> --list
|
python remove_recipients.py --user <user> --list
|
||||||
```
|
```
|
||||||
###### Remove recipient
|
###### Remove recipient
|
||||||
Remove options is searching in display_name, smtp_address or email_address.
|
Remove options is searching in display_name, smtp_address or email_address.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
python remove_recipients.py --user <user> --remove <recipient name>
|
python remove_recipients.py --user <user> --remove <recipient name>
|
||||||
```
|
```
|
||||||
|
|
||||||
###### Clear history
|
###### Clear history
|
||||||
|
|
||||||
```python
|
```python
|
||||||
python remove_recipients.py --user <user> --remove-all
|
python remove_recipients.py --user <user> --remove-all
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Example
|
#### Example
|
||||||
|
|
||||||
Remove all recipients that have example.com in there display_name, smtp_address or email_address
|
Remove all recipients that have example.com in there display_name, smtp_address or email_address
|
||||||
|
|
||||||
```python
|
```python
|
||||||
python remove_recipients.py --user user --remove example.com
|
python remove_recipients.py --user user --remove example.com
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
licensed under GNU Affero General Public License v3.
|
||||||
|
|
||||||
|
|
12
webapp_admin/LICENSE.txt
Normal file
12
webapp_admin/LICENSE.txt
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
Copyright (C) 2019 Kopano and its licensors
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify it under the terms of the
|
||||||
|
GNU Affero General Public License as published by the Free Software Foundation, either version
|
||||||
|
3 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
||||||
|
even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU Affero General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Affero General Public License along with this program.
|
||||||
|
If not, see http://www.gnu.org/licenses/.
|
@ -22,3 +22,7 @@ If you want to make a change for all users pass the --all-users parameter. Examp
|
|||||||
- python-mapi
|
- python-mapi
|
||||||
- OpenSSL
|
- OpenSSL
|
||||||
- dotty_dict
|
- dotty_dict
|
||||||
|
|
||||||
|
# License
|
||||||
|
|
||||||
|
licensed under GNU Affero General Public License v3.
|
@ -1,5 +1,6 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
from pkg_resources import parse_version
|
||||||
import sys
|
import sys
|
||||||
try:
|
try:
|
||||||
import kopano
|
import kopano
|
||||||
@ -16,8 +17,7 @@ import base64
|
|||||||
try:
|
try:
|
||||||
import OpenSSL.crypto
|
import OpenSSL.crypto
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print('pip3 install pyOpenSSL')
|
pass
|
||||||
sys.exit(1)
|
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from time import mktime
|
from time import mktime
|
||||||
import getpass
|
import getpass
|
||||||
@ -26,7 +26,8 @@ from optparse import OptionGroup
|
|||||||
try:
|
try:
|
||||||
from dotty_dict import dotty
|
from dotty_dict import dotty
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print('dotty_dict not found on your system. Run pip3 install dotty_dict')
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -75,11 +76,13 @@ def opt_args(print_help=None):
|
|||||||
|
|
||||||
# WebApp setting option group
|
# WebApp setting option group
|
||||||
group = OptionGroup(parser, "webapp-settings", "")
|
group = OptionGroup(parser, "webapp-settings", "")
|
||||||
group.add_option("--language", dest="language", action="store", help="Set new language (e.g. en_GB or nl_NL)")
|
group.add_option("--language", dest="language", action="store", type="string", help="Set new language (e.g. en_GB or nl_NL)")
|
||||||
group.add_option("--theme", dest="theme", action="store", help="Change theme (e.g. dark)")
|
group.add_option("--theme", dest="theme", action="store", help="Change theme (e.g. dark)")
|
||||||
group.add_option("--free-busy", dest="freebusy", action="store", help="Change free/busy time span in months")
|
group.add_option("--free-busy", dest="freebusy", action="store", help="Change free/busy time span in months")
|
||||||
group.add_option("--icons", dest="icons", action="store", help="Change icons (e.g. breeze)")
|
group.add_option("--icons", dest="icons", action="store", help="Change icons (e.g. breeze)")
|
||||||
group.add_option("--htmleditor", dest="htmleditor", action="store", help="Change the HTML editor (e.g. full_tinymce)")
|
group.add_option("--htmleditor", dest="htmleditor", action="store", help="Change the HTML editor (e.g. full_tinymce)")
|
||||||
|
group.add_option("--remove-state", dest="remove_state", action="store_true", help="Remove all the state settings")
|
||||||
|
group.add_option("--add-safesender", dest="addsender", action="store", help="Add domain to safe sender list")
|
||||||
parser.add_option_group(group)
|
parser.add_option_group(group)
|
||||||
|
|
||||||
# Advanced option group
|
# Advanced option group
|
||||||
@ -315,11 +318,11 @@ def import_categories(user, filename=None):
|
|||||||
if not user.store.get_prop(PR_EC_WEBAPP_PERSISTENT_SETTINGS_JSON_W):
|
if not user.store.get_prop(PR_EC_WEBAPP_PERSISTENT_SETTINGS_JSON_W):
|
||||||
persistent_settings ={'settings': {'kopano': {'main': {'categories':data}}}}
|
persistent_settings ={'settings': {'kopano': {'main': {'categories':data}}}}
|
||||||
else:
|
else:
|
||||||
persistent_settings = user.store.get_prop(PR_EC_WEBAPP_PERSISTENT_SETTINGS_JSON_W)
|
persistent_settings = json.loads(user.store.get_prop(PR_EC_WEBAPP_PERSISTENT_SETTINGS_JSON_W).value)
|
||||||
persistent_settings['settings']['kopano']['main']['categories'] = data
|
persistent_settings['settings']['kopano']['main']['categories'] = data
|
||||||
|
|
||||||
print('Restoring categories for user {}'.format(user.name))
|
print('Restoring categories for user {}'.format(user.name))
|
||||||
user.store.create_prop(PR_EC_WEBAPP_PERSISTENT_SETTINGS_JSON_W, json.dumps(persistent_settings).decode('utf-8'))
|
user.store.create_prop(PR_EC_WEBAPP_PERSISTENT_SETTINGS_JSON_W, json.dumps(persistent_settings))
|
||||||
|
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -330,6 +333,7 @@ Export S/MIME certificate from users store
|
|||||||
:param public: Export public certificate part
|
:param public: Export public certificate part
|
||||||
"""
|
"""
|
||||||
def export_smime(user, location=None, public=None):
|
def export_smime(user, location=None, public=None):
|
||||||
|
|
||||||
if location:
|
if location:
|
||||||
backup_location = location
|
backup_location = location
|
||||||
else:
|
else:
|
||||||
@ -364,6 +368,9 @@ Import S/MIME certificate into users store
|
|||||||
:param public: Import public certificate part
|
:param public: Import public certificate part
|
||||||
"""
|
"""
|
||||||
def import_smime(user, cert_file, passwd, ask_password=None, public=None):
|
def import_smime(user, cert_file, passwd, ask_password=None, public=None):
|
||||||
|
if not sys.modules.get('OpenSSL'):
|
||||||
|
print('PyOpenSSl not installed \npip3 install pyOpenSSL')
|
||||||
|
sys.exit(1)
|
||||||
if ask_password:
|
if ask_password:
|
||||||
passwd = getpass.getpass()
|
passwd = getpass.getpass()
|
||||||
elif not passwd:
|
elif not passwd:
|
||||||
@ -447,11 +454,21 @@ Inject webapp settings into the users store
|
|||||||
:param user: The user
|
:param user: The user
|
||||||
:param data: The webapp setting
|
:param data: The webapp setting
|
||||||
"""
|
"""
|
||||||
def advanced_inject(user, data):
|
def advanced_inject(user, data, value_type='string'):
|
||||||
|
if not sys.modules.get('dotty_dict'):
|
||||||
|
print('dotty_dict not found on your system. \nRun pip3 install dotty_dict')
|
||||||
|
sys.exit(1)
|
||||||
settings = read_settings(user)
|
settings = read_settings(user)
|
||||||
split_data = data.split('=')
|
split_data = data.split('=')
|
||||||
|
|
||||||
value = split_data[1].lstrip().rstrip()
|
value = split_data[1].lstrip().rstrip()
|
||||||
|
if value.lower() == 'true':
|
||||||
|
value = True
|
||||||
|
elif value.lower() == 'false':
|
||||||
|
value = False
|
||||||
|
if value_type == 'list':
|
||||||
|
value = value.split(',')
|
||||||
|
|
||||||
dot = dotty()
|
dot = dotty()
|
||||||
dot[split_data[0].rstrip()] = value
|
dot[split_data[0].rstrip()] = value
|
||||||
|
|
||||||
@ -469,14 +486,15 @@ def main():
|
|||||||
opt_args(True)
|
opt_args(True)
|
||||||
options, args = opt_args()
|
options, args = opt_args()
|
||||||
|
|
||||||
# Always first!
|
|
||||||
# If the script should execute for all users
|
# If the script should execute for all users
|
||||||
# The admin should pass the '--all-users' parameter
|
# The admin should pass the '--all-users' parameter
|
||||||
if not options.users and not options.all_users:
|
if not options.users and not options.all_users:
|
||||||
print('There are no users specified. Use "--all-users" to run for all users')
|
print('There are no users specified. Use "--all-users" to run for all users')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
for user in kopano.Server(options).users(options.users):
|
server = kopano.Server(options)
|
||||||
|
|
||||||
|
for user in server.users(options.users):
|
||||||
# Backup and restore
|
# Backup and restore
|
||||||
if options.backup:
|
if options.backup:
|
||||||
backup(user, options.location)
|
backup(user, options.location)
|
||||||
@ -489,7 +507,7 @@ def main():
|
|||||||
|
|
||||||
#Categories
|
#Categories
|
||||||
if options.export_categories:
|
if options.export_categories:
|
||||||
export_categories(user, options.change_locale)
|
export_categories(user, options.file)
|
||||||
if options.import_categories:
|
if options.import_categories:
|
||||||
import_categories(user, options.file)
|
import_categories(user, options.file)
|
||||||
# S/MIME import/export
|
# S/MIME import/export
|
||||||
@ -534,7 +552,7 @@ def main():
|
|||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
setting = 'settings.zarafa.v1.main.active_iconset = {}'.format(options.icons)
|
setting = 'settings.zarafa.v1.main.active_iconset = {}'.format(options.icons)
|
||||||
advanced_inject(user, setting)
|
advanced_inject(user, setting)
|
||||||
print('icon set changed to {}'.format(options.icons))
|
print('Icon set changed to {}'.format(options.icons))
|
||||||
|
|
||||||
# Editor
|
# Editor
|
||||||
if options.htmleditor:
|
if options.htmleditor:
|
||||||
@ -546,6 +564,20 @@ def main():
|
|||||||
advanced_inject(user, setting)
|
advanced_inject(user, setting)
|
||||||
print('Editor changed to {}'.format(options.htmleditor))
|
print('Editor changed to {}'.format(options.htmleditor))
|
||||||
|
|
||||||
|
# State settings
|
||||||
|
if options.remove_state:
|
||||||
|
settings = read_settings(user)
|
||||||
|
settings['settings']['zarafa']['v1']['state'] = {}
|
||||||
|
write_settings(user, json.dumps(settings))
|
||||||
|
print('Removed state settings for {}'.format(user.name))
|
||||||
|
|
||||||
|
# Add sender to safe sender list
|
||||||
|
if options.addsender:
|
||||||
|
settings = read_settings(user)
|
||||||
|
setting = 'settings.zarafa.v1.contexts.mail.safe_senders_list = {}'.format(options.addsender)
|
||||||
|
advanced_inject(user, setting, 'list')
|
||||||
|
print('{}'.format(options.addsender), 'Added to safe sender list')
|
||||||
|
|
||||||
# Always at last!!!
|
# Always at last!!!
|
||||||
if options.reset:
|
if options.reset:
|
||||||
reset_settings(user)
|
reset_settings(user)
|
||||||
|
Reference in New Issue
Block a user