Пример #1
0
    def login(self):
        if self.request.POST:
            username = self.request.POST.get('username')
            password = self.request.POST.get('password')
            try:
                user = self.request.userdb.login(username, password)
            except UserDoesNotExist:
                return {
                    'username':
                    username,
                    'message':
                    self.translate(
                        _("Please enter the correct username and password")),
                }

            if user is False:
                return {
                    'username':
                    username,
                    'message':
                    self.translate(
                        _("Please enter the correct username and password")),
                }

            headers = remember(self.request, username)
            created_msg(
                self.request,
                self.translate(
                    _('Welcome ${username}',
                      mapping={'username': user['username']})), 'info')
            return HTTPFound(location=self.request.route_path('home'),
                             headers=headers)
        else:
            return {}
Пример #2
0
    def login(self):
        if self.request.POST:
            username = self.request.POST.get('username')
            password = self.request.POST.get('password')
            try:
                user = self.request.userdb.login(username, password)
            except UserDoesNotExist:
                return {
                    'username': username,
                    'message': self.translate(
                        _("Please enter the correct username and password")),
                }

            if user is False:
                return {
                    'username': username,
                    'message': self.translate(_("Please enter the correct username and password")),
                }

            headers = remember(self.request, username)
            created_msg(self.request, self.translate(
                _('Welcome ${username}',
                  mapping={'username': user['username']})
            ), 'info')


            return HTTPFound(location=self.request.route_path('home'),
                             headers=headers)
        else:
            return {}
Пример #3
0
class AdminUserOUManage(colander.MappingSchema):
    ou_managed = colander.SchemaNode(colander.List(),
                                     title=_('This user can register workstation under these Organitation Units'),
                                     widget=deferred_choices_widget)
    ou_availables = colander.SchemaNode(colander.List(),
                                        title=_('Organitation Unit availables to register workstations by this user'),
                                        widget=deferred_choices_widget)
Пример #4
0
    def login(self):
        if self.request.POST:
            username = self.request.POST.get('username')
            password = self.request.POST.get('password')
            try:
                user = self.request.userdb.login(username, password)
            except UserDoesNotExist:
                return {
                    'username': username,
                    'message': self.translate(
                        _("The requested username doesn't exists")),
                }

            if user is False:
                return {
                    'username': username,
                    'message': self.translate(_("The password doesn't match")),
                }

            headers = remember(self.request, username)
            self.request.session.flash(self.translate(
                _('welcome ${username}',
                  mapping={'username': user['username']})
            ))
            return HTTPFound(location=self.request.route_path('home'),
                             headers=headers)
        else:
            return {}
Пример #5
0
    def login(self):
        if self.request.POST:
            username = self.request.POST.get('username')
            password = self.request.POST.get('password')
            try:
                user = self.request.userdb.login(username, password)
            except UserDoesNotExist:
                return {
                    'username':
                    username,
                    'message':
                    self.translate(_("The requested username doesn't exists")),
                }

            if user is False:
                return {
                    'username': username,
                    'message': self.translate(_("The password doesn't match")),
                }

            headers = remember(self.request, username)
            self.request.session.flash(
                self.translate(
                    _('welcome ${username}',
                      mapping={'username': user['username']})))
            return HTTPFound(location=self.request.route_path('home'),
                             headers=headers)
        else:
            return {}
Пример #6
0
    def save(self, postvars):
        logger.debug(
            "forms.py ::: MaintenanceForm - postvars = {0}".format(postvars))

        if postvars['maintenance_message'] == "":
            logger.debug(
                "forms.py ::: MaintenanceForm - Deleting maintenance message")
            self.request.db.settings.delete_one({'key': 'maintenance_message'})
            self.created_msg(
                _('Maintenance message was deleted successfully.'))
        else:
            logger.debug(
                "forms.py ::: MaintenanceForm - Creating maintenance message")
            compose = postvars['maintenance_message']
            maintenance_mode(self.request, compose)
            msg = self.request.db.settings.find_one(
                {'key': 'maintenance_message'})
            if msg is None:
                msg = {
                    'key': 'maintenance_message',
                    'value': compose,
                    'type': 'string'
                }
                self.request.db.settings.insert_one(msg)
            else:
                self.request.db.settings.update_one(
                    {'key': 'maintenance_message'},
                    {'$set': {
                        'value': compose
                    }})

            self.request.session['maintenance_message'] = compose
            self.created_msg(_('Maintenance settings saved successfully.'))
Пример #7
0
class BaseUser(colander.MappingSchema):
    first_name = colander.SchemaNode(colander.String(),
                                     title=_('First name'),
                                     default='',
                                     missing='')
    last_name = colander.SchemaNode(colander.String(),
                                    title=_('Last name'),
                                    default='',
                                    missing='')
Пример #8
0
def admins_superuser(context, request):
    username = request.matchdict['username']
    if '_superuser' in request.POST:
        is_superuser = True
        message = _('Now the user is a super user')
    elif '_no_superuser' in request.POST:
        is_superuser = False
        message = _('Now the user is not a super user')
        message.translate('es')
    request.userdb.collection.update({'username': username}, {'$set': {'is_superuser': is_superuser}})
    messages.created_msg(request, message, 'success')
    return HTTPFound(location=request.route_url('admins'))
Пример #9
0
class ActiveDirectoryVariableSpecific(colander.MappingSchema):
    sssd_conf = colander.SchemaNode(deform.FileData(),
                                    widget=FileUploadWidget(filestore),
                                    title=_('SSSD conf'))
    krb5_conf = colander.SchemaNode(deform.FileData(),
                                    widget=FileUploadWidget(filestore),
                                    title=_('KRB5 conf'))
    smb_conf = colander.SchemaNode(deform.FileData(),
                                   widget=FileUploadWidget(filestore),
                                   title=_('SMB conf'))
    pam_conf = colander.SchemaNode(deform.FileData(),
                                   widget=FileUploadWidget(filestore),
                                   title=_('PAM conf'))
Пример #10
0
class AdminUserOUPerm(colander.MappingSchema):
    ou_selected = colander.SchemaNode(colander.List(),
                                      title=_('Select an Organization Unit'),
                                      widget=deferred_choices_widget)


    permission = colander.SchemaNode(colander.Set(),
                                     title=_('Permissions'),
                                     validator=colander.All(
                                         colander.Length(min=1),
                                         PermissionValidator()),
                                     widget=deform.widget.CheckboxChoiceWidget(
                                         values=PERMISSIONS, inline=True))
Пример #11
0
class Setting(colander.MappingSchema):
    _id = colander.SchemaNode(ObjectIdField())
    key = colander.SchemaNode(colander.String(),
                                     title=_('Key'),
                                     default='',
                                     missing='')
    value = colander.SchemaNode(colander.String('UTF-8'),
                                    title=_('Value'),
                                    default='',
                                    missing='')
    type = colander.SchemaNode(colander.String(),
                                    title=_('Type'),
                                    default='',
                                    missing='')
Пример #12
0
def admin_delete(context, request):
    if request.method != 'DELETE':
        raise HTTPMethodNotAllowed("Only delete method is accepted")
    username = request.GET.get('username')
    if request.session['auth.userid'] == username:
        forget(request)
    settings = get_current_registry().settings
    api = get_chef_api(settings, request.user)
    success_remove_chef = delete_chef_admin_user(api, username)
    if not success_remove_chef:
        messages.created_msg(request, _('User deleted unsuccessfully from chef'), 'danger')
    request.userdb.delete_users({'username': username})
    messages.created_msg(request, _('User deleted successfully'), 'success')
    return {'ok': 'ok'}
Пример #13
0
 def __init__(self, schema, collection, *args, **kwargs):
     buttons = (GecosButton(title=_('Submit'),
                            css_class='pull-right',
                            name='_submit'),
                GecosButton(title=_('Delete'),
                            name='_delete',
                            css_class='pull-right',
                            type='button'))
     super(AdminUserEditForm, self).__init__(schema, collection, buttons=buttons, *args, **kwargs)
     schema.children[self.sorted_fields.index('password')] = schema.children[self.sorted_fields.index('password')].clone()
     schema.children[self.sorted_fields.index('repeat_password')] = schema.children[self.sorted_fields.index('repeat_password')].clone()
     schema.children[self.sorted_fields.index('password')].missing = ''
     schema.children[self.sorted_fields.index('repeat_password')].missing = ''
     self.children[self.sorted_fields.index('username')].widget.readonly = True
Пример #14
0
 def __call__(self, node, value):
     super(UpdateSequenceValidator, self).__call__(node,value)
     if self.filename:
         m = re.match(self.pattern, self.filename)
         request = pyramid.threadlocal.get_current_request()
         from gecoscc.db import get_db
         mongodb = get_db(request)
         nextseq = getNextUpdateSeq(mongodb)
         # Numeric update naming
         if m is not None and m.group(1) != nextseq:
             err_msg = _(self.err_msg, mapping={'val': nextseq})
             node.raise_invalid(err_msg)
         else:
             if mongodb.updates.find({'name':self.filename}).count() > 0:
                 node.raise_invalid(_('This name already exists'))
