def _invite(self, name, method, email, uuid, event, password=""): """Actually invite a given user""" props = { 'uuid': std_uuid(), 'status': 'Open', 'name': name, 'method': method, 'email': email, 'password': password, 'timestamp': std_now() } enrollment = objectmodels['enrollment'](props) enrollment.save() self.log('Enrollment stored', lvl=debug) self._send_invitation(enrollment, event) packet = { 'component': 'isomer.enrol.enrolmanager', 'action': 'invite', 'data': [True, email] } self.fireEvent(send(uuid, packet))
def test_std_now(): now = std_now() assert isinstance(now, str) try: result = dateutil.parser.parse(now) except ValueError: pytest.fail('std_now produces non parsable datetime strings')
def _create_user(self, username, password, mail, method, uuid): """Create a new user and all initial data""" try: if method == 'Invited': config_role = self.config.group_accept_invited else: config_role = self.config.group_accept_enrolled roles = [] if ',' in config_role: for item in config_role.split(','): roles.append(item.lstrip().rstrip()) else: roles = [config_role] newuser = objectmodels['user']({ 'name': username, 'passhash': std_hash(password, self.salt), 'mail': mail, 'uuid': std_uuid(), 'roles': roles, 'created': std_now() }) if method == 'Invited': newuser.needs_password_change = True newuser.save() except Exception as e: self.log("Problem creating new user: "******"New profile uuid: ", newprofile.uuid, lvl=verbose) newprofile.save() packet = { 'component': 'isomer.enrol.enrolmanager', 'action': 'enrol', 'data': [True, mail] } self.fireEvent(send(uuid, packet)) # TODO: Notify crew-admins except Exception as e: self.log("Problem creating new profile: ", type(e), e, lvl=error)
def _login(self, event, user_account, user_profile, client_config): """Send login notification to client""" user_account.lastlogin = std_now() user_account.save() user_account.passhash = "" self.fireEvent( authentication( user_account.name, (user_account, user_profile, client_config), event.clientuuid, user_account.uuid, event.sock, ), "auth", )
def _create_user(ctx): """Internal method to create a normal user""" username, passhash = _get_credentials(ctx.obj["username"], ctx.obj["password"], ctx.obj["db"]) if ctx.obj["db"].objectmodels["user"].count({"name": username}) > 0: raise KeyError() new_user = ctx.obj["db"].objectmodels["user"]({ "uuid": str(uuid4()), "created": std_now() }) new_user.name = username new_user.passhash = passhash return new_user
def change(self, event): """An admin user requests a change to an enrolment""" uuid = event.data['uuid'] status = event.data['status'] if status not in ['Open', 'Pending', 'Accepted', 'Denied', 'Resend']: self.log('Erroneous status for enrollment requested!', lvl=warn) return self.log('Changing status of an enrollment', uuid, 'to', status) enrollment = objectmodels['enrollment'].find_one({'uuid': uuid}) if enrollment is not None: self.log('Enrollment found', lvl=debug) else: return if status == 'Resend': enrollment.timestamp = std_now() enrollment.save() self._send_invitation(enrollment, event) reply = {True: 'Resent'} else: enrollment.status = status enrollment.save() reply = {True: enrollment.serializablefields()} if status == 'Accepted' and enrollment.method == 'Enrolled': self._create_user(enrollment.name, enrollment.password, enrollment.email, 'Invited', event.client.uuid) self._send_acceptance(enrollment, event) packet = { 'component': 'isomer.enrol.enrolmanager', 'action': 'change', 'data': reply } self.log('packet:', packet, lvl=verbose) self.fireEvent(send(event.client.uuid, packet)) self.log('Enrollment changed', lvl=debug)
from isomer.misc.std import std_hash, std_now, std_uuid from isomer.database import objectmodels import isomer.logger as logger from bcrypt import gensalt # from pprint import pprint m = Manager() auth = Authenticator() auth.register(m) new_user = objectmodels['user']({ 'uuid': std_uuid(), 'created': std_now() }) new_user.name = 'TESTER' salt = gensalt().decode("ascii") new_user.passhash = std_hash('PASSWORD', salt) new_user.save() system_config = objectmodels['systemconfig']({ 'uuid': std_uuid(), 'active': True, 'salt': salt })
def install_remote(ctx, archive, setup): """Installs Isomer (Management) on a remote host""" shell = ctx.obj["shell"] platform = ctx.obj["platform"] host_config = ctx.obj["host_config"] use_sudo = host_config["use_sudo"] username = host_config["login"]["username"] existing = ctx.obj["existing"] remote_home = get_remote_home(username) target = os.path.join(remote_home, "isomer") log(remote_home) if shell is None: log("Remote was not configured properly.", lvl=warn) abort(5000) if archive: log("Renaming remote isomer copy") success, result = run_process( remote_home, ["mv", target, os.path.join(remote_home, "isomer_" + std_now())], shell=shell, ) if not success: log("Could not rename remote copy:", result, pretty=True, lvl=error) abort(5000) if existing is None: url = ctx.obj["url"] if url is None: url = host_config.get("url", None) source = ctx.obj["source"] if source is None: source = host_config.get("source", None) if url is None or source is None: log('Need a source and url to install. Try "iso remote --help".') abort(5000) get_isomer(source, url, target, upgrade=ctx.obj["upgrade"], shell=shell) destination = os.path.join(remote_home, "isomer") else: destination = existing install_isomer(platform, use_sudo, shell=shell, cwd=destination) if setup: log("Setting up system user and paths") success, result = run_process(remote_home, ["iso", "system", "all"]) if not success: log( "Setting up system failed:", format_result(result), pretty=True, lvl=error, )
def _archive(ctx, force=False, dynamic=False): instance_configuration = ctx.obj["instance_configuration"] next_environment = get_next_environment(ctx) env = instance_configuration["environments"][next_environment] log("Instance info:", instance_configuration, next_environment, pretty=True, lvl=debug) log("Installed:", env["installed"], "Tested:", env["tested"], lvl=debug) if (not env["installed"] or not env["tested"]) and not force: log("Environment has not been installed - not archiving.", lvl=warn) return False log("Archiving environment:", next_environment) set_instance(ctx.obj["instance"], next_environment) timestamp = std_now().replace(":", "-").replace(".", "-") temp_path = mkdtemp(prefix="isomer_backup") log("Archiving database") if not dump( instance_configuration["database_host"], instance_configuration["database_port"], env["database"], os.path.join(temp_path, "db_" + timestamp + ".json"), ): if not force: log("Could not archive database.") return False archive_filename = os.path.join( "/var/backups/isomer/", "%s_%s_%s.tgz" % (ctx.obj["instance"], next_environment, timestamp), ) try: shutil.copy( os.path.join(get_etc_instance_path(), ctx.obj["instance"] + ".conf"), temp_path, ) with tarfile.open(archive_filename, "w:gz") as f: if not dynamic: for item in locations: path = get_path(item, "") log("Archiving [%s]: %s" % (item, path)) f.add(path) f.add(temp_path, "db_etc") except (PermissionError, FileNotFoundError) as e: log("Could not archive environment:", e, lvl=error) if not force: return False finally: log("Clearing temporary backup target") shutil.rmtree(temp_path) ctx.obj["instance_configuration"]["environments"]["archive"][ timestamp] = env log(ctx.obj["instance_configuration"]) return archive_filename
filename = os.path.join(get_etc_remote_path(), remote["name"] + ".conf") try: with open(filename, "w") as f: f.write(dumps(remote)) log("Instance configuration stored.", lvl=debug) except PermissionError: log( "PermissionError: Could not write instance management configuration file", lvl=error, ) abort(EXIT_NO_PERMISSION) configuration_template = document() configuration_template.add(comment("Isomer Instance Management Configuration")) configuration_template.add(comment("Created on %s" % std_now())) configuration_template.add(nl()) meta = table() meta.add("platform", "amd64") meta["platform"].comment("Set to rpi for advanced Raspberry Pi support") meta.add("distribution", "debian") meta["distribution"].comment("Currently, only debian supported") meta.add("init", "systemd") meta["init"].comment("Currently, only systemd supported") meta.add("prefix", "") configuration_template.add("meta", meta) instance_template = table() instance_template.add("name", "")
# # 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/>. from isomer.logger import isolog as log from isomer.misc.std import std_now, std_uuid DefaultLeerstandsmelderObject = { 'uuid': std_uuid(), 'text': 'Hello World!', 'number': 5, 'bool': True, 'enum': 'Lions', 'secret': 'Rawrrr!', 'timestamp': std_now() } def provision_default_leerstandsmelderobject(items, database_name, overwrite=False, clear=False, skip_user_check=False): """Provisions the default system vessel""" from isomer.provisions.base import provisionList from isomer.database import objectmodels leerstandsmelderObject = objectmodels['leerstandsmelderobject'].find_one( {'name': 'Hello World!'} ) if leerstandsmelderObject is not None: if overwrite is False: