def get_entities_for_reindex(tags): """Collect entities for theses tags.""" if isinstance(tags, Tag): tags = (tags,) session = db.session() indexing = get_service("indexing") tbl = Entity.__table__ tag_ids = [t.id for t in tags] query = ( sa.sql.select([tbl.c.entity_type, tbl.c.id]) .select_from(tbl.join(entity_tag_tbl, entity_tag_tbl.c.entity_id == tbl.c.id)) .where(entity_tag_tbl.c.tag_id.in_(tag_ids)) ) entities = set() with session.no_autoflush: for entity_type, entity_id in session.execute(query): if entity_type not in indexing.adapted: logger.debug("%r is not indexed, skipping", entity_type) item = ("changed", entity_type, entity_id, ()) entities.add(item) return entities
def is_admin(group): security = get_service("security") is_admin = current_user in group.admins if not is_admin and "security" in current_app.extensions: is_admin = security.has_role(current_user, "admin") return is_admin
def url_value_preprocess(self, endpoint, view_args): model_name = view_args.pop("Model", None) group = view_args.pop("group", _MARKER) if group == "_": # "General" group group = "" if group is not _MARKER: view_args["group"] = group if model_name is not None: svc = get_service("vocabularies") Model = svc.get_vocabulary(name=model_name, group=group) g.breadcrumb.append( BreadcrumbItem( label=Model.Meta.group if group else _("Global"), url=url_for(".vocabularies_group", group=group or "_"), )) g.breadcrumb.append( BreadcrumbItem( label=Model.Meta.label, url=url_for(".vocabularies_model", group=group or "_", Model=Model.Meta.name), )) view_args["Model"] = Model
def get_attachments_from_dms(community): index_service = get_service("indexing") filters = wq.And( [ wq.Term("community_id", community.id), wq.Term("object_type", Document.entity_type), ] ) sortedby = whoosh.sorting.FieldFacet("created_at", reverse=True) documents = index_service.search("", filter=filters, sortedby=sortedby, limit=50) attachments = [] for doc in documents: url = url_for(doc) attachment = Attachment( url, doc["name"], doc["owner_name"], doc["created_at"], doc.get("content_length"), doc.get("content_type", ""), ) attachments.append(attachment) return attachments
def get_results(self, q, *args, **kwargs): svc = get_service("indexing") search_kwargs = {"limit": 50, "Models": (self.Model, )} results = svc.search(q, **search_kwargs) itemkey = None try: # 'nom' doesn't always exist but for Contacts, sorting on # the last name ('nom') feels more natural than 'name', # which starts with the first name ('prenom'). if not results.is_empty(): res = results[0] fields = res.fields() if "nom" in fields: itemkey = "nom" elif "name" in fields: itemkey = "name" if itemkey: results.sort(key=lambda it: it.fields().get(itemkey)) except Exception: if itemkey is not None: msg = "we could not sort whoosh results on fields' key {}.".format( itemkey) logger.warning(msg) return results
def can_edit(user): security = get_service("security") if not security: return True # TODO: introduce a "self" role? return (user == current_user) or security.has_role(current_user, "admin")
def url_value_preprocess(self, endpoint, view_args): Model = view_args.pop('Model', None) group = view_args.pop('group', _MARKER) if group == '_': # "General" group group = None if group is not _MARKER: view_args['group'] = group if Model is not None: svc = get_service('vocabularies') Model = svc.get_vocabulary(name=Model, group=group) g.breadcrumb.append(BreadcrumbItem( label=Model.Meta.group if group else _('Global'), url=url_for('.vocabularies_group', group=group or '_'), )) g.breadcrumb.append( BreadcrumbItem( label=Model.Meta.label, url=url_for( '.vocabularies_model', group=group or '_', Model=Model.Meta.name, ), ), ) view_args['Model'] = Model
def data(self, *args, **kw) -> Dict: security = get_service("security") length = int(kw.get("iDisplayLength", 0)) start = int(kw.get("iDisplayStart", 0)) sort_dir = kw.get("sSortDir_0", "asc") echo = int(kw.get("sEcho", 0)) search = kw.get("sSearch", "").replace("%", "").strip().lower() end = start + length # pyre-fixme[16]: `Group` has no attribute `query`. query = Group.query.options(sa.orm.noload("*")) total_count = query.count() if search: # TODO: gérer les accents query = query.filter( func.lower(Group.name).like("%" + search + "%")) count = query.count() columns = [func.lower(Group.name)] direction = asc if sort_dir == "asc" else desc order_by = list(map(direction, columns)) # sqlite does not support 'NULLS FIRST|LAST' in ORDER BY clauses # pyre-fixme[16]: `Group` has no attribute `__mapper__`. engine = query.session.get_bind(Group.__mapper__) if engine.name != "sqlite": order_by[0] = nullslast(order_by[0]) query = query.order_by(*order_by).add_columns(Group.members_count) groups = query.slice(start, end).all() data = [] for group, members_count in groups: # TODO: this should be done on the browser. group_url = url_for(".groups_group", group_id=group.id) name = html.escape(group.name or "") # pyre-fixme[16]: `Service` has no attribute `get_roles`. roles = [r for r in security.get_roles(group) if r.assignable] columns = [ f'<a href="{group_url}">{name}</a>', str(members_count or 0), render_template_string( """{%- for role in roles %} <span class="badge badge-default">{{ role }}</span> {%- endfor %}""", roles=roles, ), "\u2713" if group.public else "", ] data.append(columns) return { "sEcho": echo, "iTotalRecords": total_count, "iTotalDisplayRecords": count, "aaData": data, }
def data(self, *args, **kw): security = get_service('security') length = int(kw.get("iDisplayLength", 0)) start = int(kw.get("iDisplayStart", 0)) sort_dir = kw.get("sSortDir_0", "asc") echo = int(kw.get("sEcho", 0)) search = kw.get("sSearch", "").replace("%", "").strip().lower() end = start + length query = Group.query \ .options(sa.orm.noload('*')) total_count = query.count() if search: # TODO: gérer les accents query = query.filter( func.lower(Group.name).like("%" + search + "%"), ) count = query.count() columns = [func.lower(Group.name)] direction = asc if sort_dir == 'asc' else desc order_by = list(map(direction, columns)) # sqlite does not support 'NULLS FIRST|LAST' in ORDER BY clauses engine = query.session.get_bind(Group.__mapper__) if engine.name != 'sqlite': order_by[0] = nullslast(order_by[0]) query = query.order_by(*order_by) \ .add_columns(Group.members_count) groups = query.slice(start, end).all() data = [] for group, members_count in groups: # TODO: this should be done on the browser. group_url = url_for(".groups_group", group_id=group.id) name = escape(getattr(group, "name") or "") roles = [r for r in security.get_roles(group) if r.assignable] columns = [ '<a href="{url}">{name}</a>'.format(url=group_url, name=name), text_type(members_count or 0), render_template_string( '''{%- for role in roles %} <span class="badge badge-default">{{ role }}</span> {%- endfor %}''', roles=roles, ), '\u2713' if group.public else '', ] data.append(columns) return { "sEcho": echo, "iTotalRecords": total_count, "iTotalDisplayRecords": count, "aaData": data, }
def data(self, q="", page=None, *args, **kwargs): if not q: q = "" svc = get_service("indexing") url_for_hit = svc.app_state.url_for_hit search_kwargs = {"facet_by_type": 5} response = {} results = svc.search(q, **search_kwargs) datasets = {} for typename, docs in results.items(): dataset = [] for doc in docs: # Because it happens sometimes try: name = doc["name"] except KeyError: continue d = {"name": name} url = url_for_hit(doc, None) if url is not None: d["url"] = url dataset.append(d) datasets[typename] = dataset response["results"] = datasets return response
def get_results(self, q, *args, **kwargs): svc = get_service("indexing") search_kwargs = {"limit": 50, "Models": (self.Model,)} results = svc.search(q, **search_kwargs) itemkey = None try: # 'nom' doesn't always exist but for Contacts, sorting on # the last name ('nom') feels more natural than 'name', # which starts with the first name ('prenom'). if not results.is_empty(): res = results[0] fields = res.fields() if "nom" in fields: itemkey = "nom" elif "name" in fields: itemkey = "name" if itemkey: results.sort(key=lambda it: it.fields().get(itemkey)) except Exception: if itemkey is not None: msg = "we could not sort whoosh results on fields' key {}.".format( itemkey ) logger.warning(msg) return results
def get_entities_for_reindex(tags): """Collect entities for theses tags.""" if isinstance(tags, Tag): tags = (tags, ) session = db.session() indexing = get_service("indexing") tbl = Entity.__table__ tag_ids = [t.id for t in tags] query = (sa.sql.select([tbl.c.entity_type, tbl.c.id]).select_from( tbl.join(entity_tag_tbl, entity_tag_tbl.c.entity_id == tbl.c.id)).where( entity_tag_tbl.c.tag_id.in_(tag_ids))) entities = set() with session.no_autoflush: for entity_type, entity_id in session.execute(query): if entity_type not in indexing.adapted: logger.debug("%r is not indexed, skipping", entity_type) item = ("changed", entity_type, entity_id, ()) entities.add(item) return entities
def content(self): obj = self.current_obj index_service = get_service("indexing") index = index_service.app_state.indexes["default"] schema = index.schema context = self.context.copy() context["schema"] = schema context["sorted_fields"] = sorted(schema.names()) adapter = index_service.adapted.get(fqcn(obj.__class__)) if adapter and adapter.indexable: doc = context["current_document"] = index_service.get_document( obj, adapter) indexed = {} for name, field in schema.items(): value = doc.get(name) indexed[name] = None if value and field.analyzer and field.format: indexed[name] = list(field.process_text(value)) context["current_indexed"] = indexed context["current_keys"] = sorted(set(doc) | set(indexed)) with index.searcher() as search: document = search.document(object_key=obj.object_key) sorted_keys = sorted(document) if document is not None else None context.update({"document": document, "sorted_keys": sorted_keys}) jinja_env = current_app.jinja_env jinja_env.filters.update(self.jinja_env.filters) template = jinja_env.get_or_select_template( "debug_panels/indexing_panel.html") return template.render(context)
def user(user_id): security = get_service("security") user = User.query.get(user_id) # FIXME: use user profiles view_form = UserProfileViewForm(obj=user) communities = [m.community for m in user.communautes_membership] if current_user != user and (not security.has_role(current_user, "manager")): # filter visible communautes (ticket 165) communities = [c for c in communities if c.has_member(current_user)] view_form.communautes._set_data(communities) # FIXME contact = user entries = get_recent_entries(user=user) entries = ActivityEntryPresenter.wrap_collection(entries) ctx = { "user": user, "contact": contact, "view_form": view_form, "can_edit": can_edit(user), "tabs": make_tabs(user), "activity_entries": entries, } return render_template("social/user.html", **ctx)
def createuser(email, password, role=None, name=None, first_name=None): """Create new user.""" if User.query.filter(User.email == email).count() > 0: print(f"A user with email '{email}' already exists, aborting.") return # if password is None: # password = prompt_pass("Password") user = User( email=email, password=password, last_name=name, first_name=first_name, can_login=True, ) db.session.add(user) if role in ("admin",): # FIXME: add other valid roles security = get_service("security") security.grant_role(user, role) db.session.commit() print(f"User {email} added")
def content(self): obj = self.current_obj index_service = get_service("indexing") index = index_service.app_state.indexes["default"] schema = index.schema context = self.context.copy() context["schema"] = schema context["sorted_fields"] = sorted(schema.names()) adapter = index_service.adapted.get(fqcn(obj.__class__)) if adapter and adapter.indexable: doc = context["current_document"] = index_service.get_document(obj, adapter) indexed = {} for name, field in schema.items(): value = doc.get(name) indexed[name] = None if value and field.analyzer and field.format: indexed[name] = list(field.process_text(value)) context["current_indexed"] = indexed context["current_keys"] = sorted(set(doc) | set(indexed)) with index.searcher() as search: document = search.document(object_key=obj.object_key) sorted_keys = sorted(document) if document is not None else None context.update({"document": document, "sorted_keys": sorted_keys}) jinja_env = current_app.jinja_env jinja_env.filters.update(self.jinja_env.filters) template = jinja_env.get_or_select_template("debug_panels/indexing_panel.html") return template.render(context)
def createuser(email, password, role=None, name=None, first_name=None): """Create new user.""" email = text_type(email) if User.query.filter(User.email == email).count() > 0: print("A user with email '{}' already exists, aborting.".format(email)) return if password is None: password = prompt_pass('Password') user = User( email=email, password=password, last_name=name, first_name=first_name, can_login=True, ) db.session.add(user) if role in ('admin',): # FIXME: add other valid roles security = get_service('security') security.grant_role(user, role) db.session.commit() print("User {} added".format(email))
def __call__(self, form, field): svc = get_service('antivirus') if not svc: return res = svc.scan(field.data) if res is False: raise ValidationError(_(u'Virus detected!'))
def __call__(self, form, field): svc = get_service("antivirus") if not svc: return res = svc.scan(field.data) if res is False: raise validators.ValidationError(_("Virus detected!"))
def get_form_kwargs(self): kw = super().get_form_kwargs() security = get_service("security") roles = [ r for r in security.get_roles(self.obj, no_group_roles=True) if r.assignable ] kw["roles"] = [role.name for role in roles] return kw
def _run_antivirus(document): antivirus = get_service("antivirus") if antivirus and antivirus.running: is_clean = antivirus.scan(document.content_blob) if "antivirus_task" in document.content_blob.meta: del document.content_blob.meta["antivirus_task"] return is_clean return None
def _run_antivirus(document): antivirus = get_service('antivirus') if antivirus and antivirus.running: is_clean = antivirus.scan(document.content_blob) if 'antivirus_task' in document.content_blob.meta: del document.content_blob.meta['antivirus_task'] return is_clean return None
def get(self): svc = get_service('vocabularies') ctx = { 'service': svc, 'url_for_voc_edit': self.voc_edit_url, 'icon_checked': Glyphicon('check'), 'vocabularies': svc.grouped_vocabularies, } return render_template('admin/vocabularies.html', **ctx)
def decorated_view(*args, **kwargs): community = g.community if community and community.has_permission(current_user, MANAGE): return func(*args, **kwargs) security = get_service("security") is_admin = security.has_role(current_user, "admin") if not is_admin: raise Forbidden() return func(*args, **kwargs)
def decorated_view(*args, **kwargs): community = getattr(g, "community") if community and community.has_permission(current_user, MANAGE): return func(*args, **kwargs) security = get_service("security") is_admin = security.has_role(current_user, "admin") if not is_admin: raise Forbidden() return func(*args, **kwargs)
def finalize_validate(): config_file = Path(current_app.instance_path) / "config.py" logging_file = Path(current_app.instance_path) / "logging.yml" assert not config_file.exists() config = cmd_config.DefaultConfig(logging_file="logging.yml") config.SQLALCHEMY_DATABASE_URI = session_get("db")["uri"] redis_uri = session_get("redis")["uri"] config.REDIS_URI = redis_uri config.BROKER_URL = redis_uri config.CELERY_RESULT_BACKEND = redis_uri d = session_get("site_info") config.SITE_NAME = d["sitename"] config.MAIL_SENDER = d["mailsender"] is_production = d["server_mode"] == "production" config.PRODUCTION = is_production config.DEBUG = not is_production config.DEBUG_TB_ENABLED = config.DEBUG config.CELERY_ALWAYS_EAGER = not is_production cmd_config.write_config(config_file, config) cmd_config.maybe_write_logging(logging_file) admin_account = session_get("admin_account") # create a new app that will be configured with new config, # to create database and admin_user setup_app = unwrap(current_app) app = setup_app.__class__( setup_app.import_name, static_url_path=setup_app.static_url_path, static_folder=setup_app.static_folder, template_folder=setup_app.template_folder, instance_path=setup_app.instance_path, ) with app.test_request_context("/setup/finalize"): app.create_db() db_session = db.session() admin = User( email=admin_account["email"], password=admin_account["password"], last_name=admin_account["name"], first_name=admin_account["firstname"], can_login=True, ) db_session.add(admin) security = get_service("security") security.grant_role(admin, Admin) db_session.commit() session_clear() return render_template("setupwizard/done.html", config_file=config_file, logging_file=logging_file)
def finalize_validate(): config_file = Path(current_app.instance_path) / "config.py" logging_file = Path(current_app.instance_path) / "logging.yml" assert not config_file.exists() config = cmd_config.DefaultConfig(logging_file="logging.yml") config.SQLALCHEMY_DATABASE_URI = session_get("db")["uri"] redis_uri = session_get("redis")["uri"] config.REDIS_URI = redis_uri config.BROKER_URL = redis_uri config.CELERY_RESULT_BACKEND = redis_uri d = session_get("site_info") config.SITE_NAME = d["sitename"] config.MAIL_SENDER = d["mailsender"] is_production = d["server_mode"] == "production" config.PRODUCTION = is_production config.DEBUG = not is_production config.DEBUG_TB_ENABLED = config.DEBUG config.CELERY_ALWAYS_EAGER = not is_production cmd_config.write_config(config_file, config) cmd_config.maybe_write_logging(logging_file) admin_account = session_get("admin_account") # create a new app that will be configured with new config, # to create database and admin_user setup_app = unwrap(current_app) app = setup_app.__class__( setup_app.import_name, static_url_path=setup_app.static_url_path, static_folder=setup_app.static_folder, template_folder=setup_app.template_folder, instance_path=setup_app.instance_path, ) with app.test_request_context("/setup/finalize"): app.create_db() db_session = db.session() admin = User( email=admin_account["email"], password=admin_account["password"], last_name=admin_account["name"], first_name=admin_account["firstname"], can_login=True, ) db_session.add(admin) security = get_service("security") security.grant_role(admin, Admin) db_session.commit() session_clear() return render_template( "setupwizard/done.html", config_file=config_file, logging_file=logging_file )
def finalize_validate(): config_file = os.path.join(current_app.instance_path, 'config.py') logging_file = os.path.join(current_app.instance_path, 'logging.yml') assert not os.path.exists(config_file) config = cmd_config.DefaultConfig(logging_file='logging.yml') config.SQLALCHEMY_DATABASE_URI = session_get('db')['uri'] redis_uri = session_get('redis')['uri'] config.REDIS_URI = redis_uri config.BROKER_URL = redis_uri config.CELERY_RESULT_BACKEND = redis_uri d = session_get('site_info') config.SITE_NAME = d['sitename'] config.MAIL_SENDER = d['mailsender'] is_production = d['server_mode'] == u'production' config.PRODUCTION = is_production config.DEBUG = not is_production config.DEBUG_TB_ENABLED = config.DEBUG config.CELERY_ALWAYS_EAGER = not is_production cmd_config.write_config(config_file, config) cmd_config.maybe_write_logging(logging_file) admin_account = session_get('admin_account') # create a new app that will be configured with new config, to create database # and admin_user setup_app = current_app._get_current_object() app = setup_app.__class__( setup_app.import_name, static_url_path=setup_app.static_url_path, static_folder=setup_app.static_folder, template_folder=setup_app.template_folder, instance_path=setup_app.instance_path, ) with app.test_request_context('/setup/finalize'): app.create_db() db_session = app.db.session() admin = User(email=admin_account['email'], password=admin_account['password'], last_name=admin_account['name'], first_name=admin_account['firstname'], can_login=True) db_session.add(admin) security = get_service('security') security.grant_role(admin, Admin) db_session.commit() session_clear() response = make_response( render_template('setupwizard/done.html', config_file=config_file, logging_file=logging_file), 200) return response
def get_form_kwargs(self): kw = super(GroupEdit, self).get_form_kwargs() security = get_service('security') roles = [ r for r in security.get_roles(self.obj, no_group_roles=True) if r.assignable ] kw['roles'] = [r.name for r in roles] return kw
def data(self, *args, **kw): security = get_service("security") length = int(kw.get("iDisplayLength", 0)) start = int(kw.get("iDisplayStart", 0)) sort_dir = kw.get("sSortDir_0", "asc") echo = int(kw.get("sEcho", 0)) search = kw.get("sSearch", "").replace("%", "").strip().lower() end = start + length query = Group.query.options(sa.orm.noload("*")) total_count = query.count() if search: # TODO: gérer les accents query = query.filter(func.lower(Group.name).like("%" + search + "%")) count = query.count() columns = [func.lower(Group.name)] direction = asc if sort_dir == "asc" else desc order_by = list(map(direction, columns)) # sqlite does not support 'NULLS FIRST|LAST' in ORDER BY clauses engine = query.session.get_bind(Group.__mapper__) if engine.name != "sqlite": order_by[0] = nullslast(order_by[0]) query = query.order_by(*order_by).add_columns(Group.members_count) groups = query.slice(start, end).all() data = [] for group, members_count in groups: # TODO: this should be done on the browser. group_url = url_for(".groups_group", group_id=group.id) name = html.escape(group.name or "") roles = [r for r in security.get_roles(group) if r.assignable] columns = [ f'<a href="{group_url}">{name}</a>', str(members_count or 0), render_template_string( """{%- for role in roles %} <span class="badge badge-default">{{ role }}</span> {%- endfor %}""", roles=roles, ), "\u2713" if group.public else "", ] data.append(columns) return { "sEcho": echo, "iTotalRecords": total_count, "iTotalDisplayRecords": count, "aaData": data, }
def get(self): svc = get_service("vocabularies") vocabularies = svc.grouped_vocabularies ctx = { "service": svc, "url_for_voc_edit": self.voc_edit_url, "icon_checked": Glyphicon("check"), "vocabularies": vocabularies, } return render_template("admin/vocabularies.html", **ctx)
def with_permission(self, permission, user=None): from abilian.services import get_service security = get_service("security") if hasattr(self, "_query_entity_zero"): # SQLAlchemy 1.1+ model = self._query_entity_zero().entity_zero.entity else: # SQLAlchemy 1.0 model = self._entity_zero().entity_zero.entity expr = security.query_entity_with_permission(permission, user, Model=model) return self.filter(expr)
def template_kwargs(self): security = get_service("security") kw = super().template_kwargs members = list(self.obj.members) members.sort(key=lambda u: (u.last_name, u.first_name)) kw["members"] = members kw["roles"] = sorted( r for r in security.get_roles(self.obj, no_group_roles=True) if r.assignable) kw["ADD_USER_BUTTON"] = ADD_USER_BUTTON kw["REMOVE_USER_BUTTON"] = REMOVE_USER_BUTTON return kw
def template_kwargs(self): security = get_service("security") kw = super().template_kwargs members = list(self.obj.members) members.sort(key=lambda u: (u.last_name, u.first_name)) kw["members"] = members kw["roles"] = sorted( r for r in security.get_roles(self.obj, no_group_roles=True) if r.assignable ) kw["ADD_USER_BUTTON"] = ADD_USER_BUTTON kw["REMOVE_USER_BUTTON"] = REMOVE_USER_BUTTON return kw
def model_view(self, Model, group=None): svc = get_service('vocabularies') ctx = { 'service': svc, 'url_for_voc_edit': self.voc_edit_url, 'icon_checked': Glyphicon('check'), 'vocabularies': { Model.Meta.group: [Model], }, 'edit_return_to': 'model', } return render_template('admin/vocabularies.html', **ctx)
def after_populate_obj(self): security = get_service('security') current_roles = security.get_roles(self.obj, no_group_roles=True) current_roles = {r for r in current_roles if r.assignable} new_roles = {Role(r) for r in self.form.roles.data} for r in (current_roles - new_roles): security.ungrant_role(self.obj, r) for r in (new_roles - current_roles): security.grant_role(self.obj, r) return super(GroupEdit, self).after_populate_obj()
def template_kwargs(self): security = get_service('security') kw = super(GroupView, self).template_kwargs members = list(self.obj.members) members.sort(key=lambda u: (u.last_name, u.first_name)) kw['members'] = members kw['roles'] = sorted( r for r in security.get_roles(self.obj, no_group_roles=True) if r.assignable ) kw['ADD_USER_BUTTON'] = ADD_USER_BUTTON kw['REMOVE_USER_BUTTON'] = REMOVE_USER_BUTTON return kw
def after_populate_obj(self): security = get_service("security") current_roles = security.get_roles(self.obj, no_group_roles=True) current_roles = {r for r in current_roles if r.assignable} new_roles = {Role(r) for r in self.form.roles.data} for r in current_roles - new_roles: security.ungrant_role(self.obj, r) for r in new_roles - current_roles: security.grant_role(self.obj, r) return super().after_populate_obj()
def model_view(self, Model, group=None): svc = get_service("vocabularies") ctx = { "service": svc, "url_for_voc_edit": self.voc_edit_url, "icon_checked": Glyphicon("check"), "vocabularies": { Model.Meta.group: [Model] }, "edit_return_to": "model", } return render_template("admin/vocabularies.html", **ctx)
def _setup_default_permissions(instance): """Separate method to conveniently call it from scripts for example.""" from abilian.services import get_service security = get_service("security") for permission, roles in instance.__default_permissions__: if permission == "create": # use str for comparison instead of `abilian.services.security.CREATE` # symbol to avoid imports that quickly become circular. # # FIXME: put roles and permissions in a separate, isolated module. continue for role in roles: security.add_permission(permission, role, obj=instance)
def can_create(self): create_cls = self.module.create_cls permission = create_cls.permission cls_permissions = dict(self.Model.__default_permissions__) if self.permission in cls_permissions: security = get_service("security") return security.has_permission( current_user, create_cls.permission, obj=self.obj, roles=cls_permissions[permission], ) return False
def __init__(self, clear, progressive, batch_size): # type: (bool, bool, int) -> None self.clear = clear self.progressive = progressive self.batch_size = int(batch_size or 0) self.index_service = get_service("indexing") self.index = self.index_service.app_state.indexes["default"] self.adapted = self.index_service.adapted self.session = Session(bind=db.session.get_bind(None, None), autocommit=True) self.indexed = set() # type: Set[str] self.cleared = set() # type: Set[str] strategy = progressive_mode if self.progressive else single_transaction self.strategy = strategy(self.index, clear=self.clear)
def send_daily_social_digest(): for user in User.query.filter(User.can_login == True).all(): preferences = get_service("preferences") prefs = preferences.get_preferences(user) if not prefs.get("sbe:notifications:daily", False): continue # Defensive programming. if not validate_email(user.email): continue try: send_daily_social_digest_to(user) except BaseException: current_app.logger.error("Error sending daily social digest", exc_info=True)
def createuser(email, password, role=None, name=None, first_name=None): """ Adds an admin user with given email and password. """ user = User(email=email, password=password, last_name=name, first_name=first_name, can_login=True) db.session.add(user) if role in ('admin',): # FIXME: add other valid roles security = get_service('security') security.grant_role(user, role) db.session.commit() print "User {} added".format(email)
def do_access_control(self): """`before_request` handler to check if user should be redirected to login page.""" from abilian.services import get_service if current_app.testing and current_app.config.get("NO_LOGIN"): # Special case for tests user = User.query.get(0) login_user(user, force=True) return state = self.app_state user = unwrap(current_user) # Another special case for tests if current_app.testing and getattr(user, "is_admin", False): return security = get_service("security") user_roles = frozenset(security.get_roles(user)) endpoint = request.endpoint blueprint = request.blueprint access_controllers = [] access_controllers.extend(state.bp_access_controllers.get(None, [])) if blueprint and blueprint in state.bp_access_controllers: access_controllers.extend(state.bp_access_controllers[blueprint]) if endpoint and endpoint in state.endpoint_access_controllers: access_controllers.extend(state.endpoint_access_controllers[endpoint]) for access_controller in reversed(access_controllers): verdict = access_controller(user=user, roles=user_roles) if verdict is None: continue elif verdict is True: return else: if user.is_anonymous: return self.redirect_to_login() raise Forbidden() # default policy if current_app.config.get("PRIVATE_SITE") and user.is_anonymous: return self.redirect_to_login()
def has_access(community=None, user=None): if not user: user = current_user if user.is_anonymous: return False security = get_service("security") is_admin = security.has_role(user, "admin") if is_admin: return True if not community: community = getattr(g, "community", None) if community is not None: return community.get_role(user) is not None return False
def reindex_tree(obj): """Schedule reindexing `obj` and all of its descendants. Generally needed to update indexed security. """ assert isinstance(obj, CmisObject) index_service = get_service("indexing") if not index_service.running: return descendants = ( sa.select([CmisObject.id, CmisObject._parent_id]) .where(CmisObject._parent_id == sa.bindparam("ancestor_id")) .cte(name="descendants", recursive=True) ) da = descendants.alias() CA = sa.orm.aliased(CmisObject) d_ids = sa.select([CA.id, CA._parent_id]) descendants = descendants.union_all(d_ids.where(CA._parent_id == da.c.id)) session = sa.orm.object_session(obj) or db.session() # including ancestor_id in entity_ids_q will garantee at least 1 value for the # "IN" predicate; otherwise when using sqlite (as during tests...) # 'ResourceClosedError' will be raised. # # as an added bonus, "obj" will also be in query results, thus will be added # in "to_update" without needing to do it apart. entity_ids_q = sa.union( sa.select([descendants.c.id]), sa.select([sa.bindparam("ancestor_id")]) ) query = ( session.query(Entity) .filter(Entity.id.in_(entity_ids_q)) .options(sa.orm.noload("*")) .params(ancestor_id=obj.id) ) to_update = index_service.app_state.to_update key = "changed" for item in query.yield_per(1000): to_update.append((key, item))
def is_manager(context=None, user=None): security = get_service("security") if not user: user = current_user if user.is_anonymous: return False if context: community = context.get("object").community else: community = g.community if community.has_permission(user, MANAGE) or user == community.creator: return True if security.has_role(user, "admin"): return True return False
def content(self): obj = self.current_obj security = get_service("security") context = self.context.copy() context["permissions"] = security.get_permissions_assignments(obj=obj) context["roles"] = roles = {} for principal, r in security.get_role_assignements(obj=obj): if r not in roles: roles[r] = {"anonymous": False, "users": set(), "groups": set()} info = roles[r] if principal is Anonymous: info["anonymous"] = True elif isinstance(principal, Group): info["groups"].add(principal) else: info["users"].add(principal) for r in roles: info = roles[r] info["groups"] = [ "{g} (id={g.id})".format(g=g) for g in sorted(info["groups"], key=lambda g: g.name) ] users = sorted( info["users"], key=lambda u: (u.last_name.lower(), u.first_name.lower()) ) info["users"] = [ '{u} (id={u.id}, email="{u.email}")'.format(u=u) for u in users ] jinja_env = current_app.jinja_env jinja_env.filters.update(self.jinja_env.filters) template = jinja_env.get_or_select_template( "debug_panels/security_info_panel.html" ) return template.render(context)
def _indexable_roles_and_users(self): """Return a string made for indexing roles having :any:`READ` permission on this object.""" from abilian.services.indexing import indexable_role from abilian.services.security import READ, Admin, Anonymous, Creator, Owner from abilian.services import get_service result = [] security = get_service("security") # roles - required to match when user has a global role assignments = security.get_permissions_assignments(permission=READ, obj=self) allowed_roles = assignments.get(READ, set()) allowed_roles.add(Admin) for r in allowed_roles: result.append(indexable_role(r)) for role, attr in ((Creator, "creator"), (Owner, "owner")): if role in allowed_roles: user = getattr(self, attr) if user: result.append(indexable_role(user)) # users and groups principals = set() for user, role in security.get_role_assignements(self): if role in allowed_roles: principals.add(user) if Anonymous in principals: # it's a role listed in role assignments - legacy when there wasn't # permission-role assignments principals.remove(Anonymous) for p in principals: result.append(indexable_role(p)) return " ".join(result)
def createuser(email, password, role=None, name=None, first_name=None): """ Create new user. """ email = unicode(email) if User.query.filter(User.email == email).count() > 0: print("A user with email '{}' already exists, aborting.".format(email)) return if password is None: password = prompt_pass(u'Password') user = User(email=email, password=password, last_name=name, first_name=first_name, can_login=True) db.session.add(user) if role in ('admin',): # FIXME: add other valid roles security = get_service('security') security.grant_role(user, role) db.session.commit() print("User {} added".format(email))
def is_admin(context): security = get_service("security") return security.has_role(current_user, Admin, object=context.get("object"))