Пример #15
0
def admins_superuser(context, request):
    username = request.matchdict['username']
    if '_superuser' in request.POST:
        is_superuser = True
        message = _('Now the user is a super user')
    elif '_no_superuser' in request.POST:
        is_superuser = False
        message = _('Now the user is not a super user')
        message.translate('es')
    request.userdb.collection.update({'username': username},
                                     {'$set': {
                                         'is_superuser': is_superuser
                                     }})
    messages.created_msg(request, message, 'success')
    return HTTPFound(location=request.route_url('admins'))
Пример #16
0
def settings_save(_context, request):
    data = request.POST.get('data')
    response = Response()
    if data is not None:
        data = json.loads(data)
        for key in data:
            k = key.replace("___", ".")
            setting_data = request.db.settings.find_one({"key": k})
            if setting_data is None:
                setting = create_setting(k)
            else:
                setting = Setting().deserialize(setting_data)

            if isinstance(data[key], str):
                Setting().set_value(setting, 'value', data[key])
            else:
                Setting().set_value(setting, 'value', json.dumps(data[key]))

            # Save in mongoDB
            obj = Setting().serialize(setting)
            if obj['_id'] == colander.null:
                del obj['_id']
                request.db.settings.insert_one(obj)
            else:
                obj['_id'] = ObjectId(obj['_id'])
                request.db.settings.replace_one({'_id': obj['_id']}, obj)

    messages.created_msg(request, _('Settings modified successfully'),
                         'success')
    response.write('SUCCESS')
    return response
Пример #17
0
 def __call__(self, node, value):
     if value['password'] != value['repeat_password']:
         node.raise_invalid(_('The passwords do not match'))
     from gecoscc.userdb import create_password
     if bool(value['password']):
         value['password'] = create_password(value['password'])
     del value['repeat_password']
Пример #18
0
class LowerAlphaNumeric(object):
    err_msg = _('Only lowercase letters, numbers or dots')
    regex = re.compile(r'^([a-z0-9\.])*$')

    def __call__(self, node, value):
        if not self.regex.match(value):
            node.raise_invalid(self.err_msg)
Пример #19
0
 def __call__(self, node, value):
     if value['password'] != value['repeat_password']:
         node.raise_invalid(_('The passwords do not match'))
     from gecoscc.userdb import create_password
     if bool(value['password']):
         value['password'] = create_password(value['password'])
     del value['repeat_password']
Пример #20
0
class UpdateSequenceValidator(UpdateBaseValidator):
    ''' Subclass for validating numeric sequence of an update
    
    Attributes:
      err_msg (str):    error message
      pattern (str):    regex for valid numeric sequence
    '''
    err_msg = _('No valid update sequence. Must be: {$val}')
    def __call__(self, node, value):
        super(UpdateSequenceValidator, self).__call__(node,value)
        if self.filename:
            m = re.match(SERIALIZED_UPDATE_PATTERN, self.filename)
            request = pyramid.threadlocal.get_current_request()
            from gecoscc.db import get_db
            mongodb = get_db(request)
            nextseq = getNextUpdateSeq(mongodb)
            # Numeric update naming
            if m is not None and m.group(1) != nextseq:
                err_msg = _(self.err_msg, mapping={'val': nextseq})
                node.raise_invalid(err_msg)
            else:
                if mongodb.updates.find({'name':self.filename}).count() > 0:
                    node.raise_invalid(_('This name already exists'))
                    
                sequence = re.match(BASE_UPDATE_PATTERN, self.filename).group(1)
                if mongodb.updates.find({'_id': sequence}).count() > 0:
                    node.raise_invalid(_('This sequence already exists'))
Пример #21
0
class Maintenance(colander.MappingSchema):
    maintenance_message = colander.SchemaNode(colander.String(),
                                              validator=colander.Length(max=500),
                                              widget=deform.widget.TextAreaWidget(rows=10, cols=80, maxlength=500, css_class='deform-widget-textarea-maintenance'),
                                              title=_('Users will be warned with this message'),
                                              default='',
                                              missing='')
Пример #22
0
class UpdateFileStructureValidator(UpdateBaseValidator):
    ''' Subclass for validating zip file content
    
    This structure is defined by UPDATE_STRUCTURE variable in this file.
    UPDATE_STRUCTURE = ['control','cookbook/','scripts/']
    
    Attributes:
      err_msg (str):    error message
    '''
    err_msg = _('No valid zip file structure')

    def __call__(self, node, value):

        super(UpdateFileStructureValidator, self).__call__(node,value)
       
        if os.path.isdir(self.decompress):
            for archive in os.listdir(self.decompress):
                # Adding slash if archive is a dir for comparison
                if os.path.isdir(self.decompress + archive):
                    archive += os.sep

                if archive not in UPDATE_STRUCTURE:
                    node.raise_invalid(gettext(self.err_msg))

            for required in UPDATE_STRUCTURE:
                if not os.path.exists(self.decompress + required):
                    node.raise_invalid(gettext(self.err_msg))
Пример #23
0
def admin_delete(context, request):
    if request.method != 'DELETE':
        raise HTTPMethodNotAllowed("Only delete method is accepted")
    username = request.GET.get('username')
    if request.session['auth.userid'] == username:
        forget(request)
    settings = get_current_registry().settings
    api = get_chef_api(settings, request.user)
    success_remove_chef = delete_chef_admin_user(api, username)
    if not success_remove_chef:
        messages.created_msg(request,
                             _('User deleted unsuccessfully from chef'),
                             'danger')
    request.userdb.delete_user({'username': username})
    messages.created_msg(request, _('User deleted successfully'), 'success')
    return {'ok': 'ok'}
Пример #24
0
 def __init__(self,
              schema,
              action='',
              method='POST',
              buttons=(),
              formid='deform',
              use_ajax=False,
              ajax_options='{}',
              autocomplete=None,
              **kw):
     if not buttons:
         buttons = (GecosButton(title=_('Submit'),
                                css_class='pull-right'), )
     if self.sorted_fields:
         schema.children.sort(
             key=lambda item: self.sorted_fields.index(item.name))
     super(GecosForm, self).__init__(schema,
                                     action=action,
                                     method=method,
                                     buttons=buttons,
                                     formid='deform',
                                     use_ajax=use_ajax,
                                     ajax_options=ajax_options,
                                     autocomplete=None,
                                     **kw)
     self.widget.template = self.template
     self.widget.item_template = self.item_template
     self.widget.css_class = self.css_class
Пример #25
0
class AuthLDAPVariable(colander.MappingSchema):
    uri = colander.SchemaNode(colander.String(),
                              title=_('uri'),
                              default='URL_LDAP')
    base = colander.SchemaNode(colander.String(),
                               title=_('base'),
                               default='OU_BASE_USER')
    basegroup = colander.SchemaNode(colander.String(),
                                    title=_('base group'),
                                    default='OU_BASE_GROUP')
    binddn = colander.SchemaNode(colander.String(),
                                 title=_('binddn'),
                                 default='USER_WITH_BIND_PRIVILEGES')
    bindpwd = colander.SchemaNode(colander.String(),
                                  title=_('bindpwd'),
                                  default='PASSWORD_USER_BIND')
Пример #26
0
def settings_save(_context, request):
    data = request.POST.get('data')
    response = Response()
    if data is not None:
        data = json.loads(data)
        for key in data:
            k = key.replace("___", ".")
            setting_data = request.db.settings.find_one({"key": k })
            if setting_data is None:
                setting = create_setting(k)
            else:
                setting = Setting().deserialize(setting_data)
            
            if isinstance(data[key], str) or isinstance(data[key], unicode):
                Setting().set_value(setting, 'value', data[key])
            else:
                Setting().set_value(setting, 'value', json.dumps(data[key]))
            
            # Save in mongoDB
            obj = Setting().serialize(setting)
            if obj['_id'] == colander.null:
                del obj['_id']
            else:
                obj['_id'] = ObjectId(obj['_id'])
            #logger.debug('save= %s'%(obj))
            request.db.settings.save(obj)
                                    
    messages.created_msg(request, _('Settings modified successfully'), 'success')
    response.write('SUCCESS')
    return response
