Comparar commits
	
		
			28 Commits
		
	
	
		
			use-python
			...
			malberts/f
		
	
	| Autor | SHA1 | Data | |
|---|---|---|---|
| 
						 | 
					0bb8913794 | ||
| 
						 | 
					d515051244 | ||
| 
						 | 
					a708768c7a | ||
| 
						 | 
					5048d33cf1 | ||
| 
						 | 
					87a5ab0b07 | ||
| 
						 | 
					7a75569e5d | ||
| 
						 | 
					7477f89a54 | ||
| 
						 | 
					7b4845a877 | ||
| 
						 | 
					35b4bbeec1 | ||
| 
						 | 
					8d8e3f3e50 | ||
| 
						 | 
					e976f230da | ||
| 
						 | 
					2e97a42720 | ||
| 
						 | 
					145a4e4352 | ||
| 
						 | 
					debee2fd7b | ||
| 
						 | 
					a95dfca22f | ||
| 
						 | 
					aff40b21b0 | ||
| 
						 | 
					420c02a0fa | ||
| 
						 | 
					30f07c076f | ||
| 
						 | 
					20896cbbc2 | ||
| 
						 | 
					8381c1b700 | ||
| 
						 | 
					e3338ba61e | ||
| 
						 | 
					76f300984d | ||
| 
						 | 
					d055b4dd8e | ||
| 
						 | 
					e49df89f29 | ||
| 
						 | 
					b835ddde91 | ||
| 
						 | 
					c755fbdb99 | ||
| 
						 | 
					3026d1ce87 | ||
| 
						 | 
					0634ec9ef4 | 
							
								
								
									
										12
									
								
								LICENSE.txt
									
									
									
									
									
										Arquivo normal
									
								
							
							
						
						
									
										12
									
								
								LICENSE.txt
									
									
									
									
									
										Arquivo normal
									
								
							@@ -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
									
									
									
									
									
										Arquivo normal
									
								
							
							
						
						
									
										27
									
								
								README.md
									
									
									
									
									
										Arquivo normal
									
								
							@@ -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
									
									
									
									
									
										Arquivo normal
									
								
							
							
						
						
									
										12
									
								
								files_admin/LICENSE.txt
									
									
									
									
									
										Arquivo normal
									
								
							@@ -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/.
 | 
				
			||||||
@@ -20,3 +20,7 @@ Use the username and password provided in the config file
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
- python-kopano
 | 
					- python-kopano
 | 
				
			||||||
- python-mapi
 | 
					- python-mapi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# License
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					licensed under GNU Affero General Public License v3.
 | 
				
			||||||
@@ -54,11 +54,19 @@ 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']:
 | 
					        
 | 
				
			||||||
            username = configfile['setting']['default_user']
 | 
					        # Check if the settings section key is present in the file
 | 
				
			||||||
        else:
 | 
					        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
 | 
					            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 +101,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 +110,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
									
									
									
									
									
										Arquivo normal
									
								
							
							
						
						
									
										13
									
								
								files_admin/ftp.cfg
									
									
									
									
									
										Arquivo normal
									
								
							@@ -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
									
									
									
									
									
										Arquivo normal
									
								
							
							
						
						
									
										12
									
								
								manage_recipients/LICENSE.txt
									
									
									
									
									
										Arquivo normal
									
								
							@@ -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/.
 | 
				
			||||||
@@ -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
 | 
					python remove_recipients.py --user user  --remove example.com
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# License
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					licensed under GNU Affero General Public License v3.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2,8 +2,10 @@
 | 
				
			|||||||
#encoding: utf-8
 | 
					#encoding: utf-8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import kopano
 | 
					import kopano
 | 
				
			||||||
 | 
					from kopano.errors import NotFoundError
 | 
				
			||||||
from MAPI.Util import *
 | 
					from MAPI.Util import *
 | 
				
			||||||
import json
 | 
					import json
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def opt_args():
 | 
					def opt_args():
 | 
				
			||||||
