# Authors: # Petr Vobornik # # Copyright (C) 2014 Red Hat # see file 'COPYING' for use and warranty information # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU 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 General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . """ OTP Token Tests """ from ipatests.test_webui.ui_driver import UI_driver from ipatests.test_webui.ui_driver import screenshot import ipatests.test_webui.data_user as user from ipatests.util import get_api from ipalib.rpc import jsonclient from ipalib import api from ipapython import ipautil import json from ipapython.ipautil import run from ipapython import certdb from ipalib import x509, certstore from ipaplatform.paths import paths from urllib2 import urlparse ENTITY = 'otptoken' def add(driver, entity, args=None, options=None): return driver.rpc(entity + '_add', args, options) def reset_pw(driver, user, password, current_password=None, otp=None): options = { 'password': password } if current_password is not None: options['current_password'] = current_password if otp is not None: options['otp'] = otp return driver.rpc('user_passwd', [user], options) # TODO: find a way to get UUID after add class test_otptoken(UI_driver): def check_visible_fields(self, user=True, totp=True): ''' Check if admin interface contains all fields and self-service only type and description. ''' admin = not user self.assert_visible("[name='description']") self.assert_visible("[name='ipatokenuniqueid']", negative=user, present=admin) self.assert_visible("[name='ipatokenowner']", negative=user, present=admin) self.assert_visible("[name='ipatokennotbefore']", negative=user, present=admin) self.assert_visible("[name='ipatokennotafter']", negative=user, present=admin) self.assert_visible("[name='ipatokenvendor']", negative=user, present=admin) self.assert_visible("[name='ipatokenmodel']", negative=user, present=admin) self.assert_visible("[name='ipatokenserial']", negative=user, present=admin) self.assert_visible("[name='ipatokenotpkey']", negative=user, present=admin) self.assert_visible("[name='ipatokenotpalgorithm']", negative=user, present=admin) self.assert_visible("[name='ipatokenotpdigits']", negative=user, present=admin) totp = totp and admin # visible only in admin interface self.assert_visible("[name='ipatokentotptimestep']", negative=(not totp), present=(totp)) def token_post_add(self): ''' Check functionality of QR dialog and retrieve configuration url which also contains a token name. ''' qr_image_cont = "a[name='qr'] div[name='qr']" uri_cont = "div[name='uri-control']" self.assert_visible(qr_image_cont) self.assert_visible(uri_cont, negative=True) self.click_on_link('Show configuration uri') self.assert_visible(uri_cont) self.assert_visible(qr_image_cont, negative=True) self.config_uri = self.get_text(uri_cont) self.click_on_link('Show QR code') self.assert_visible(qr_image_cont) self.assert_visible(uri_cont, negative=True) self.dialog_button_click('ok') @screenshot def test_crud_admin(self): """ Basic CRUD: OTPToken - admin """ self.init_app() pkey = 'testkey' self.basic_crud(ENTITY, { 'pkey': pkey, 'add': [ ('callback', lambda: self.check_visible_fields(False, True), None), ('textbox', 'ipatokenuniqueid', pkey), ('textbox', 'description', 'testtoken1'), ('callback', lambda: self.check_visible_fields(False, False), None), ], 'mod': [ ('textbox', 'ipatokenvendor', 'ipa tests'), ], }, post_add_action=lambda : self.token_post_add()) @screenshot def test_crud_selfservice(self): """ Basic CRUD: OTPToken - self-service """ self.init_app() uid = 'tuser1' pw = 'Secret123' self.rpc(user.ENTITY + '_del', [uid], { 'continue': True }) add(self, user.ENTITY, [uid], { 'givenname': 'test', 'sn': 'user1', 'userpassword': pw }) #re-login as new user self.logout() self.init_app(uid, pw) self.navigate_to_entity(ENTITY) self.assert_facet(ENTITY, "search") self.wait_for_request() self.add_record( ENTITY, { 'pkey': 'unknown', 'add': [ ('callback', lambda: self.check_visible_fields(True, True), None), ('radio', 'type', 'hotp'), ('textbox', 'description', 'testtoken2'), ('callback', lambda: self.check_visible_fields(True, False), None), ], }, pre_delete=False, post_add_action=lambda : self.token_post_add() ) print self.config_uri self.rpc(user.ENTITY + '_del', [uid], { 'continue': True }) def _prepare_nss_dir(self, ipa_server): """ Create temporary NSS Database with IPA server CA cert """ # create new NSSDatabase tmp_db = certdb.NSSDatabase() pwd_file = ipautil.write_tmp_file(ipautil.ipa_generate_password()) tmp_db.create_db(pwd_file.name) # download and add cert url = urlparse.urlunparse(('http', ipautil.format_netloc(ipa_server), '/ipa/config/ca.crt', '', '', '')) stdout, stderr, rc = run([paths.BIN_WGET, "-O", "-", url]) certs = x509.load_certificate_list(stdout, tmp_db.secdir) ca_certs = [cert.der_data for cert in certs] for i, cert in enumerate(ca_certs): tmp_db.add_cert(cert, 'CA certificate %d' % (i + 1), 'C,,') return tmp_db def test_rpc(self): ipa_server = self.config['ipa_server'] tmp_cert_db = self._prepare_nss_dir(ipa_server) api.bootstrap( context='webui_tests', in_server=False, debug=False, verbose=1, xmlrpc_uri="https://" + ipa_server + "/ipa/json", ) api.finalize() api.Backend.rpcclient.connect( nss_dir=tmp_cert_db.secdir, user=u"admin", password=u"Secret123" ) result = api.Command.user_show(u'admin') print json.dumps(result) assert False