Пример #27
0
    def save(self, update):
        settings = get_current_registry().settings
        update = update['local_file'] if update['local_file'] is not None else update['remote_file']
        sequence = re.match('^update-(\w+)\.zip$', update['filename']).group(1)
        logger.debug("forms.py ::: UpdateForm - sequence = %s" % sequence)
        # Updates directory: /opt/gecoscc/updates/<sequence>
        updatesdir = settings['updates.dir'] + sequence
        logger.debug("forms.py ::: UpdateForm - updatesdir = %s" % updatesdir)
        # Update zip file
        zipped = settings['updates.tmp'] + update['filename']
        logger.debug("forms.py ::: UpdateForm - zipped = %s" % zipped)
        try:
            # https://docs.python.org/2/library/shutil.html
            # The destination directory, named by dst, must not already exist; it will be created as well as missing parent directories
            # Checking copytree NFS
            shutil.copytree(update['decompress'], updatesdir)
            shutil.rmtree(update['decompress'])
            # Move zip file to updates dir
            shutil.move(zipped, updatesdir)

            # Decompress cookbook zipfile
            cookbookdir = settings['updates.cookbook'].format(sequence)
            logger.debug("forms.py ::: UpdateForm - cookbookdir = %s" % cookbookdir)
            for cookbook in os.listdir(cookbookdir):
                cookbook = cookbookdir + os.sep + cookbook
                logger.debug("forms.py ::: UpdateForm - cookbook = %s" % cookbook)
                if zipfile.is_zipfile(cookbook):
                    zip_ref = zipfile.ZipFile(cookbook,'r')
                    zip_ref.extractall(cookbookdir + os.sep + settings['chef.cookbook_name'])
                    zip_ref.close()
            # Insert update register
            self.request.db.updates.insert({'_id': sequence, 'name': update['filename'], 'path': updatesdir, 'timestamp': int(time.time()), 'rollback':0, 'user': self.request.user['username']})
            # Launching task for script execution
            script_runner.delay(self.request.user, sequence)
            link = '<a href="' +  self.request.route_url('updates_tail',sequence=sequence) + '">' + _("here") + '</a>'
            self.created_msg(_("Update log. %s") % link)
        except OSError as e:
                error = True
                if e.errno == errno.EACCES:
                    self.created_msg(_('Permission denied: %s') % updatesdir, 'danger')
                else:
                    self.created_msg(_('There was an error attempting to upload an update. Please contact an administrator'), 'danger')
        except (IOError, os.error) as e:
            pass
        except errors.DuplicateKeyError as e:
            logger.error('Duplicate key error')
            self.created_msg(_('There was an error attempting to upload an update. Please contact an administrator'), 'danger')
Пример #28
0
 def save(self, admin_user):
     if admin_user['password'] == '':
         del admin_user['password']
     self.collection.update({'username': self.username},
                            {'$set': admin_user})
     if admin_user['username'] != self.username and self.request.session['auth.userid'] == self.username:
         self.request.session['auth.userid'] = admin_user['username']
     self.created_msg(_('User edited successfully'))
Пример #29
0
 def __init__(self, schema, collection, username, request, *args, **kwargs):
     schema.get(
         'ou_managed'
     ).title += '<p><a href="#ou-managed" class="add-another">%s</a></p>' % _(
         'Add another')
     schema.get(
         'ou_availables'
     ).title += '<p><a href="#ou-availables" class="add-another">%s</a></p>' % _(
         'Add another')
     schema.children.append(self.ou_managed_count)
     schema.children.append(self.ou_availables_count)
     super(AdminUserOUManageForm, self).__init__(schema,
                                                 collection=collection,
                                                 username=username,
                                                 request=request,
                                                 *args,
                                                 **kwargs)
Пример #30
0
 def save(self, admin_user):
     if admin_user['password'] == '':
         del admin_user['password']
     self.collection.update({'username': self.username},
                            {'$set': admin_user})
     if admin_user['username'] != self.username and self.request.session[
             'auth.userid'] == self.username:
         self.request.session['auth.userid'] = admin_user['username']
     self.created_msg(_('User edited successfully'))
Пример #31
0
    def __init__(self, schema, request, *args, **kwargs):
        self.request = request
        buttons = (GecosButton(title=_('Submit'),
                               css_class='deform-maintenance-submit'), )

        super(MaintenanceForm, self).__init__(schema,
                                              buttons=buttons,
                                              *args,
                                              **kwargs)
Пример #32
0
 def __call__(self, node, value):
     super(UpdateSequenceValidator, self).__call__(node,value)
     if self.filename:
         m = re.match(SERIALIZED_UPDATE_PATTERN, self.filename)
         request = pyramid.threadlocal.get_current_request()
         from gecoscc.db import get_db
         mongodb = get_db(request)
         nextseq = getNextUpdateSeq(mongodb)
         # Numeric update naming
         if m is not None and m.group(1) != nextseq:
             err_msg = _(self.err_msg, mapping={'val': nextseq})
             node.raise_invalid(err_msg)
         else:
             if mongodb.updates.find({'name':self.filename}).count() > 0:
                 node.raise_invalid(_('This name already exists'))
                 
             sequence = re.match(BASE_UPDATE_PATTERN, self.filename).group(1)
             if mongodb.updates.find({'_id': sequence}).count() > 0:
                 node.raise_invalid(_('This sequence already exists'))
Пример #33
0
 def __call__(self, node, value):
     ignore_unique = getattr(node, 'ignore_unique', False)
     if ignore_unique:
         return
     request = pyramid.threadlocal.get_current_request()
     from gecoscc.db import get_db
     mongodb = get_db(request)
     if mongodb.adminusers.find({node.name: value}).count() > 0:
         err_msg = _(self.err_msg, mapping={'val': value})
         node.raise_invalid(err_msg)
Пример #34
0
 def __call__(self, node, value):
     ignore_unique = getattr(node, 'ignore_unique', False)
     if ignore_unique:
         return
     request = pyramid.threadlocal.get_current_request()
     from gecoscc.db import get_db
     mongodb = get_db(request)
     if mongodb.adminusers.find({node.name: value}).count() > 0:
         err_msg = _(self.err_msg, mapping={'val': value})
         node.raise_invalid(err_msg)
Пример #35
0
    def save(self, postvars):
        logger.debug("forms.py ::: MaintenanceForm - postvars = {0}".format(postvars))

        if postvars['maintenance_message'] == "":
            logger.debug("forms.py ::: MaintenanceForm - Deleting maintenance message")
            self.request.db.settings.remove({'key':'maintenance_message'})
            self.created_msg(_('Maintenance message was deleted successfully.'))
        else:
            logger.debug("forms.py ::: MaintenanceForm - Creating maintenance message")
            compose = postvars['maintenance_message']
            maintenance_mode(self.request, compose)
            msg = self.request.db.settings.find_one({'key':'maintenance_message'})
            if msg is None:
                msg = {'key':'maintenance_message', 'value': compose, 'type':'string'}
                self.request.db.settings.insert(msg)
            else:
                self.request.db.settings.update({'key':'maintenance_message'},{'$set':{ 'value': compose}})

            self.request.session['maintenance_message'] = compose
            self.created_msg(_('Maintenance settings saved successfully.'))
Пример #36
0
class AdminUserVariables(colander.MappingSchema):
    uri_ntp = colander.SchemaNode(colander.String(),
                                  default='URI_NTP_SERVER.EX',
                                  title=_('URI ntp'))
    auth_type = colander.SchemaNode(colander.String(),
                                    title=_('Auth type'),
                                    default='LDAP',
                                    widget=deform.widget.SelectWidget(values=AUTH_TYPE_CHOICES))
    specific_conf = colander.SchemaNode(colander.Boolean(),
                                        title=_('Specific conf'),
                                        default=False)
    auth_ldap = AuthLDAPVariable(title=_('Auth LDAP'))
    auth_ad = ActiveDirectoryVariableNoSpecific(title=_('Auth Active directory'))
    auth_ad_spec = ActiveDirectoryVariableSpecific(title=_('Auth Active directory'))

    def get_config_files(self, mode, username):
        return self.get_files(mode, username, ['sssd.conf', 'krb5.conf', 'smb.conf', 'pam.conf'])

    def get_files(self, mode, username, file_name):
        settings = get_current_registry().settings
        first_boot_media = settings.get('firstboot_api.media')
        user_media = os.path.join(first_boot_media, username)
        if mode == 'w' and not os.path.exists(user_media):
            os.makedirs(user_media)
        if isinstance(file_name, list):
            files = [open(os.path.join(user_media, name), mode) for name in file_name]
            return files
        return open(os.path.join(user_media, file_name), mode)
Пример #37
0
class UpdateNamingValidator(UpdateBaseValidator):
    ''' Subclass for validating naming convention of an update
    
    Attributes:
      err_msg (str):    error message
      pattern (str):    regex for valid naming convention
    '''
    err_msg = _('The uploaded file is not followed naming convention')
    pattern = BASE_UPDATE_PATTERN
    def __call__(self, node, value):
        super(UpdateNamingValidator, self).__call__(node, value)
        if self.filename and not (re.match(self.pattern, self.filename)):
            node.raise_invalid(self.err_msg)
