Updating new actor configuration tool

This commit is contained in:
Adolfo Gómez García 2019-11-21 12:34:02 +01:00
parent 09000f8b00
commit 4df7c18ddc
7 changed files with 87 additions and 27 deletions

View File

@ -88,9 +88,11 @@ class UDSConfigDialog(QDialog):
auth: udsactor.types.AuthenticatorType auth: udsactor.types.AuthenticatorType
for auth in self.api.enumerateAuthenticators(): for auth in self.api.enumerateAuthenticators():
self.ui.authenticators.addItem(auth.auth, userData=auth) self.ui.authenticators.addItem(auth.auth, userData=auth)
# Last, add "admin" authenticator (for uds root user)
self.ui.authenticators.addItem('Administration', userData=udsactor.types.AuthenticatorType('admin', 'admin', 'admin', 'admin', 1, False))
def textChanged(self): def textChanged(self):
enableButtons = self.ui.host.text() != '' and self.ui.username.text() != '' and self.ui.password.text() != '' enableButtons = bool(self.ui.host.text() and self.ui.username.text() and self.ui.password.text() and self.ui.authenticators.currentText())
self.ui.registerButton.setEnabled(enableButtons) self.ui.registerButton.setEnabled(enableButtons)
def finish(self): def finish(self):
@ -100,6 +102,7 @@ class UDSConfigDialog(QDialog):
# Get network card. Will fail if no network card is available, but don't mind (not contempled) # Get network card. Will fail if no network card is available, but don't mind (not contempled)
data: udsactor.types.InterfaceInfo = next(udsactor.operations.getNetworkInfo()) data: udsactor.types.InterfaceInfo = next(udsactor.operations.getNetworkInfo())
try:
key = self.api.register( key = self.api.register(
self.ui.authenticators.currentData().auth, self.ui.authenticators.currentData().auth,
self.ui.username.text(), self.ui.username.text(),
@ -108,10 +111,15 @@ class UDSConfigDialog(QDialog):
data.mac or '', # MAC data.mac or '', # MAC
self.ui.preCommand.text(), self.ui.preCommand.text(),
self.ui.runonceCommand.text(), self.ui.runonceCommand.text(),
self.ui.postConfigCommand.text() self.ui.postConfigCommand.text(),
(self.ui.logLevelComboBox.currentIndex() + 1) * 10000 # Loglevel
) )
# Store parameters on register for later use, notify user of registration
print(key) # Inform the user
QMessageBox.information(self, 'UDS Registration', 'Registration with UDS completed.', QMessageBox.Ok)
except udsactor.rest.RESTError as e:
QMessageBox.critical(self, 'UDS Registration', 'UDS Registration error: {}'.format(e), QMessageBox.Ok)
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -579,6 +579,22 @@
</hint> </hint>
</hints> </hints>
</connection> </connection>
<connection>
<sender>authenticators</sender>
<signal>currentTextChanged(QString)</signal>
<receiver>UdsActorSetupDialog</receiver>
<slot>textChanged()</slot>
<hints>
<hint type="sourcelabel">
<x>343</x>
<y>137</y>
</hint>
<hint type="destinationlabel">
<x>294</x>
<y>153</y>
</hint>
</hints>
</connection>
</connections> </connections>
<slots> <slots>
<slot>textChanged()</slot> <slot>textChanged()</slot>

View File

@ -125,7 +125,7 @@ class REST:
pass pass
def register(self, auth: str, username: str, password: str, ip: str, mac: str, preCommand: str, runOnceCommand: str, postCommand: str) -> str: def register(self, auth: str, username: str, password: str, ip: str, mac: str, preCommand: str, runOnceCommand: str, postCommand: str, logLevel: int) -> str:
""" """
Raises an exception if could not register, or registers and returns the "authorization token" Raises an exception if could not register, or registers and returns the "authorization token"
""" """
@ -133,16 +133,24 @@ class REST:
'username': username, 'username': username,
'ip': ip, 'ip': ip,
'mac': mac, 'mac': mac,
'preCommand': preCommand, 'pre_command': preCommand,
'runOnceCommand': runOnceCommand, 'run_once_command': runOnceCommand,
'postCommand': postCommand 'post_command': postCommand,
'log_level': logLevel
} }
try: try:
# First, try to login # First, try to login
authInfo = {'auth': auth, 'username': username, 'password': password } authInfo = {'auth': auth, 'username': username, 'password': password }
headers = self.headers headers = self.headers
result = requests.post(self.url + 'auth/login', data=json.dumps(authInfo), headers=headers, verify=self.validateCert) result = requests.post(self.url + 'auth/login', data=json.dumps(authInfo), headers=headers, verify=self.validateCert)
if result.ok: if not result.ok or result.json()['result'] == 'error':
raise Exception() # Invalid credentials
except (requests.ConnectionError, requests.ConnectTimeout) as e:
raise RESTConnectionError(str(e))
except Exception as e:
raise RESTError('Invalid credentials')
try:
headers['X-Auth-Token'] = result.json()['token'] headers['X-Auth-Token'] = result.json()['token']
result = requests.post(self.url + 'actor/v2/register', data=json.dumps(data), headers=headers, verify=self.validateCert) result = requests.post(self.url + 'actor/v2/register', data=json.dumps(data), headers=headers, verify=self.validateCert)
if result.ok: if result.ok:

