28 Commits

Author SHA1 Message Date
0bb8913794 Add check for settings key 2019-12-09 17:10:38 +01:00
d515051244 Merge pull request #21 in KSC/webapp-tools from ~MALBERTS/webapp-tools-martijn:add_calendar_resolution to master
* commit 'a708768c7a1c248bbfd5fb8c7ee793ad113257f2':
  Add calendar resolution setting
2019-09-12 12:39:39 +02:00
a708768c7a Add calendar resolution setting 2019-09-12 12:00:34 +02:00
5048d33cf1 add hint that python3-pkg-resources is required for debian 10 2019-08-13 16:38:14 +02:00
87a5ab0b07 create empty prop if not exist 2019-07-22 16:00:07 +02:00
7a75569e5d Merge pull request #20 in KSC/webapp-tools from ~MALBERTS/webapp-tools-martijn:norecipient to master
* commit '7477f89a54af5b5fb10d1c46a9f81e88eb4d77df':
  Manage recipient: Display error when PR_EC_RECIPIENT_HISTORY_JSON_W does not exist
2019-07-18 13:56:21 +02:00
7477f89a54 Manage recipient: Display error when PR_EC_RECIPIENT_HISTORY_JSON_W does not exist 2019-07-18 13:08:13 +02:00
7b4845a877 Merge pull request #19 in KSC/webapp-tools from ~MALBERTS/webapp-tools-martijn:python3 to master
* commit '35b4bbeec1bde647cbf0da316ef0984f5a23bf00':
  Add brackets around prints
2019-07-18 12:40:29 +02:00
35b4bbeec1 Add brackets around prints 2019-07-18 12:36:41 +02:00
8d8e3f3e50 Merge pull request #17 in KSC/webapp-tools from ~MALBERTS/webapp-tools-martijn:addInterval to master
* commit 'e976f230da31301ab16531caf9997fa6216f7ff3':
  WebApp Admin: Add polling interval injection
2019-07-12 09:32:20 +02:00
e976f230da WebApp Admin: Add polling interval injection 2019-07-11 16:02:30 +02:00
2e97a42720 if value is true or false convert it to a boolean 2019-07-02 12:25:00 +02:00
145a4e4352 Merge pull request #14 in KSC/webapp-tools from readme_license to master
* commit 'debee2fd7bca15ae55ea726be1a646edc52c70f1':
  Add license and update readme
2019-06-27 07:50:05 +02:00
debee2fd7b Add license and update readme 2019-06-25 16:05:54 +02:00
a95dfca22f change order to get the right username 2019-06-04 16:09:58 +02:00
aff40b21b0 Merge pull request #13 in KSC/webapp-tools from remove_version_check_server to master
* commit '420c02a0fa90dc270b8d4ef16a61765d2fe5938e':
  Remove version check for server
2019-05-23 18:37:56 +02:00
420c02a0fa Remove version check for server 2019-05-23 18:13:47 +02:00
30f07c076f Check for version number and only complain about PYopenSSL een dotty_dict when it's needed
modified:   webapp_admin/webapp_admin.py
2019-05-02 13:53:05 +02:00
20896cbbc2 set type to string for language option 2019-05-02 13:12:14 +02:00
8381c1b700 Merge pull request #11 in KSC/webapp-tools from ftpsmbupdate to master
* commit 'e3338ba61e8cf99eca49b5e5759bd4e84c2c74c5':
  Configs for ftp and smb
2019-04-26 14:31:02 +02:00
e3338ba61e Configs for ftp and smb 2019-04-26 14:29:38 +02:00
76f300984d remove text 2019-04-17 14:51:13 +02:00
d055b4dd8e Merge pull request #10 in KSC/webapp-tools from ~MALBERTS/webapp-tools-martijn:master to master
* commit 'e49df89f29e83d93a0d9fe18eccbcda2ad6b8b94':
  Option to add user to safesenders
2019-04-15 20:57:11 +02:00
e49df89f29 Option to add user to safesenders 2019-04-15 17:07:55 +02:00
b835ddde91 load settings as json 2019-03-26 12:49:24 +01:00
c755fbdb99 change file optin 2019-03-26 12:43:31 +01:00
3026d1ce87 Merge pull request #9 in KSC/webapp-tools from ~MALBERTS/webapp-tools-martijn:state_settings to master
* commit '0634ec9ef49d733275a02bebbdda90abe85fadf0':
  Add option to remove state settings
2019-03-18 14:01:39 +01:00
0634ec9ef4 Add option to remove state settings 2019-03-18 13:01:02 +01:00
13 changed files with 221 additions and 36 deletions