Пример #38
0
 def save(self, admin_user):
     self.collection.insert(admin_user)
     admin_user['plain_password'] = self.cstruct['password']
     settings = get_current_registry().settings
     user = self.request.user
     api = get_chef_api(settings, user)
     try:
         create_chef_admin_user(api, settings, admin_user['username'])
         self.created_msg(_('User created successfully'))
         return True
     except ChefServerError as e:
         self.created_msg(e.message, 'danger')
         self.collection.remove({'username': admin_user['username']})
         raise e
Пример #39
0
class AdminUser(BaseUser):
    validator = AdminUserValidator()
    username = colander.SchemaNode(colander.String(),
                                   title=_('Username'),
                                   validator=colander.All(
                                       Unique('adminusers',
                                              'There is a user with this username: ${val}'),
                                       LowerAlphaNumeric()))
    password = colander.SchemaNode(colander.String(),
                                   title=_('Password'),
                                   widget=deform.widget.PasswordWidget(),
                                   validator=colander.Length(min=6))
    repeat_password = colander.SchemaNode(colander.String(),
                                          default='',
                                          title=_('Repeat the password'),
                                          widget=deform.widget.PasswordWidget(),
                                          validator=colander.Length(min=6))
    email = colander.SchemaNode(colander.String(),
                                title=_('Email'),
                                validator=colander.All(
                                    colander.Email(),
                                    Unique('adminusers',
                                           'There is a user with this email: ${val}')))
Пример #40
0
 def save(self, admin_user):
     self.collection.insert(admin_user)
     admin_user['plain_password'] = self.cstruct['password']
     settings = get_current_registry().settings
     user = self.request.user
     api = get_chef_api(settings, user)
     try:
         create_chef_admin_user(api, settings, admin_user['username'])
         self.created_msg(_('User created successfully'))
         return True
     except ChefServerError as e:
         self.created_msg(e.message, 'danger')
         self.collection.remove({'username': admin_user['username']})
         raise e
Пример #41
0
 def save(self, variables):
     if variables['auth_type'] != 'LDAP' and variables.get('specific_conf', False):
         for i, fileout in enumerate(self.schema.get_config_files('w', self.username)):
             fileout_name = fileout.name.split(os.sep)[-1]
             file_field = variables['auth_ad_spec'][fileout_name.replace('.', '_')]
             if not file_field:
                 continue
             filein = file_field['fp']
             fileout.write(filein.read())
             filein.close()
             fileout.close()
     del variables['auth_ad_spec']
     self.collection.update({'username': self.username}, {'$set': {'variables': variables}})
     self.created_msg(_('Variables updated successfully'))
Пример #42
0
class RemoteStoragePolicy(BasePolicy):
    name = 'remote-storage'
    screen_name = _('Remote Storage')

    schema = {
        'type': 'object',
        'properties': {
            'name': {
                'type': 'string'
            },
            'node': {
                'type': 'string'
            },
            'storage_id': {
                'type': 'string'
            },
            'storage_node': {
                'type': 'object',
                'properties': {
                    'memberof': {
                        'type': 'array'
                    },
                    'server': {
                        'type': 'string'
                    },
                    'port': {
                        'type': 'integer'
                    },
                    'protocol': {
                        'type': 'string'
                    },
                    'localpath': {
                        'type': 'string'
                    },
                    'mount': {
                        'type': 'string'
                    },
                    'extraops': {
                        'type': 'string'
                    },
                },
                'required': ['server', 'protocol', 'localpath', 'mount']
            }
        },
        'required': ['name', 'node', 'storage_id']
    }

    def translate_to_recipes(self):
        return {}
Пример #43
0
 def __init__(self, schema, collection, *args, **kwargs):
     buttons = (GecosButton(title=_('Submit'),
                            css_class='pull-right',
                            name='_submit'),
                GecosButton(title=_('Delete'),
                            name='_delete',
                            css_class='pull-right',
                            type='button'))
     super(AdminUserEditForm, self).__init__(schema,
                                             collection,
                                             buttons=buttons,
                                             *args,
                                             **kwargs)
     schema.children[self.sorted_fields.index(
         'password')] = schema.children[self.sorted_fields.index(
             'password')].clone()
     schema.children[self.sorted_fields.index(
         'repeat_password')] = schema.children[self.sorted_fields.index(
             'repeat_password')].clone()
     schema.children[self.sorted_fields.index('password')].missing = ''
     schema.children[self.sorted_fields.index(
         'repeat_password')].missing = ''
     self.children[self.sorted_fields.index(
         'username')].widget.readonly = True
Пример #44
0
class UpdateModel(colander.MappingSchema):
    '''
    Schema for representing an update in form 
    '''
    local_file = colander.SchemaNode(deform.FileData(),
                                     widget=FileUploadWidget(filestore),
                                     preparer=unzip_preparer,
                                     validator = colander.All(
                                         UpdateNamingValidator(), 
                                         UpdateSequenceValidator(),
                                         UpdateFileStructureValidator(), 
                                         UpdateControlFileValidator(),
                                         UpdateScriptRangeValidator()),
                                     missing=colander.null,
                                     title=_('Update ZIP'))
    remote_file = colander.SchemaNode(UrlFile(),
                                      preparer=unzip_preparer,
                                      validator = colander.All(
                                          UpdateNamingValidator(), 
                                          UpdateSequenceValidator(),
                                          UpdateFileStructureValidator(), 
                                          UpdateControlFileValidator()),
                                      missing=colander.null,
                                      title=_('URL download'))
Пример #45
0
 def __init__(self, schema, action='', method='POST', buttons=(),
              formid='deform', use_ajax=False, ajax_options='{}',
              autocomplete=None, **kw):
     if not buttons:
         buttons = (GecosButton(title=_('Submit'),
                                css_class='pull-right'),)
     if self.sorted_fields:
         schema.children.sort(key=lambda item: self.sorted_fields.index(item.name))
     super(GecosForm, self).__init__(schema, action=action,
                                     method=method,
                                     buttons=buttons,
                                     formid='deform',
                                     use_ajax=use_ajax,
                                     ajax_options=ajax_options,
                                     autocomplete=None, **kw)
     self.widget.template = self.template
     self.widget.item_template = self.item_template
     self.widget.css_class = self.css_class
Пример #46
0
    def save(self, permissions):
        ''' Saving permissions '''

        (ou_managed, ou_availables, ou_remote, ou_readonly) = (set(), set(), set(), set())

        for p in permissions:

            ou_selected = p['ou_selected'][0]

            if 'MANAGE' in p['permission']:
                ou_managed.add(ou_selected)
            if 'LINK' in p['permission']:
                ou_availables.add(ou_selected)
            if 'READONLY' in p['permission']:
                ou_readonly.add(ou_selected)
            if 'REMOTE' in p['permission']:
                ou_remote.add(ou_selected)
                if 'MANAGE' not in p['permission']:
                    ou_readonly.add(ou_selected)

        logger.debug("PermissionsForm ::: save - ou_managed = {}".format(ou_managed))
        logger.debug("PermissionsForm ::: save - ou_availables = {}".format(ou_availables))
        logger.debug("PermissionsForm ::: save - ou_remote = {}".format(ou_remote))
        logger.debug("PermissionsForm ::: save - ou_readonly = {}".format(ou_readonly))

        self.collection.update(
            {'username': self.username},
            {'$set': {
                'ou_managed': list(ou_managed),
                'ou_availables': list(ou_availables),
                'ou_remote': list(ou_remote),
                'ou_readonly': list(ou_readonly)
                }
            }
        )
        self.created_msg(_('User edited successfully'))
