def handle_add(self, *args, **options): if "username" not in options: raise CommandError("Username is not set") if "email" not in options: raise CommandError("Email is not set") if "pwgen" in options: passwd = "".join( random.choice(self.pwset) for _ in range(self.PWLEN)) else: passwd = None if not passwd: raise CommandError("Password is not set") permissions = set() if not options.get("template"): raise CommandError("template permission not set") for t in options["template"]: if t not in self.TEMPLATES: raise CommandError("Invalid template '%s'" % t) permissions.update(self.TEMPLATES[t]) if not permissions: raise CommandError("No permissions set") # Create user u = User(username=options["username"], email=options["email"], is_active=True) u.set_password(passwd) u.save() for p in permissions: try: perm = Permission.objects.get(name=p) except Permission.DoesNotExist: perm = Permission(name=p) perm.save() perm.users.add(u) print(passwd)
def update_m2m(self, o, name, values): if values is None: return # Do not touch if name == "permissions": Permission.set_group_permissions(group=o, perms=values) else: super().update_m2m(o, name, values)
def update_m2m(self, o, name, values): if values is None: return # Do not touch if name == "permissions": Permission.set_user_permissions(user=o, perms=values) else: super(UserApplication, self).update_m2m(o, name, values)
def handle(self, *args, **options): from noc.lib.app.site import site site.service = get_service() try: Permission.sync() except ValueError as e: self.die(str(e))
def handle(self, *args, **options): from noc.lib.app.site import site connect() # Install service stub site.service = get_service() # Synchronize permissions try: Permission.sync() except ValueError as e: self.die(str(e))
def view_view(self, request, refbook_id): """ Refbook preview :param request: :param refbook_id: :return: """ rb = get_object_or_404(RefBook, id=int(refbook_id)) can_edit = not rb.is_builtin and Permission.has_perm( request.user, "main.change_refbookdata" ) queryset = rb.refbookdata_set.all() # Search if request.GET and "query" in request.GET and request.GET["query"]: query = request.GET["query"] # Build query clause w = [] p = [] for f in rb.refbookfield_set.filter(search_method__isnull=False): x = f.get_extra(query) if not x: continue w += x["where"] p += x["params"] w = " OR ".join(["(%s)" % xx for xx in w]) queryset = queryset.extra(where=["(%s)" % w], params=p) else: query = "" # Use generic view for final result request._gv_queryset = queryset request._gv_ctx = {"rb": rb, "can_edit": can_edit, "query": query, "app": self} return RefBookList().get(request)
def view_new(self, request, refbook_id): """ Create refbook record :param request: :param refbook_id: :return: """ rb = get_object_or_404(RefBook, id=int(refbook_id)) can_edit = not rb.is_builtin and Permission.has_perm( request.user, "main.change_refbookdata" ) if not can_edit: return self.response_forbidden("Read-only refbook") if request.POST: # Edit refbook if not can_edit: return self.response_forbidden("Read-only refbook") # Retrieve record data fns = [int(k[6:]) for k in request.POST if k.startswith("field_")] data = ["" for i in range(max(fns) + 1)] for i in fns: data[i] = request.POST["field_%d" % i] rbr = RefBookData(ref_book=rb, value=data) rbr.save() self.message_user(request, "Record added") return self.response_redirect("main:refbook:item", rb.id, rbr.id) return self.render(request, "new.html", {"rb": rb})
def has_secret(self): """ Check current user has *secret* permission on given app :return: """ perm_name = "%s:secret" % (self.get_app_id().replace(".", ":")) return perm_name in Permission.get_effective_permissions(get_user())
def view_edit(self, request, refbook_id, record_id=0): """ Edit item :param request: :param refbook_id: :param record_id: :return: """ rb = get_object_or_404(RefBook, id=int(refbook_id)) rbr = get_object_or_404(RefBookData, id=int(record_id), ref_book=rb) can_edit = not rb.is_builtin and Permission.has_perm( request.user, "main.change_refbookdata") if not can_edit: return self.response_forbidden("Read-only refbook") if request.POST: # Edit refbook if not can_edit: return self.response_forbidden("Read-only refbook") # Retrieve record data fns = [ int(k[6:]) for k in six.iterkeys(request.POST) if k.startswith("field_") ] data = ["" for i in range(max(fns) + 1)] for i in fns: data[i] = request.POST["field_%d" % i] rbr.value = data rbr.save() self.message_user(request, "Record updated successfully") return self.response_redirect("main:refbook:item", rb.id, rbr.id) return self.render(request, "edit.html", {"rb": rb, "record": rbr})
def save(self, *args, **kwargs): super().save(*args, **kwargs) # Create permission if required if self.permission_name: try: Permission.objects.get(name=self.effective_permission_name) except Permission.DoesNotExist: Permission(name=self.effective_permission_name).save()
def view_desktop(self, request): """ Render application root template """ cp = CPClient() ext_apps = [ a for a in self.site.apps if isinstance(self.site.apps[a], ExtApplication) ] apps = [a.split(".") for a in sorted(ext_apps)] # Prepare settings favicon_url = config.customization.favicon_url if favicon_url.endswith(".png"): favicon_mime = "image/png" elif favicon_url.endswith(".jpg") or favicon_url.endswith(".jpeg"): favicon_mime = "image/jpeg" else: favicon_mime = None if request.user.is_authenticated(): enable_search = Permission.has_perm(request.user, "main:search:launch") else: enable_search = False setup = { "system_uuid": cp.system_uuid, "installation_name": config.installation_name, "theme": config.web.theme, "logo_url": config.customization.logo_url, "logo_width": config.customization.logo_width, "logo_height": config.customization.logo_height, "brand": version.brand, "branding_color": config.customization.branding_color, "branding_background_color": config.customization.branding_background_color, "favicon_url": favicon_url, "favicon_mime": favicon_mime, "debug_js": False, "gitlab_url": config.gitlab_url, "collections_allow_sharing": config.collections.allow_sharing, "collections_project_id": config.collections.project_id, "enable_gis_base_osm": config.gis.enable_osm, "enable_gis_base_google_sat": config.gis.enable_google_sat, "enable_gis_base_google_roadmap": config.gis.enable_google_roadmap, "trace_extjs_events": False, "preview_theme": config.customization.preview_theme, "enable_search": enable_search, "help_base_url": config.help.base_url, "help_branch": config.help.branch, "help_language": config.help.language, "enable_remote_system_last_extract_info": config.web.enable_remote_system_last_extract_info, "timezone": config.timezone, } return self.render(request, "desktop.html", language=self.get_language(request), apps=apps, setup=setup)
def instance_to_dict_get(self, o, fields=None): r = super().instance_to_dict(o, fields) r["permissions"] = self.apps_permissions_list() current_perms = Permission.get_group_permissions(o) if current_perms: for p in r["permissions"]: if p["name"] in current_perms: p["status"] = True return r
def instance_to_dict_get(self, o, fields=None): r = super(UserApplication, self).instance_to_dict(o, fields) del r["password"] r["permissions"] = self.apps_permissions_list() current_perms = Permission.get_user_permissions(o) if current_perms: for p in r["permissions"]: if p["name"] in current_perms: p["status"] = True return r
def api_settings(self, request): cp = CPClient() # Prepare settings favicon_url = config.customization.favicon_url if favicon_url.endswith(".png"): favicon_mime = "image/png" elif favicon_url.endswith(".jpg") or favicon_url.endswith(".jpeg"): favicon_mime = "image/jpeg" else: favicon_mime = None if request.user.is_authenticated(): enable_search = Permission.has_perm(request.user, "main:search:launch") else: enable_search = False language = self.get_language(request) return { "system_uuid": cp.system_uuid or None, "brand": version.brand, "installation_name": config.installation_name, "preview_theme": config.customization.preview_theme, "language": language, "logo_url": config.customization.logo_url, "logo_width": config.customization.logo_width, "logo_height": config.customization.logo_height, "branding_color": config.customization.branding_color, "branding_background_color": config.customization.branding_background_color, "favicon_mime": favicon_mime, "favicon_url": favicon_url, "enable_search": enable_search, "gitlab_url": config.gitlab_url, "collections": { "allow_sharing": config.collections.allow_sharing, "project_id": config.collections.project_id, }, "gis": { "base": { "enable_osm": config.gis.enable_osm, "enable_google_sat": config.gis.enable_google_sat, "enable_google_roadmap": config.gis.enable_google_roadmap, } }, "traceExtJSEvents": False, "helpUrl": config.help.base_url, "helpBranch": config.help.branch, "helpLanguage": config.help.language, "timezone": config.timezone, "enable_remote_system_last_extract_info": config.web.enable_remote_system_last_extract_info, "theme": config.web.theme, }
def view_item(self, request, refbook_id, record_id): """ Item preview :param request: :param refbook_id: :param record_id: :return: """ rb = get_object_or_404(RefBook, id=int(refbook_id)) rbr = get_object_or_404(RefBookData, id=int(record_id), ref_book=rb) can_edit = not rb.is_builtin and Permission.has_perm( request.user, "main.change_refbookdata" ) return self.render(request, "item.html", {"rb": rb, "record": rbr, "can_edit": can_edit})
def view_delete(self, request, refbook_id, record_id): """ Delete refbook record :param request: :param refbook_id: :param record_id: :return: """ rb = get_object_or_404(RefBook, id=int(refbook_id)) can_edit = not rb.is_builtin and Permission.has_perm( request.user, "main.change_refbookdata") if not can_edit: return self.response_forbidden() rbd = get_object_or_404(RefBookData, ref_book=rb, id=int(record_id)) rbd.delete() self.message_user(request, "Record deleted") return self.response_redirect("main:refbook:view", rb.id)
def get_launch_info(self, request): """ Return desktop launch information """ from noc.aaa.models.permission import Permission user = request.user # Amount of characters to strip lps = len(self.get_app_id()) + 1 # Get effective user permissions user_perms = Permission.get_effective_permissions(user) # Leave only application permissions # and strip <module>:<app>: app_perms = [p[lps:] for p in user_perms & self.get_permissions()] return { "class": self.js_app_class, "title": unicode(self.title), "params": { "url": self.menu_url, "permissions": app_perms, "app_id": self.app_id, "link": self.link, }, }
def prefix_contents(self, request, prefix): vrf = prefix.vrf # List of nested prefixes # @todo: prefetch_related prefixes = list( prefix.children_set.select_related().order_by("prefix")) # Bulk utilization Prefix.update_prefixes_usage(prefixes) # Free prefixes free_prefixes = list( IP.prefix(prefix.prefix).iter_free([pp.prefix for pp in prefixes])) # Get permissions user = request.user can_view = prefix.can_view(user) can_change = prefix.can_change(user) can_bind_vc = can_change and Permission.has_perm( user, "ip:ipam:bind_vc") can_change_maintainers = user.is_superuser can_add_prefix = can_change can_add_address = can_change and len(prefixes) == 0 # Bookmarks has_bookmark = prefix.has_bookmark(user) bookmarks = set(b.prefix for b in PrefixBookmark.user_bookmarks( user, vrf=vrf, afi=prefix.afi)) l_prefixes = sorted( ([(IP.prefix(pp.prefix), pp, pp.prefix in bookmarks) for pp in prefixes] + [(pp, None, False) for pp in free_prefixes]), key=lambda x: x[0], ) # List of nested addresses addresses = list( prefix.address_set.select_related().order_by("address")) # Ranges ranges = [] rs = [] max_slots = 0 r_spots = [] allocated_addresses = set() if addresses: # Assign ranges colors ranges = list(prefix.address_ranges) for r, c in zip(ranges, get_colors(len(ranges))): r.color = c # Schedule ranges r_changes = { } # Address -> (set of entering ranges, set of leaving ranges) for r in ranges: if r.from_address not in r_changes: r_changes[r.from_address] = (set(), set()) if r.to_address not in r_changes: r_changes[r.to_address] = (set(), set()) r_changes[r.from_address][0].add(r) r_changes[r.to_address][1].add(r) # <!> n = (IP.prefix(r.to_address) + 1).address if n not in r_changes: r_changes[n] = (set(), set()) r_spots = list(r_changes) # Allocate slots used_slots = set() free_slots = set() r_slots = {} # Range -> slot max_slots = 0 rs = sorted([[IP.prefix(i), d, []] for i, d in r_changes.items()], key=itemgetter(0)) for address, d, x in rs: entering, leaving = d for r in entering: if not free_slots: free_slots.add(max_slots) max_slots += 1 spt = free_slots.pop() used_slots.add(spt) r_slots[r] = spt for r in leaving: spt = r_slots[r] used_slots.remove(spt) free_slots.add(spt) # Assign ranges to slots slots = [None] * max_slots for r in rs: address, [entering, leaving], _ = r for e in entering: slots[r_slots[e]] = e r[2] = slots[:] for ll in leaving: slots[r_slots[ll]] = None # Assign slots to addresses c = [None] * max_slots rrs = rs[:] cr = rrs.pop(0) if rrs else None for a in addresses: allocated_addresses.add(str(a.address)) address = IP.prefix(a.address) while cr and address >= cr[0]: c = cr[2] if rrs: cr = rrs.pop(0) else: break a.slots = c # Address spot if can_add_address: c = [None] * max_slots rrs = rs[:] if rrs: cr = rrs.pop(0) else: cr = None spot = [] for a in self.get_prefix_spot(prefix, extra=r_spots): if cr and a is not None and a == cr[0]: c = [None if cc is None else cc.id for cc in cr[2]] if rrs: cr = rrs.pop(0) spot += [(None if a is None else a.address, c)] # spot += [(None if a is None else a.address, c, a in special_addr)] # spot = ujson.dumps(spot) # spot = JSONEncoder(ensure_ascii=False).encode(spot) else: spot = None can_ping = spot is not None and len( [a for a in addresses if a.managed_object]) > 0 prefix_info = self.get_info_block(prefix.afi, prefix, addresses) path = [Prefix.objects.get(id=pp) for pp in prefix.get_path()] return { "id": prefix.id, "name": prefix.prefix, "vrf": prefix.vrf.id, "vrf__label": "%s (%s)" % (prefix.vrf.name, prefix.vrf.vpn_id), "description": prefix.description, "afi": prefix.afi, "profile": prefix.profile.name, "state": prefix.state.name, "maintainers": [m.username for m in prefix.maintainers], "has_bookmark": has_bookmark, "permissions": { "view": can_view, "change": can_change, "bind_vc": can_bind_vc, "change_maintainers": can_change_maintainers, "add_prefix": can_add_prefix, "delete_prefix": True, "add_address": can_add_address, "ping": can_ping, }, "path": [{ "id": p.id, "parent_id": p.parent_id, "name": p.prefix } for p in path], "prefixes": [{ "id": p.id, "name": p.prefix, "has_bookmark": is_bookmarks, "description": p.description, "afi": p.afi, "project": p.project.code if p.project else None, "as": "AS%d" % p.asn.asn if p.asn else None, "vc": p.vc.name if p.vc else None, "tt": p.tt, "usage": p.usage_percent, "address_usage": p.address_usage_percent, "labels": p.labels, "state": p.state.name, "state_desc": p.state.description, "isFree": False, } if p else { "name": ip.prefix, "isFree": True } for ip, p, is_bookmarks in l_prefixes], "addresses": sorted( [{ "id": a.id, "name": a.name, "address": a.address, "state": a.state.name, "fqdn": a.fqdn if a.fqdn else None, "mac": a.mac if a.mac else None, "mo_id": a.managed_object.id if a.managed_object else None, "mo_name": a.managed_object.name if a.managed_object else None, "is_router": a.managed_object.is_router if a.managed_object else None, "project": a.project.code if a.project else None, "subinterface": a.subinterface if a.subinterface else None, "short_desc": a.short_description, "desc": a.description, "source": { "M": "Manual", "i": "Interface", "m": "Mgmt", "d": "DHCP", "n": "Neighbor", }.get(a.source, "-"), "tt": a.tt, "labels": a.labels, "isFree": False, } for a in addresses] + ([{ "address": z[0], "isFree": True } for z in spot if str(z[0]) not in allocated_addresses] if spot else []), key=lambda x: IP.prefix(x["address"]), ), "info": dict(prefix_info), "ranges": [{ "name": r.name, "description": r.description, "from_address": r.from_address, "to_address": r.to_address, "color": r.color, } for r in ranges], "bookmarks": [{ "id": b.id, "text": b.prefix } for b in PrefixBookmark.user_bookmarks( user, vrf=vrf, afi=prefix.afi)], }
def test_permissions(): site.service = get_service() Permission.sync() assert Permission.objects.count() > 0
def check(self, app, user, obj=None): return DBPermission.has_perm(user, self.get_permission(app))
def view_vrf_index(self, request, vrf_id, afi, prefix): """ Display VRF Index """ # Validate vrf = self.get_object_or_404(VRF, id=int(vrf_id)) if (afi == "4" and (not is_ipv4_prefix(prefix)) or not vrf.afi_ipv4) or ( afi == "6" and (not is_ipv6_prefix(prefix) or not vrf.afi_ipv6) ): return self.response_forbidden("Invalid prefix") prefix = self.get_object_or_404(Prefix, vrf=vrf, afi=afi, prefix=prefix) # Get prefix path path = [] p = prefix.parent while p: path = [p] + path p = p.parent # List of nested prefixes # @todo: prefetch_related prefixes = list(prefix.children_set.select_related().order_by("prefix")) # Bulk utilization Prefix.update_prefixes_usage(prefixes) # Get permissions user = request.user can_view = prefix.can_view(user) can_change = prefix.can_change(user) can_bind_vc = can_change and Permission.has_perm(user, "ip:ipam:bind_vc") can_change_maintainers = user.is_superuser can_add_prefix = can_change can_add_address = can_change and len(prefixes) == 0 can_edit_special = prefix.effective_prefix_special_address == "I" # Bookmarks has_bookmark = prefix.has_bookmark(user) bookmarks = PrefixBookmark.user_bookmarks(user, vrf=vrf, afi=afi) s_bookmarks = set(b.prefix for b in bookmarks) # Add free prefixes free_prefixes = list(IP.prefix(prefix.prefix).iter_free([pp.prefix for pp in prefixes])) l_prefixes = sorted( ( [(True, IP.prefix(pp.prefix), pp, pp.prefix in s_bookmarks) for pp in prefixes] + [(False, pp, None, None) for pp in free_prefixes] ), key=lambda x: x[1], ) # List of nested addresses # @todo: prefetch_related addresses = list(prefix.address_set.select_related().order_by("address")) # Prepare block info prefix_info = [("Network", prefix.prefix)] if afi == "4": prefix_info += [ ("Broadcast", prefix.broadcast), ("Netmask", prefix.netmask), ("Widlcard", prefix.wildcard), ("Size", prefix.size), ("Usage", prefix.usage_percent), ("Usage Address", prefix.address_usage_percent), ] if addresses: prefix_info += [("Used addresses", len(addresses))] if afi == "4": free = prefix.size - len(addresses) prefix_info += [("Free addresses", free - 2 if free >= 2 else free)] # Prefix discovery dmap = {"E": "Enabled", "D": "Disabled"} if prefix.prefix_discovery_policy == "P": t = "Profile (%s)" % dmap[prefix.profile.prefix_discovery_policy] else: t = dmap[prefix.prefix_discovery_policy] prefix_info += [("Prefix Discovery", t)] # Address discovery if prefix.address_discovery_policy == "P": t = "Profile (%s)" % dmap[prefix.profile.address_discovery_policy] else: t = dmap[prefix.address_discovery_policy] prefix_info += [("Address Discovery", t)] # Source prefix_info += [ ( "Source", {"M": "Manual", "i": "Interface", "w": "Whois Route", "n": "Neighbor"}.get( prefix.source, "-" ), ) ] # # Add custom fields for f in CustomField.table_fields("ip_prefix"): v = getattr(prefix, f.name) prefix_info += [(f.label, v if v is not None else "")] # Ranges ranges = [] rs = [] max_slots = 0 r_spots = [] if addresses: # Assign ranges colors ranges = list(prefix.address_ranges) for r, c in zip(ranges, get_colors(len(ranges))): r.color = c # Schedule ranges r_changes = {} # Address -> (set of entering ranges, set of leaving ranges) for r in ranges: if r.from_address not in r_changes: r_changes[r.from_address] = (set(), set()) if r.to_address not in r_changes: r_changes[r.to_address] = (set(), set()) r_changes[r.from_address][0].add(r) r_changes[r.to_address][1].add(r) # <!> n = (IP.prefix(r.to_address) + 1).address if n not in r_changes: r_changes[n] = (set(), set()) r_spots = list(six.iterkeys(r_changes)) # Allocate slots used_slots = set() free_slots = set() r_slots = {} # Range -> slot max_slots = 0 rs = sorted( ([IP.prefix(i), d, []] for i, d in six.iteritems(r_changes)), key=itemgetter(0) ) for address, d, x in rs: entering, leaving = d for r in entering: if not free_slots: free_slots.add(max_slots) max_slots += 1 s = free_slots.pop() used_slots.add(s) r_slots[r] = s for r in leaving: s = r_slots[r] used_slots.remove(s) free_slots.add(s) # Assign ranges to slots slots = [None] * max_slots for r in rs: address, [entering, leaving], _ = r for e in entering: slots[r_slots[e]] = e r[2] = slots[:] for l in leaving: slots[r_slots[l]] = None # Assign slots to addresses c = [None] * max_slots rrs = rs[:] cr = rrs.pop(0) if rrs else None for a in addresses: address = IP.prefix(a.address) while cr and address >= cr[0]: c = cr[2] if rrs: cr = rrs.pop(0) else: break a.slots = c # Address spot if can_add_address: special_addr = IP.prefix(prefix.prefix).special_addresses c = [None] * max_slots rrs = rs[:] if rrs: cr = rrs.pop(0) else: cr = None spot = [] for a in self.get_prefix_spot(prefix, extra=r_spots): if cr and a is not None and a == cr[0]: c = [None if cc is None else cc.id for cc in cr[2]] if rrs: cr = rrs.pop(0) spot += [(None if a is None else a.address, c, a in special_addr)] spot = ujson.dumps(spot) else: spot = None can_ping = spot is not None and len([a for a in addresses if a.managed_object]) > 0 # Build custom styles styles = {} if prefix.profile.style: styles[prefix.profile.style.css_class_name] = prefix.profile.style.css for p in prefixes: if p.profile.style and p.profile.style.css_class_name not in styles: styles[p.profile.style.css_class_name] = p.profile.style.css for a in addresses: if a.profile.style and a.profile.style.css_class_name not in styles: styles[a.profile.style.css_class_name] = a.profile.style.css styles = "\n".join(six.itervalues(styles)) # Render return self.render( request, "vrf_index.html.j2", user=request.user, vrf=vrf, prefix=prefix, path=path, prefixes=prefixes, addresses=addresses, prefix_info=prefix_info, display_empty_message=not addresses and not prefixes, can_view=can_view, can_change=can_change, can_bind_vc=can_bind_vc, can_change_maintainers=can_change_maintainers, can_add_prefix=can_add_prefix, can_add_address=can_add_address, can_edit_special=can_edit_special, has_bookmark=has_bookmark, bookmarks=bookmarks, spot=spot, can_ping=can_ping, styles=styles, ranges=ranges, max_slots=max_slots, l_prefixes=l_prefixes, )