View File

@ -193,6 +193,7 @@ class Ui_UdsActorSetupDialog(object):
self.browsePostConfigButton.clicked.connect(UdsActorSetupDialog.browsePostConfig) self.browsePostConfigButton.clicked.connect(UdsActorSetupDialog.browsePostConfig)
self.browseRunOnceButton.clicked.connect(UdsActorSetupDialog.browseRunOnce) self.browseRunOnceButton.clicked.connect(UdsActorSetupDialog.browseRunOnce)
self.host.editingFinished.connect(UdsActorSetupDialog.updateAuthenticators) self.host.editingFinished.connect(UdsActorSetupDialog.updateAuthenticators)
self.authenticators.currentTextChanged['QString'].connect(UdsActorSetupDialog.textChanged)
QtCore.QMetaObject.connectSlotsByName(UdsActorSetupDialog) QtCore.QMetaObject.connectSlotsByName(UdsActorSetupDialog)
def retranslateUi(self, UdsActorSetupDialog): def retranslateUi(self, UdsActorSetupDialog):

View File

@ -30,12 +30,12 @@
""" """
@author: Adolfo Gómez, dkmaster at dkmon dot com @author: Adolfo Gómez, dkmaster at dkmon dot com
""" """
import secrets
import logging import logging
import typing import typing
from django.utils.translation import ugettext as _ from uds.models import getSqlDatetimeAsUnix, getSqlDatetime, ActorToken
from uds.models.util import getSqlDatetimeAsUnix
from uds.core import VERSION from uds.core import VERSION
from ..handlers import Handler from ..handlers import Handler
@ -72,8 +72,6 @@ class ActorV2Action(Handler):
def get(self): def get(self):
return actorResult('') return actorResult('')
class ActorV2Register(ActorV2Action): class ActorV2Register(ActorV2Action):
""" """
Registers an actor Registers an actor
@ -81,9 +79,34 @@ class ActorV2Register(ActorV2Action):
authenticated = True authenticated = True
name = 'register' name = 'register'
def post(self): def post(self) -> typing.MutableMapping[str, typing.Any]:
logger.debug('Args: %s, Params: %s', self._args, self._params) actorToken: ActorToken
return actorResult('ok') try:
# If already exists a token for this MAC, return it instead of creating a new one, and update the information...
actorToken = ActorToken.objects.get(mac=self._params['mac'])
# Update parameters
actorToken.ip_from = self._request.ip
actorToken.ip = self._params['ip']
actorToken.pre_command = self._params['pre_command']
actorToken.post_command = self._params['post_command']
actorToken.runonce_command = self._params['run_once_command']
actorToken.log_level = self._params['log_level']
actorToken.stamp = getSqlDatetime()
actorToken.save()
except Exception:
actorToken = ActorToken.objects.create(
username=self._params['username'],
ip_from=self._request.ip,
ip=self._params['ip'],
mac=self._params['mac'],
pre_command=self._params['pre_command'],
post_command=self._params['post_command'],
runonce_command=self._params['run_once_command'],
log_level=self._params['log_level'],
token=secrets.token_urlsafe(36),
stamp=getSqlDatetime()
)
return actorResult(actorToken.token)
class ActorV2Initiialize(ActorV2Action): class ActorV2Initiialize(ActorV2Action):
""" """

View File

@ -112,4 +112,7 @@ from .tag import Tag
# Utility # Utility
from .dbfile import DBFile from .dbfile import DBFile
# Actor tokens
from .actor_token import ActorToken
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@ -42,6 +42,7 @@ class LoginForm(forms.Form):
user = forms.CharField(label=_('Username'), max_length=64, widget=forms.TextInput()) user = forms.CharField(label=_('Username'), max_length=64, widget=forms.TextInput())
password = forms.CharField(label=_('Password'), widget=forms.PasswordInput(attrs={'title': _('Password')}), required=False) password = forms.CharField(label=_('Password'), widget=forms.PasswordInput(attrs={'title': _('Password')}), required=False)
authenticator = forms.ChoiceField(label=_('Authenticator'), choices=(), required=False) authenticator = forms.ChoiceField(label=_('Authenticator'), choices=(), required=False)
logouturl = forms.CharField(widget=forms.HiddenInput(), required=False)
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
# If an specified login is passed in, retrieve it & remove it from kwargs dict # If an specified login is passed in, retrieve it & remove it from kwargs dict