Пример #47
0
    def save(self, upload):
        
        logger.info("CookbookUpload - upload - %s" % upload)
        error = False
        settings = get_current_registry().settings
        rootdir = settings['cookbook_upload_rootdir'] + '/'
        logger.debug("forms.py ::: CookbookUpload - rootdir = %s" % rootdir)
        uploadir = rootdir + self.username + "/uploads/" + str(int(time.time())) + "/"
        logger.debug("forms.py ::: CookbookUpload - uploadir = %s" % uploadir)

        try:
            if not os.path.exists(uploadir):
                os.makedirs(uploadir)
            if upload['local_file']:
                f = upload['local_file']
                with open('/tmp/' + f['filename'], 'wb') as zipped: 
                    zipped.write(f['fp'].read())

            elif upload['remote_file']:
                f = urllib2.urlopen(upload['remote_file'])
                with open('/tmp/' + os.path.basename(upload['remote_file']), "wb") as zipped:
                    zipped.write(f.read())

            logger.info("forms.py ::: CookbookUpload - zipped = %s" % zipped)

            # Decompress zipfile into temporal dir
            tmpdir = tempfile.mkdtemp()
            zip_ref = zipfile.ZipFile(zipped.name,'r')
            zip_ref.extractall(tmpdir)
            zip_ref.close()

            # Getting cookbook's name
            cookbook_name = cookbook_ver = ""
            for name in glob.glob(tmpdir + "/*"):
                logger.info("forms.py ::: CookbookUpload - name = %s" % name)
                tmpdir = name
                logger.info("forms.py ::: CookbookUpload - tmpdir = %s" % tmpdir)
                with open("%s/metadata.rb" % name) as metafile:
                    for line in metafile:
                        logger.debug("forms.py ::: CookbookUpload - line = %s" % line)
                        matchname = re.search(r'name[ \t]+(")?(\w+)(?(1)\1|)', line)
                        matchver  = re.search(r'version[ \t]+(")?([\d.]+)(?(1)\1|)', line)
                        if matchname:
                            cookbook_name = matchname.group(2)
                        elif matchver:
                            cookbook_ver  = matchver.group(2)
                            break
            
            if  not (cookbook_name and cookbook_ver):            
                raise ParseMetadataException()

            logger.debug("forms.py ::: CookbookUpload - cookbook_name = %s" % cookbook_name)
            logger.debug("forms.py ::: CookbookUpload - cookbook_ver = %s" % cookbook_ver)
            cookbook_path = uploadir + cookbook_name
            logger.debug("forms.py ::: CookbookUpload - cookbook_path = %s" % cookbook_path)
            os.rename(tmpdir, cookbook_path)

        except urllib2.HTTPError as e:
                error = True
                self.created_msg(_('There was an error downloading zip file'), 'danger')
        except urllib2.URLError as e:
                error = True
                self.created_msg(_('There was an error downloading zip file'), 'danger')
        except zipfile.BadZipfile as e:
                error = True
                self.created_msg(_('File is not a zip file: %s') % zipped.name, 'danger')
        except OSError as e:
                error = True
                if e.errno == errno.EACCES:
                    self.created_msg(_('Permission denied: %s') % uploadir, 'danger')
                else:
                    logger.error("forms.py ::: CookbookUpload - Error = %s" % e.strerror)
                    self.created_msg(_('There was an error attempting to upload the cookbook. Please contact an administrator'), 'danger')
        except IOError as e:
                logger.debug("forms.py ::: CookbookUpload - e = %s" % e)
                error = True
                self.created_msg(_('No such file or directory: metadata.rb'), 'danger')
        except ParseMetadataException as e:
                logger.debug("forms.py ::: CookbookUpload - e = %s" % e)
                error = True
                self.created_msg(_('No cookbook name or version found in metadata.rb'),'danger')

        if not error:
            obj = {
                "_id": ObjectId(),
                "name": cookbook_name,
                "path": uploadir,
                "type": 'upload',
                "version": cookbook_ver
            }
            cookbook_upload.delay(self.request.user, 'upload', obj)
            logbook_link = '<a href="' +  self.request.application_url + '/#logbook' + '">' + _("here") + '</a>'
            self.created_msg(_("Upload cookbook enqueue. Visit logbook %s") % logbook_link)
Пример #48
0
def settings_save(context, request):
    data = request.POST.get('data')
    settings = request.db.settings.find()
    response = Response()
    if data is not None:
        data = json.loads(data)
        for key in data:
            k = key.replace("___", ".")
            setting_data = request.db.settings.find_one({"key": k })
            if setting_data is None:
                setting = create_setting(k)
            else:
                setting = Setting().deserialize(setting_data)
            
            if isinstance(data[key], str) or isinstance(data[key], unicode):
                Setting().set_value(setting, 'value', data[key])
            else:
                Setting().set_value(setting, 'value', json.dumps(data[key]))
            
            # Save in mongoDB
            obj = Setting().serialize(setting)
            if obj['_id'] == colander.null:
                del obj['_id']
            else:
                obj['_id'] = ObjectId(obj['_id'])
            #logger.debug('save= %s'%(obj))
            request.db.settings.save(obj)
            
            # If saving "software_profiles", save them also in "software_profiles" collection
            if key == "software_profiles":
                collection = request.db.software_profiles
                # Update the software profiles
                for new_profile in data[key]:
                    name = new_profile['name']
                    db_profile = collection.find_one({'name': name})
                    
                    if not db_profile:
                        collection.insert(new_profile)
                        logger.debug("Created profile: %s" % name)

                    elif new_profile['packages'] != db_profile['packages']:
                        collection.update({'name': name}, new_profile)
                        logger.debug("Updated profile: %s" % name)

                # Check if the user is trying to delete a software profile
                sp_policy = request.db.policies.find_one({"slug" : "package_profile_res"})
                if not sp_policy:
                    messages.created_msg(request, _('Software Profiles policy not found'), 'warning')
                    response.write('SUCCESS')
                    return response
                    
                db_profiles = collection.find()
                for profile in db_profiles:
                    profile_found = False
                    for new_profile in data[key]:
                        if new_profile['name'] == profile['name']:
                            profile_found = True
                            
                    if not profile_found:
                        # Check if we can delete the software profile
                        # (the software profile is not in use)
                        logger.debug("Try to delete: %s - %s"%(str(profile['_id']), profile['name']))
                        obj_related_list = "policies.%s.object_related_list"%(str(sp_policy['_id']))
                        profile_id = str(profile['_id'])
                        nnodes = request.db.nodes.find({obj_related_list : profile_id}).count()
                        logger.debug("Found %s nodes"%(nnodes))
                        
                        if nnodes == 0:
                            # It it's not used we can delete it
                            collection.remove({"_id": profile['_id']})
                        else:
                            # It's used, so we can't delete it
                            messages.created_msg(request, _('Software Profile in use: %s')%(profile['name']), 'warning')
                            response.write('SUCCESS')
                            return response
                        
                        
                        
    messages.created_msg(request, _('Settings modified successfully'), 'success')
    response.write('SUCCESS')
    return response
Пример #49
0
def report_permission(context, request, file_ext):
    '''
    Generate a report with all the admin permissions.
    
    Args:

    Returns:
        headers (list) : The headers of the table to export
        rows (list)    : Rows with the report data
        widths (list)  : The witdhs of the columns of the table to export
        page           : Translation of the word "page" to the current language
        of             : Translation of the word "of" to the current language
        report_type    : Type of report (html, csv or pdf)
    '''    

    items = []
    total_ous = []
    vmark_html = "<div class='centered'><img alt=\"OK\" src='/static/images/checkmark.jpg'/></div>"
    xmark_html = "<div class='centered'><img alt=\"NOK\" src='/static/images/xmark.jpg'/></div>"

    # Get all admins
    admins = request.db.adminusers.find()

    for admin in admins:
        ou_readonly = admin.get('ou_readonly', [])
        ou_availables = admin.get('ou_availables', [])
        ou_remote = admin.get('ou_remote', [])
        ou_managed = admin.get('ou_managed', [])
        admin_ous = set(ou_readonly + ou_availables + ou_remote + ou_managed)
        total_ous += admin_ous

        for ou in admin_ous:
            item = {}
            item['_id'] = str(admin['_id'])
            item['username'] = admin['username']
            item['OU'] = ou
            item['email'] = admin['email']
            item['name'] = admin['first_name']+" "+admin['last_name']

            if file_ext == 'csv':
                item['readonly'] = _('Yes') if ou in ou_readonly else _('No')
                item['link'] = _('Yes') if ou in ou_availables else _('No')
                item['remote'] = _('Yes') if ou in ou_remote else _('No')
                item['managed'] = _('Yes') if ou in ou_managed else _('No')
            else:
                item['readonly'] = vmark_html if ou in ou_readonly else xmark_html
                item['link'] = vmark_html if ou in ou_availables else xmark_html
                item['remote'] =  vmark_html if ou in ou_remote else xmark_html
                item['managed'] = vmark_html if ou in ou_managed else xmark_html
            items.append(item)

    logger.debug("report_permission: items = {}".format(items))
            
    # Get all OU names
    ids = map(lambda x: ObjectId(x), total_ous)
    result = request.db.nodes.find({'_id': {'$in': ids}},{'_id':1, 'path':1})
    ou_paths = {}

    for r in result:
        path = r['path']+','+str(r['_id'])
        ou_paths.update({str(r['_id']): get_complete_path(request.db, path)})

    logger.debug("report_permission: ou_paths = {}".format(ou_paths))

    rows = []

    for item in items:    
        row = []
        item['OU'] = ou_paths.get(item['OU'], item['OU'])

        if file_ext == 'pdf':
            row.append(item['username']+"<br/>"+item['email'])
            row.append(item['OU'])
            row.append(treatment_string_to_pdf(item, 'readonly', 80))
            row.append(treatment_string_to_pdf(item, 'link', 80))
            row.append(treatment_string_to_pdf(item, 'remote', 80))
            row.append(treatment_string_to_pdf(item, 'managed', 80))
        else:
            row.append(treatment_string_to_csv(item, 'username'))
            row.append(treatment_string_to_csv(item, 'email'))
            row.append(treatment_string_to_csv(item, 'name'))
            row.append(treatment_string_to_csv(item, 'OU'))
            row.append(treatment_string_to_csv(item, 'readonly'))
            row.append(treatment_string_to_csv(item, 'link'))
            row.append(treatment_string_to_csv(item, 'remote'))
            row.append(treatment_string_to_csv(item, 'managed'))

        rows.append(row)
                
    if file_ext == 'pdf':
        header = (_(u'Username and Email').encode('utf-8'),
                  _(u'Organizational Unit').encode('utf-8'),
                  _(u'Read Only').encode('utf-8'),
                  _(u'Link').encode('utf-8'),
                  _(u'Remote').encode('utf-8'),
                  _(u'Manage').encode('utf-8'))
    else:
        header = (_(u'Username').encode('utf-8'),
                  _(u'Email').encode('utf-8'),
                  _(u'Name').encode('utf-8'),
                  _(u'Organizational Unit').encode('utf-8'),
                  _(u'Read Only').encode('utf-8'),
                  _(u'Link').encode('utf-8'),
                  _(u'Remote').encode('utf-8'),
                  _(u'Manage').encode('utf-8'))

    # Column widths in percentage
    if file_ext == 'pdf':
        widths = (36, 36, 7, 7, 7, 7)
    else:
        widths = (20, 20, 20, 20, 20, 10, 10, 10, 10)

    now = datetime.datetime.now().strftime("%d/%m/%Y %H:%M")

    title = _(u'Permissions report')
        
    return {'headers': header,
            'rows': rows,
            'widths': widths,
            'report_title': title,
            'page': _(u'Page').encode('utf-8'),
            'of': _(u'of').encode('utf-8'),
            'report_type': file_ext,
            'now': now}