@@ -24,14 +26,22 @@ def main():
 | 
				
			|||||||
    options, args = opt_args()
 | 
					    options, args = opt_args()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if not options.user:
 | 
					    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)
 | 
					        sys.exit(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    user = kopano.Server(options).user(options.user)
 | 
					    user = kopano.Server(options).user(options.user)
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
        webapp = user.store.prop(0X6773001F).value
 | 
					        webapp = user.store.prop(0X6773001F).value
 | 
				
			||||||
 | 
					    except NotFoundError:
 | 
				
			||||||
 | 
					        webapp = dict(recipients=[])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    webapp = json.loads(webapp)
 | 
					    webapp = json.loads(webapp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if options.backup:
 | 
					    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 = open('%s.json' % user.name, 'w')
 | 
				
			||||||
        f.write(json.dumps(webapp, sort_keys=True,
 | 
					        f.write(json.dumps(webapp, sort_keys=True,
 | 
				
			||||||
                           indent=4, separators=(',', ': ')))
 | 
					                           indent=4, separators=(',', ': ')))
 | 
				
			||||||
@@ -50,8 +60,8 @@ def main():
 | 
				
			|||||||
        sys.exit(0)
 | 
					        sys.exit(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if options.list:
 | 
					    if options.list:
 | 
				
			||||||
        print json.dumps(webapp, sort_keys=True,
 | 
					        print(json.dumps(webapp, sort_keys=True,
 | 
				
			||||||
                         indent=4, separators=(',', ': '))
 | 
					                         indent=4, separators=(',', ': ')))
 | 
				
			||||||
        sys.exit(0)
 | 
					        sys.exit(0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if options.remove:
 | 
					    if options.remove:
 | 
				
			||||||
@@ -59,7 +69,7 @@ def main():
 | 
				
			|||||||
        for rec in webapp['recipients']:
 | 
					        for rec in webapp['recipients']:
 | 
				
			||||||
            if options.remove in rec['display_name'] or options.remove in rec['smtp_address'] \
 | 
					            if options.remove in rec['display_name'] or options.remove in rec['smtp_address'] \
 | 
				
			||||||
                    or options.remove in rec['email_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:
 | 
					            else:
 | 
				
			||||||
                newlist['recipients'].append(rec)
 | 
					                newlist['recipients'].append(rec)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								webapp_admin/LICENSE.txt
									
									
									
									
									
										Arquivo normal
									
								
							
							
						
						
									
										12
									
								
								webapp_admin/LICENSE.txt
									
									
									
									
									
										Arquivo normal
									
								
							@@ -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/.
 | 
				
			||||||
@@ -1,11 +1,14 @@
 | 
				
			|||||||
# WebApp Admin
 | 
					# 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.
 | 
					WebApp admin is a command-line interface to modify, inject and export WebApp settings.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Example Usage
 | 
					# Example Usage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Overview of all options:
 | 
				
			||||||
 | 
					> python3 webapp_admin -h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Reset WebApp settings
 | 
					Reset WebApp settings
 | 
				
			||||||
> python3 webapp_admin -u john --reset
 | 
					> 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
 | 
					- python-mapi
 | 
				
			||||||
- OpenSSL
 | 
					- OpenSSL
 | 
				
			||||||
- dotty_dict
 | 
					- dotty_dict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					For debian 10 python3-pkg-resources is required
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# 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,7 @@ 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
@@ -62,8 +62,8 @@ def opt_args(print_help=None):
 | 
				
			|||||||
    group = OptionGroup(parser, "Categories", "")
 | 
					    group = OptionGroup(parser, "Categories", "")
 | 
				
			||||||
    group.add_option("--export-categories", dest="export_categories", action="store_true", help="Export Categories (name and color)")
 | 
					    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)")
 | 
					    group.add_option("--import-categories", dest="import_categories", action="store_true", help="Import Categories (name and color)")
 | 
				
			||||||
 | 
					 | 
				
			||||||
    parser.add_option_group(group)
 | 
					    parser.add_option_group(group)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # S/MIME option group
 | 
					    # S/MIME option group
 | 
				
			||||||
    group = OptionGroup(parser, "S/MIME", "")
 | 
					    group = OptionGroup(parser, "S/MIME", "")
 | 
				
			||||||
    group.add_option("--export-smime", dest="export_smime", action="store_true", help="Export private S/MIME certificate")
 | 
					    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
 | 
					    # 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="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)
 | 
					    parser.add_option_group(group)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Advanced option group
 | 
					    # Advanced option group
 | 
				
			||||||
@@ -269,6 +273,7 @@ def restore_signature(user, filename, replace=None, default=None):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    write_settings(user, json.dumps(settings))
 | 
					    write_settings(user, json.dumps(settings))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
Export categories from users store
 | 
					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):
 | 
					    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 +335,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 +370,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 +456,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 +488,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 +509,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 +554,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 +566,47 @@ 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.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!!!
 | 
					        # Always at last!!!
 | 
				
			||||||
        if options.reset:
 | 
					        if options.reset:
 | 
				
			||||||
            reset_settings(user)
 | 
					            reset_settings(user)
 | 
				
			||||||
 
 | 
				
			|||||||
		Referência em uma Nova Issue
	
	Bloquear um usuário