12
LICENSE.txt Normal file
View 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
View 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
View 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/.

View File

@ -20,3 +20,7 @@ Use the username and password provided in the config file
- python-kopano
- python-mapi
# License
licensed under GNU Affero General Public License v3.

View File

@ -54,11 +54,19 @@ def files(options):
files = options.file.split(',')
for file in files:
configfile = ConfigObj(file)
if configfile['setting']['use_zarafa_credentials']:
username = configfile['setting']['default_user']
else:
# Check if the settings section key is present in the file
try:
value = configfile['setting']
except KeyError:
print('Setting does not exist in', file)
continue
if configfile['setting'].as_bool('use_zarafa_credentials'):
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 = {
'ftp': {"backend_features": {
"Streaming": "true", }},
@ -93,6 +101,7 @@ def files(options):
address = configfile['setting']['server_address']
ssl = configfile['setting']['server_ssl']
id = str(uuid.uuid4())
filesjson['accounts'][id] = {
"status": "ok",
"backend_config": {
@ -101,7 +110,7 @@ def files(options):
"server_address": encode(address).decode('utf-8'),
"server_ssl": ssl,
"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'),
"password": password.decode('utf-8'),
"server_port": encode(port).decode('utf-8')

13
files_admin/ftp.cfg Normal file
View 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

View File

@ -4,7 +4,7 @@ name = Samba share
type = SMB
workgroup = zarafa
server_path = files
server_address = 192.168.1.230
server_address = 10.10.11.9
server_ssl = false
use_zarafa_credentials = true
server_port = 80

View 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/.

View File

@ -31,4 +31,8 @@ Remove all recipients that have example.com in there display_name, smtp_address
python remove_recipients.py --user user --remove example.com
```
# License
licensed under GNU Affero General Public License v3.

View File

@ -2,8 +2,10 @@
#encoding: utf-8
import kopano
from kopano.errors import NotFoundError
from MAPI.Util import *
import json
import sys
def opt_args():
@ -24,14 +26,22 @@ def main():
options, args = opt_args()
if not options.user:
print 'Please use:\n %s --user <username>' % (sys.argv[0])
print('Please use:\n %s --user <username>' % (sys.argv[0]))
sys.exit(0)
user = kopano.Server(options).user(options.user)
try:
webapp = user.store.prop(0X6773001F).value
except NotFoundError:
webapp = dict(recipients=[])
webapp = json.loads(webapp)
if options.backup:
if len(webapp['recipients']) == 0:
print('Property PR_EC_RECIPIENT_HISTORY_JSON_W not found . User might have never used recipient history before.', file=sys.stderr)
sys.exit(1)
f = open('%s.json' % user.name, 'w')
f.write(json.dumps(webapp, sort_keys=True,
indent=4, separators=(',', ': ')))
@ -50,8 +60,8 @@ def main():
sys.exit(0)
if options.list:
print json.dumps(webapp, sort_keys=True,
indent=4, separators=(',', ': '))
print(json.dumps(webapp, sort_keys=True,
indent=4, separators=(',', ': ')))
sys.exit(0)
if options.remove:
@ -59,7 +69,7 @@ def main():
for rec in webapp['recipients']:
if options.remove in rec['display_name'] or options.remove in rec['smtp_address'] \
or options.remove in rec['email_address']:
print 'removing contact %s [%s]' % (rec['display_name'], rec['smtp_address'])
print('removing contact %s [%s]' % (rec['display_name'], rec['smtp_address']))
else:
newlist['recipients'].append(rec)

12
webapp_admin/LICENSE.txt Normal file
View 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/.

View File

@ -1,11 +1,14 @@
# WebApp Admin
>**This tool is under contruction. Use caution on a live server. Always make a backup of the user settings and test first before modifing**
>**Always make a backup of the user settings and test the new settings afterwards**
WebApp admin is a command-line interface to modify, inject and export WebApp settings.
# Example Usage
Overview of all options:
> python3 webapp_admin -h
Reset WebApp settings
> python3 webapp_admin -u john --reset
@ -22,3 +25,9 @@ If you want to make a change for all users pass the --all-users parameter. Examp
- python-mapi
- OpenSSL
- dotty_dict
For debian 10 python3-pkg-resources is required
# License
licensed under GNU Affero General Public License v3.

View File

@ -1,5 +1,6 @@
#!/usr/bin/env python3
# encoding: utf-8
from pkg_resources import parse_version
import sys
try:
import kopano
@ -16,8 +17,7 @@ import base64
try:
import OpenSSL.crypto
except ImportError:
print('pip3 install pyOpenSSL')
sys.exit(1)
pass
from datetime import datetime
from time import mktime
import getpass
@ -26,7 +26,7 @@ from optparse import OptionGroup
try:
from dotty_dict import dotty
except ImportError:
print('dotty_dict not found on your system. Run pip3 install dotty_dict')
pass
"""
@ -62,8 +62,8 @@ def opt_args(print_help=None):
group = OptionGroup(parser, "Categories", "")
group.add_option("--export-categories", dest="export_categories", action="store_true", help="Export Categories (name and color)")
group.add_option("--import-categories", dest="import_categories", action="store_true", help="Import Categories (name and color)")
parser.add_option_group(group)
# S/MIME option group
group = OptionGroup(parser, "S/MIME", "")
group.add_option("--export-smime", dest="export_smime", action="store_true", help="Export private S/MIME certificate")
@ -75,11 +75,15 @@ def opt_args(print_help=None):
# WebApp setting option group
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("--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("--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="add_sender", action="store", help="Add domain to safe sender list")
group.add_option("--polling-interval", dest="polling_interval", action="store", help="Change the polling interval (seconds)")
group.add_option("--calendar-resolution", dest="calendar_resolution", action="store", help="Change the calendar resolution (minutes)")
parser.add_option_group(group)
# Advanced option group
@ -269,6 +273,7 @@ def restore_signature(user, filename, replace=None, default=None):
write_settings(user, json.dumps(settings))
"""
Export categories from users store
@ -315,11 +320,11 @@ def import_categories(user, filename=None):
if not user.store.get_prop(PR_EC_WEBAPP_PERSISTENT_SETTINGS_JSON_W):
persistent_settings ={'settings': {'kopano': {'main': {'categories':data}}}}
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
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 +335,7 @@ Export S/MIME certificate from users store
:param public: Export public certificate part
"""
def export_smime(user, location=None, public=None):
if location:
backup_location = location
else:
@ -364,6 +370,9 @@ Import S/MIME certificate into users store
:param public: Import public certificate part
"""
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:
passwd = getpass.getpass()
elif not passwd:
@ -447,11 +456,21 @@ Inject webapp settings into the users store
:param user: The user
: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)
split_data = data.split('=')
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[split_data[0].rstrip()] = value
@ -469,14 +488,15 @@ def main():
opt_args(True)
options, args = opt_args()
# Always first!
# If the script should execute for all users
# The admin should pass the '--all-users' parameter
if not options.users and not options.all_users:
print('There are no users specified. Use "--all-users" to run for all users')
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
if options.backup:
backup(user, options.location)
@ -489,7 +509,7 @@ def main():
#Categories
if options.export_categories:
export_categories(user, options.change_locale)
export_categories(user, options.file)
if options.import_categories:
import_categories(user, options.file)
# S/MIME import/export
@ -534,7 +554,7 @@ def main():
sys.exit(1)
setting = 'settings.zarafa.v1.main.active_iconset = {}'.format(options.icons)
advanced_inject(user, setting)
print('icon set changed to {}'.format(options.icons))
print('Icon set changed to {}'.format(options.icons))
# Editor
if options.htmleditor:
@ -546,6 +566,47 @@ def main():
advanced_inject(user, setting)
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.add_sender:
settings = read_settings(user)
setting = 'settings.zarafa.v1.contexts.mail.safe_senders_list = {}'.format(options.add_sender)
advanced_inject(user, setting, 'list')
print('{}'.format(options.add_sender), 'Added to safe sender list for {}'.format(user.name))
# Polling interval
if options.polling_interval:
try:
value = int(options.polling_interval)
except ValueError:
print('Invalid number used. Please specify the value in seconds')
sys.exit(1)
settings = read_settings(user)
setting = 'settings.zarafa.v1.main.reminder.polling_interval = {}'.format(options.polling_interval)
advanced_inject(user, setting)
print('Polling interval changed to', '{}'.format(options.polling_interval), 'for {}'.format(user.name))
# Calendar resolution (zoom level)
if options.calendar_resolution:
try:
value = int(options.calendar_resolution)
except ValueError:
print('Invalid number used. Please specify the value in minutes')
sys.exit(1)
if value < 5 or value > 60:
print('Unsupported value used. Use a number between 5 and 60')
sys.exit(1)
settings = read_settings(user)
setting = 'settings.zarafa.v1.contexts.calendar.default_zoom_level = {}'.format(options.calendar_resolution)
advanced_inject(user, setting)
print('Calendar resolution changed to', '{}'.format(options.calendar_resolution), 'for {}'.format(user.name))
# Always at last!!!
if options.reset:
reset_settings(user)