Пример #50
0
def report_user(context, request, file_ext):
    '''
    Generate a report with all the users that belongs to an OU.
    If the administrator is a superadmin the generated report will contain 
    all the users in the database. 
    
    Args:
        ou_id (string) : ID of the OU.

    Returns:
        headers (list) : The headers of the table to export
        rows (list)    : Rows with the report data
        widths (list)  : The witdhs of the columns of the table to export
        page           : Translation of the word "page" to the current language
        of             : Translation of the word "of" to the current language
        report_type    : Type of report (html, csv or pdf)
    '''    

    # Check current user permissions
    ou_id = check_visibility_of_ou(request)
    if ou_id is None:
        raise HTTPBadRequest()

    # Get user data
    query = request.db.nodes.find(
            {'type': 'user','path': get_filter_nodes_belonging_ou(ou_id)})
  
    rows = []

    if file_ext == 'pdf':
        rows = [('&nbsp;'+item['name'],
                 '&nbsp;'+item['first_name']+" "+item['last_name'],
                 '&nbsp;'+item['email'],
                 '&nbsp;'+item['phone'],
                 '&nbsp;'+item['address'],
                 '&nbsp;'+str(item['_id'])) for item in query]
    else:
        rows = [(treatment_string_to_csv(item, 'name') if file_ext == 'csv' else get_html_node_link(item),
                treatment_string_to_csv(item, 'first_name'),
                treatment_string_to_csv(item, 'last_name'),
                treatment_string_to_csv(item, 'email'),
                treatment_string_to_csv(item, 'phone'),
                treatment_string_to_csv(item, 'address'),
                str(item['_id'])) for item in query]

    if file_ext == 'pdf':
        header = (u'Username',
                  u'Name',
                  u'Email',
                  u'Phone',
                  u'Address',
                  u'ID')
    else:
        header = (_(u'Username').encode('utf-8'),
                  _(u'First name').encode('utf-8'),
                  _(u'Last name').encode('utf-8'),
                  _(u'Email').encode('utf-8'),
                  _(u'Phone').encode('utf-8'),
                  _(u'Address').encode('utf-8'),
                  _(u'Id').encode('utf-8'))
    
    # Column widths in percentage
    if file_ext == 'pdf':
        widths = (15, 15, 25, 10, 15, 20)
    else:
        widths = (15, 25, 10, 10, 5, 20, 15)

    title =  _(u'Users report')
    now = datetime.datetime.now().strftime("%d/%m/%Y %H:%M")
        
    return {'headers': header,
            'rows': rows,
            'widths': widths,
            'report_title': title,
            'page': _(u'Page').encode('utf-8'),
            'of': _(u'of').encode('utf-8'),
            'report_type': file_ext,
            'now': now}
Пример #51
0
def report_audit(context, request, file_ext):
    '''
    Generate audit log for user information tracking
    
    Args:

    Returns:
        headers (list) : The headers of the table to export
        rows (list)    : Rows with the report data
        widths (list)  : The witdhs of the columns of the table to export
        page           : Translation of the word "page" to the current language
        of             : Translation of the word "of" to the current language
        report_type    : Type of report (html, csv or pdf)
    '''    

    rows = []

    # Getting audit logs
    items = request.db.auditlog.find()

    for item in items:
        row = []
        # Converts timestamp to date
        item['date']  =datetime.datetime.fromtimestamp(item['timestamp']).strftime('%d/%m/%Y %H:%M:%S')

        if file_ext == 'pdf':
            row.append(treatment_string_to_pdf(item, 'action', 10))
            row.append(treatment_string_to_pdf(item, 'username', 15))
            row.append(treatment_string_to_pdf(item, 'ipaddr', 20))
            row.append(item['user-agent'])#treatment_string_to_pdf(item, 'user-agent',100))
            row.append(treatment_string_to_pdf(item, 'date', 80))
        else:
            row.append(treatment_string_to_csv(item, 'action'))
            row.append(treatment_string_to_csv(item, 'username'))
            row.append(treatment_string_to_csv(item, 'ipaddr'))
            row.append(treatment_string_to_csv(item, 'user-agent'))
            row.append(treatment_string_to_csv(item, 'date'))

        rows.append(row)
                
    
    header = (_(u'Action').encode('utf-8'),
              _(u'Username').encode('utf-8'),
              _(u'IP Address').encode('utf-8'),
              _(u'User Agent').encode('utf-8'),
              _(u'Date').encode('utf-8'))
    
    # Column widths in percentage
    widths = (10, 15, 20, 40, 15)
    title =  _(u'Audit report')

    now = datetime.datetime.now().strftime("%d/%m/%Y %H:%M")

    return {'headers': header,
            'rows': rows,
            'widths': widths,
            'report_title': title,
            'page': _(u'Page').encode('utf-8'),
            'of': _(u'of').encode('utf-8'),
            'report_type': file_ext,
            'now': now}
Пример #52
0
    def __init__(self, schema, request, *args, **kwargs):
        self.request = request
        buttons = (GecosButton(title=_('Submit'),
                               css_class='deform-maintenance-submit'),)

        super(MaintenanceForm, self).__init__(schema, buttons=buttons, *args, **kwargs)
