Change username for server and web server authentication (issue #693)

pull/805/head
nicolargo 2016-03-04 10:57:15 +01:00
parent 5497ae125f
commit 40d05a7a71
4 changed files with 40 additions and 18 deletions

1
NEWS
View File

@ -11,6 +11,7 @@ Enhancements and new features:
* New folders' monitoring plugins (issue #721)
* Use wildcard (regexp) to the hide configuration option for network, diskio and fs sections (issue #799 )
* Command line arguments are now take into account in the WebUI (#789 from @notFloran)
* Change username for server and web server authentication (issue #693)
* Add an option to disable top menu (issue #766)
* Add IOps in the DiskIO plugin (issue #763)
* Add hide configuration key for FS Plugin (issue #736)

View File

@ -114,7 +114,7 @@ class GlancesClient(object):
# Other errors
msg = "Connection to server failed"
if err.errcode == 401:
msg += " (Bad password)"
msg += " (Bad username/password)"
else:
msg += " ({0} {1})".format(err.errcode, err.errmsg)
self.log_and_exit(msg)

View File

@ -24,6 +24,7 @@ import os
import sys
import tempfile
from glances.compat import input
from glances.config import Config
from glances.globals import appname, LINUX, WINDOWS, psutil_version, version
from glances.logger import logger
@ -174,6 +175,8 @@ Start the client browser (browser mode):\n\
help='define the client/server TCP port [default: {0}]'.format(self.server_port))
parser.add_argument('-B', '--bind', default='0.0.0.0', dest='bind_address',
help='bind server to the given IPv4/IPv6 address or hostname')
parser.add_argument('--username', action='store_true', default=False, dest='username_prompt',
help='define a client/server username')
parser.add_argument('--password', action='store_true', default=False, dest='password_prompt',
help='define a client/server password')
parser.add_argument('--snmp-community', default='public', dest='snmp_community',
@ -252,21 +255,37 @@ Start the client browser (browser mode):\n\
args.process_short_name = True
# Server or client login/password
if args.username_prompt:
# Every username needs a password
args.password_prompt = True
# Prompt username
if args.server:
args.username = self.__get_username(description='Define the Glances server username: ')
elif args.webserver:
args.username = self.__get_username(description='Define the Glances webserver username: ')
elif args.client:
args.username = self.__get_username(description='Enter the Glances server username: ')
else:
# Default user name is 'glances'
args.username = self.username
if args.password_prompt:
# Interactive or file password
if args.server:
args.password = self.__get_password(
description='Define the password for the Glances server',
confirm=True)
description='Define the Glances server password ({} username): '.format(args.username),
confirm=True,
username=args.username)
elif args.webserver:
args.password = self.__get_password(
description='Define the password for the Glances web server\nUser name: glances',
confirm=True)
description='Define the Glances webserver password ({} username): '.format(args.username),
confirm=True,
username=args.username)
elif args.client:
args.password = self.__get_password(
description='Enter the Glances server password',
clear=True)
description='Enter the Glances server password({} username): '.format(args.username),
clear=True,
username=args.username)
else:
# Default is no password
args.password = self.password
@ -324,14 +343,19 @@ Start the client browser (browser mode):\n\
return args
def __get_password(self, description='', confirm=False, clear=False):
def __get_username(self, description=''):
"""Read a username from the command line.
"""
return input(description)
def __get_password(self, description='', confirm=False, clear=False, username='glances'):
"""Read a password from the command line.
- if confirm = True, with confirmation
- if clear = True, plain (clear password)
"""
from glances.password import GlancesPassword
password = GlancesPassword()
password = GlancesPassword(username=username)
return password.get_password(description, confirm, clear)
def is_standalone(self):

View File

@ -35,9 +35,10 @@ class GlancesPassword(object):
"""This class contains all the methods relating to password."""
def __init__(self):
def __init__(self, username='glances'):
self.username = username
self.password_path = self.get_password_path()
self.password_filename = 'glances.pwd'
self.password_filename = self.username + '.pwd'
self.password_filepath = os.path.join(self.password_path, self.password_filename)
def get_password_path(self):
@ -102,13 +103,9 @@ class GlancesPassword(object):
logger.info("Read password from file {0}".format(self.password_filepath))
password = self.load_password()
else:
# Else enter the password from the command line
if description != '':
print(description)
# password_sha256 is the plain SHA-256 password
# password_hashed is the salt + SHA-256 password
password_sha256 = self.sha256_hash(getpass.getpass('Password: '))
password_sha256 = self.sha256_hash(getpass.getpass(description))
password_hashed = self.hash_password(password_sha256)
if confirm:
# password_confirm is the clear password (only used to compare)
@ -144,7 +141,7 @@ class GlancesPassword(object):
return
# Create/overwrite the password file
with open(self.password_filepath, 'w') as file_pwd:
with open(self.password_filepath, 'wb') as file_pwd:
file_pwd.write(hashed_password)
def load_password(self):