Пример #53
0
    def get(self):
        result = super(ComputerResource, self).get()
        node_collection = self.request.db.nodes
        
        if not result.get('node_chef_id', None):
            return result
        
        logger.info("/api/computers/: node_chef_id: %s" % (str(result.get('node_chef_id', None))))

        try:
            api = get_chef_api(self.request.registry.settings, self.request.user)
            computer_node = ChefNode(result['node_chef_id'], api)
            ohai = to_deep_dict(computer_node.attributes)
            nodeid = result.get('_id',None)
            usernames = [i['username'] for i in ohai.get('ohai_gecos', {}).get('users', [])]
            users = list(node_collection.find({
                "$and": [
                    { "$or": [{"name": {"$in": usernames}}] }, 
                    { "type":"user"},
                    { "computers": {"$elemMatch": {"$eq": ObjectId(nodeid)}}}
                 ]
            },{'_id':1,'name':1,'path':1}))
            # ObjectId to string for JSON serialize
            [d.update({'_id': str(d['_id'])}) for d in users]
            
            # Create a list of users that provides at least one user policy to this computer
            users_inheritance_pre = list(node_collection.find({
                "$and": [
                    { "$or": [{"name": {"$in": usernames}}] }, 
                    { "type":"user"},
                    { "computers": {"$elemMatch": {"$eq": ObjectId(nodeid)}}}
                 ]
            },{'_id':1,'name':1,'path':1, 'inheritance': 1}))
            [d.update({'_id': str(d['_id'])}) for d in users_inheritance_pre]

            users_inheritance = []
            for usr_inh in users_inheritance_pre:
                if 'inheritance' in usr_inh:
                    policies_list = get_inheritance_tree_policies_list(usr_inh['inheritance'], [])
                    if len(policies_list) > 0:
                        users_inheritance.append(usr_inh)
            
            
            cpu = ohai.get('cpu', {}).get('0', {})
            dmi = ohai.get('dmi', {})
            
            # debug_mode flag for logs tab
            debug_mode = False
            try:
                debug_mode = computer_node.attributes.get_dotted(DEBUG_MODE_ENABLE_ATTR_PATH)
            except KeyError:
                pass
            
            # Get logs info
            logs_data = node_collection.find_one({"type": "computer", "_id": ObjectId(nodeid)}, {"logs": True})
            logs = {}
            if logs_data is not None and 'logs' in logs_data:
                logs_data = logs_data['logs']
                
                date_format = locale.nl_langinfo(locale.D_T_FMT)
                date = datetime.datetime(*map(int, re.split('[^\d]', logs_data['date'])[:-1]))
                localename = locale.normalize(get_current_request().locale_name+'.UTF-8')
                logger.debug("/api/computers/: localename: %s" % (str(localename)))
                locale.setlocale(locale.LC_TIME, localename)
                logs['date'] = date.strftime(date_format)
                logger.debug("/api/computers/: date: %s" % (str(logs['date'])))
                
                logs['files'] = logs_data['files']
                for filedata in logs_data['files']:
                    # Do not send file contents
                    del filedata['content']
            
            # Get Help Channel info
            help_channel_enabled = True
            helpchannel_data = self.request.db.helpchannel.find(
                {"computer_node_id" : result['node_chef_id']}).sort(
                    [("last_modified", pymongo.DESCENDING)]).limit(6)
            helpchannel = {}
            helpchannel['current'] = None
            helpchannel['last'] = []
            if helpchannel_data is not None:
                c = 0
                for hcdata in helpchannel_data:
                    # Format date
                    date_format = locale.nl_langinfo(locale.D_T_FMT)
                    logger.info("last_modified: {0}".format( hcdata['last_modified']))
                    last_mod = re.split('[^\d]', str(hcdata['last_modified']))
                    logger.info("last_mod: {0}".format(last_mod))

                    date = datetime.datetime(*map(int, last_mod[:-2]))
                    localename = locale.normalize(get_current_request().locale_name+'.UTF-8')
                    logger.debug("/api/computers/: localename: %s" % (str(localename)))
                    locale.setlocale(locale.LC_TIME, localename)
                    hcdata['last_modified'] = date.strftime(date_format)
                    
                    if hcdata['user_node_id']:
                        # Format user
                        user_data = node_collection.find_one({"type": "user", "_id": ObjectId(hcdata['user_node_id'])})
                        if user_data:
                            hcdata['user'] = user_data['name']
                        else:
                            logger.error("User not found: {0}".format(hcdata['user_node_id']))
                    else:
                        hcdata['user'] = ''
                    
                    if hcdata['adminuser_id']:
                        # Format user
                        user_data = self.request.db.adminusers.find_one({"_id": ObjectId(hcdata['adminuser_id'])})
                        if user_data:
                            hcdata['admin'] = user_data['username']
                        else:
                            logger.error("Admin user not found: {0}".format(hcdata['adminuser_id']))
                    else:
                        hcdata['admin'] = ''
                        
                    # Translate status info
                    hcdata['status'] = _('Unknown status')
                    if hcdata['action'] == 'request':
                        hcdata['status'] = _('User is requesting support')
                    elif hcdata['action'] == 'accepted':
                        hcdata['status'] = _('User is requesting support')
                    elif hcdata['action'] == 'finished user':
                        hcdata['status'] = _('Terminated by user')
                    elif hcdata['action'] == 'finished tech':
                        hcdata['status'] = _('Terminated by technician')
                    elif hcdata['action'] == 'finished error':
                        hcdata['status'] = _('Terminated because of a communication error')
                    elif hcdata['action'] == 'giving support':
                        hcdata['status'] = _('The technician is giving support to the user')
                        
                        
                    hcdata['_id'] = str(hcdata['_id'])                
                    
                    if (c==0 and hcdata['action']=='accepted'):
                        helpchannel['current'] = hcdata
                    else:
                        helpchannel['last'].append(hcdata)
                    
                    c = c + 1
           
            
            result.update({'ohai': ohai,
                           'users': users, # Users related with this computer
                           'users_inheritance': users_inheritance, # Users related with this computer that provides at least one user policy
                           'uptime': ohai.get('uptime', ''),
                           #'gcc_link': ohai.get('gcc_link',True),
                           'ipaddress': ohai.get('ipaddress', ''),
                           'cpu': '%s %s' % (cpu.get('vendor_id', ''), cpu.get('model_name', '')),
                           'product_name': dmi.get('system', {}).get('product_name', ''),
                           'manufacturer': dmi.get('system', {}).get('manufacturer', ''),
                           'ram': ohai.get('memory', {}).get('total', ''),
                           'lsb': ohai.get('lsb', {}),
                           'kernel': ohai.get('kernel', {}),
                           'filesystem': ohai.get('filesystem', {}),
                           'debug_mode': debug_mode,
                           'logs': logs,
                           'helpchannel': helpchannel,
                           'help_channel_enabled': help_channel_enabled
                           })
        except (urllib2.URLError, ChefError, ChefServerError):
            pass
        return result
Пример #54
0
def report_status(context, request, file_ext):
    '''
    Generate a report with all the users that belongs to an OU.
    If the administrator is a superadmin the generated report will contain 
    all the users in the database. 
    
    Args:
        ou_id (string) : ID of the OU.

    Returns:
        headers (list) : The headers of the table to export
        rows (list)    : Rows with the report data
        widths (list)  : The witdhs of the columns of the table to export
        page           : Translation of the word "page" to the current language
        of             : Translation of the word "of" to the current language
        report_type    : Type of report (html, csv or pdf)
    '''    

    # Check current user permissions
    ou_id = check_visibility_of_ou(request)
    if ou_id is None:
        raise HTTPBadRequest()
    
    # Get user data
    query = request.db.nodes.find(
        {'type': 'computer','path': get_filter_nodes_belonging_ou(ou_id)}).sort('last_agent_run_time', -1)
  
    rows = []

    current_time = int(time.time())
    logger.debug("report_status: current_time = {}".format(current_time))

    # update_error_interval: Hours. Converts it to seconds
    update_error_interval = timedelta(hours=int(get_current_registry().settings.get('update_error_interval', 24))).seconds
    logger.debug("report_status: update_error_interval = {}".format(update_error_interval))
    
    # gecos-agent runs every 60 minutes (cron resource: minutes 30)
    # See https://github.com/gecos-team/gecos-workstation-management-cookbook/blob/master/recipes/default.rb (line: 57)
    # 10-min max delay margin of chef-client concurrent executions
    # See https://github.com/gecos-team/gecosws-agent/blob/trusty/scripts/gecos-chef-client-wrapper (line: 30)
    # 15-min delay margin of network or chef-client execution
    # 60 + 10 + 15 = 85
    delay_margin = timedelta(minutes=85).seconds

    for item in query:
        row = []

        last_agent_run_time = int(item.get('last_agent_run_time',0))
        logger.debug("report_status: last_agent_run_time = {}".format(last_agent_run_time))

        if last_agent_run_time + delay_margin >= current_time:
            item['status'] = '<div class="centered" style="width: 100%"><img alt="OK" src="/static/images/checkmark.jpg"/></div>' \
                             if file_ext != 'csv' else 'OK'

        # Chef-run error or update_error_interval hours has elapsed from last agent run time
        elif (item['error_last_chef_client'] or
            last_agent_run_time + update_error_interval >= current_time
        ):
            item['status'] = '<div class="centered" style="width: 100%"><img alt="ERROR" src="/static/images/xmark.jpg"/></div>' \
                             if file_ext != 'csv' else 'ERROR'

        # delay_margin < last_agent_run_time < update_error_interval
        else:
            item['status'] = '<div class="centered" style="width: 100%"><img alt="WARN" src="/static/images/alertmark.jpg"/></div>' \
                             if file_ext != 'csv' else 'WARN'
        

        if file_ext == 'pdf':
            row.append(treatment_string_to_pdf(item, 'name', 20))
            row.append(item['_id'])

            if last_agent_run_time != 0:
                row.append(datetime.utcfromtimestamp(last_agent_run_time).strftime('%Y-%m-%d %H:%M:%S'))
            else:
                row.append(' -- ')

            row.append(item['status'])
        else:
            if file_ext == 'csv':
                row.append(treatment_string_to_csv(item, 'name'))
            else:
                row.append(get_html_node_link(item))
                row.append(item['_id'])
            if last_agent_run_time != 0:
                row.append(datetime.utcfromtimestamp(last_agent_run_time).strftime('%Y-%m-%d %H:%M:%S'))
            else:
                row.append('--')
            row.append(treatment_string_to_csv(item, 'status'))

        rows.append(row)
        
                
    header = (_(u'Name').encode('utf-8'),
              _(u'Id').encode('utf-8'),
              _(u'Agent last runtime').encode('utf-8'),
              _(u'Status').encode('utf-8'))

    # Column widths in percentage
    if file_ext == 'pdf':
        widths = (45, 20, 20, 15)
    else:
        widths = (15, 35, 15, 20)

    title =  _(u'Computer with anomalies')

    now = datetime.now().strftime("%d/%m/%Y %H:%M")

    return {'headers': header,
            'rows': rows,
            'widths': widths,
            'report_title': title,
            'page': _(u'Page').encode('utf-8'),
            'of': _(u'of').encode('utf-8'),
            'report_type': file_ext,
            'now': now}
Пример #55
0
def report_computer(context, request, file_ext):
    '''
    Generate a report with all the computers that belongs to an OU.
    If the administrator is a superadmin the generated report will contain 
    all the computers in the database. 

    
    Args:
        ou_id (string) : ID of the OU.

    Returns:
        headers (list) : The headers of the table to export
        rows (list)    : Rows with the report data
        widths (list)  : The witdhs of the columns of the table to export
        page           : Translation of the word "page" to the current language
        of             : Translation of the word "of" to the current language
        report_type    : Type of report (html, csv or pdf)
    '''    

    # Check current user permissions
    ou_id = check_visibility_of_ou(request)
    if ou_id is None:
        raise HTTPBadRequest()

    # Get user data
    query = request.db.nodes.find(
            {'type': 'computer', 'path': get_filter_nodes_belonging_ou(ou_id)})

    if file_ext == 'pdf':
        rows = [(treatment_string_to_pdf(item, 'name', 20),
                 treatment_string_to_pdf(item, 'family', 10),
                 treatment_string_to_pdf(item, 'registry', 10),
                 treatment_string_to_pdf(item, 'serial', 15),
                 #treatment_string_to_pdf(item, 'node_chef_id', 25),
                 item['_id']) for item in query]
    else:
        rows = [(treatment_string_to_csv(item, 'name') if file_ext == 'csv' else get_html_node_link(item),
                 treatment_string_to_csv(item, 'family'),
                 treatment_string_to_csv(item, 'registry'),
                 treatment_string_to_csv(item, 'serial'),
                 #treatment_string_to_csv(item, 'node_chef_id'),
                 item['_id']) for item in query]
    
    header = (_(u'Name').encode('utf-8'),
              _(u'Type').encode('utf-8'),
              _(u'Registry number').encode('utf-8'),
              _(u'Serial number').encode('utf-8'),
              #_(u'Node chef id').encode('utf-8'),
              _(u'Id').encode('utf-8'))
    
    # Column widths in percentage
    widths = (20, 20, 20, 20, 20)
    title =  _(u'Computers report')
    now = datetime.datetime.now().strftime("%d/%m/%Y %H:%M")
        
    return {'headers': header,
            'rows': rows,
            'widths': widths,
            'report_title': title,
            'page': _(u'Page').encode('utf-8'),
            'of': _(u'of').encode('utf-8'),
            'report_type': file_ext,
            'now': now}
Пример #56
0
 def save(self, upload):
     self.created_msg(_('Restore cookbook.'))
Пример #57
0
def report_storages(context, request, file_ext):
    '''
    Generate a report with all the storages and its related users.

    
    Args:
        ou_id (string) : ID of the OU.

    Returns:
        headers (list) : The headers of the table to export
        rows (list)    : Rows with the report data
        widths (list)  : The witdhs of the columns of the table to export
        page           : Translation of the word "page" to the current language
        of             : Translation of the word "of" to the current language
        report_type    : Type of report (html, csv or pdf)
    '''    

    # Check current user permissions
    ou_id = check_visibility_of_ou(request)
    if ou_id is None:
        raise HTTPBadRequest()
 
    # Get storages policy
    policy = request.db.policies.find_one({'slug': 'storage_can_view'})
    property_name = 'policies.' + str(policy['_id']) + '.object_related_list'
    
    # Get all storages
    query = request.db.nodes.find(
        {'type': 'storage','path': get_filter_nodes_belonging_ou(ou_id)})

    rows = []
    if file_ext == 'pdf':
        for item in query:
            row = []
            # No path in PDF because it's too long
            row.append('--')
            row.append(item['name'])
            row.append(item['uri'])
            row.append(item['_id'])
            
            # Get all nodes related with this storage
            nodes_query = request.db.nodes.find({property_name: str(item['_id'])})
            # Targets: ou, group or user
            users = []
            for node in nodes_query:
                if node['type'] == 'ou':
                    users = list(request.db.nodes.find(
                                    {'path': get_filter_nodes_belonging_ou(node['_id']),
                                    'type': 'user'}))
                elif node['type'] == 'group':
                    users = list(request.db.nodes.find(
                                    {'_id': node['members'], 
                                    'type': 'user'}))
                elif node['type'] == 'user':
                    users = [node]
                
            if len(users) == 0:
                row.append('--')
                row.append('--')                
                rows.append(row)
            else:
                for user in users:
                    user_row = list(row)
                    user_row.append(user['name'])
                    # No path in PDF because it's too long
                    user_row.append('--')
                    rows.append(user_row)

            
    else:
        for item in query:
            row = []
            item['complete_path'] = get_complete_path(request.db, item['path'])
            row.append(treatment_string_to_csv(item, 'complete_path'))
            if file_ext == 'csv':
                row.append(treatment_string_to_csv(item, 'name'))
            else: # html links
                row.append(get_html_node_link(item))
            row.append(treatment_string_to_csv(item, 'uri'))
            row.append(item['_id'])
            
            # Get all nodes related with this printer
            nodes_query = request.db.nodes.find({property_name: str(item['_id'])})
            # Targets: ou, group or user
            users = []
            for node in nodes_query:
                if node['type'] == 'ou':
                    users = list(request.db.nodes.find(
                                    {'path': get_filter_nodes_belonging_ou(node['_id']),
                                    'type': 'user'}))
                elif node['type'] == 'group':
                    users = list(request.db.nodes.find(
                                    {'_id': node['members'], 
                                    'type': 'user'}))
                elif node['type'] == 'user':
                    users = [node]
                
            if len(users) == 0:
                row.append('--')
                rows.append(row)
            else:
                for user in users:
                    user_row = list(row)
                    if file_ext == 'csv':
                        user_row.append(treatment_string_to_csv(user, 'name'))
                    else: # html links
                        user_row.append(get_html_node_link(user))
                    user['complete_path'] = get_complete_path(request.db, item['path'])
                    rows.append(user_row)
        
    
    header = (_(u'Path').encode('utf-8'),
              _(u'Name').encode('utf-8'),
              _(u'Uri').encode('utf-8'),
              _(u'Id').encode('utf-8'),
              _(u'User').encode('utf-8'))
    
    # Column widths in percentage
    widths = (0, 20, 45, 15, 20, 0)
    title =  _(u'Storages and related users report')
    now = datetime.datetime.now().strftime("%d/%m/%Y %H:%M")
        
    return {'headers': header,
            'rows': rows,
            'widths': widths,
            'report_title': title,
            'page': _(u'Page').encode('utf-8'),
            'of': _(u'of').encode('utf-8'),
            'report_type': file_ext,
            'now': now}
Пример #58
0
import pyramid

from bson import ObjectId
from bson.objectid import InvalidId
from colander import null
from copy import copy

from deform.widget import FileUploadWidget, _normalize_choices, SelectWidget
from gecoscc.i18n import gettext_lazy as _
from gecoscc.i18n import gettext                                
from gecoscc.utils import get_items_ou_children, getNextUpdateSeq, get_chef_api, get_cookbook
from pyramid.threadlocal import get_current_registry

OU_ORDER = 1
UPDATE_STRUCTURE = ['control', 'cookbook/', 'scripts/']
PERMISSIONS = (('READONLY', _('read')),
               ('MANAGE', _('manage')),
               ('LINK', _('link')),
               ('REMOTE', _('remote')))

class MemoryTmpStore(dict):

    def preview_url(self, _name):
        return None

filestore = MemoryTmpStore()


class MyModel(object):
    pass
Пример #59
0
 def save(self, ous_managed):
     self.collection.update({'username': self.username},
                            {'$set': ous_managed})
     self.created_msg(_('User edited successfully'))
Пример #60
0
 def __init__(self, schema, collection, username, request, *args, **kwargs):
     schema.get('ou_managed').title += '<p><a href="#ou-managed" class="add-another">%s</a></p>' % _('Add another')
     schema.get('ou_availables').title += '<p><a href="#ou-availables" class="add-another">%s</a></p>' % _('Add another')
     schema.children.append(self.ou_managed_count)
     schema.children.append(self.ou_availables_count)
     super(AdminUserOUManageForm, self).__init__(schema, collection=collection,
                                                 username=username, request=request,
                                                 *args, **kwargs)