示例#1
0
    def __init__(self, hosts=settings.AMQP_HOSTS, max_retries=30,
                 confirms=True, confirm_buffer=100, logger=None):
        """
        Format hosts as "amqp://*****:*****@host:port"
        max_retries=0 defaults to unlimited retries

        """

        self.hosts = hosts
        shuffle(self.hosts)

        self.max_retries = max_retries
        self.confirms = confirms
        self.confirm_buffer = confirm_buffer

        self.connection = None
        self.channel = None
        self.consumers = {}
        self.unacked = OrderedDict()
        self.unsend = OrderedDict()
        self.consume_promises = []
        self.exchanges = []
        if logger:
            self.log = logger
        else:
            logger = logging.getLogger("amqp")
            logging.basicConfig()
            self.log = logger
示例#2
0
    def __init__(self, user=None, identifier=None, **provider_params):
        """
        3 ways to initialize (no args, user, user and identifier).

        no args: Used for anonymous unauthenticated users.
        >>> p = auth_providers.get_provider('local')
        >>> # check that global settings allows us to create a new account
        >>> # using `local` provider.
        >>> print p.is_available_for_create()

        user and identifier: Used to provide details about a user's specific
        login method.
        >>> p = auth_providers.get_provider('google', user,
        >>>                                 identifier='1421421')
        >>> # provider (google) details prompt
        >>> print p.get_method_details()
        "Google account: 1421421"
        """

        # handle AnonymousUser instance
        self.user = None
        if user and hasattr(user, 'pk') and user.pk:
            self.user = user

        self.identifier = identifier
        self._instance = None
        if 'instance' in provider_params:
            self._instance = provider_params['instance']
            del provider_params['instance']

        # initialize policies
        self.module_policies = copy.copy(self.default_policies)
        self.module_policies['automoderate'] = not \
            astakos_settings.MODERATION_ENABLED
        for policy, value in self.policies.iteritems():
            setting_key = "%s_POLICY" % policy.upper()
            if self.has_setting(setting_key):
                self.module_policies[policy] = self.get_setting(setting_key)
            else:
                self.module_policies[policy] = value

        # messages cache
        self.message_tpls_compiled = OrderedDict()

        # module specific messages
        self.message_tpls = OrderedDict(self.message_tpls)
        for key, value in self.messages.iteritems():
            self.message_tpls[key] = value

        self._provider_details = provider_params

        self.resolve_available_methods = True
示例#3
0
def handle_destroy(viol_id,
                   resource,
                   vms,
                   diff,
                   actions,
                   remains,
                   options=None):
    cascade_remove = options.get("cascade_remove", False)
    vm_actions = actions["vm"]
    if "volume" not in actions:
        actions["volume"] = OrderedDict()
    volume_actions = actions["volume"]
    vms = sorted(vms, key=sort_vms(), reverse=True)
    all_volumes = Volume.objects.filter(deleted=False, machine__in=vms)
    all_volumes = _partition_by(lambda vol: vol.machine_id, all_volumes)
    for vm in vms:
        if diff < 1:
            break
        volumes = all_volumes.get(vm.id, [])
        if has_extra_disks(volumes) and not cascade_remove:
            continue
        diff -= CHANGE[resource](vm)
        vm_actions[vm.id] = vm_remove_action(viol_id, vm)
        for volume in volumes:
            volume_actions[volume.id] = volume_remove_action(viol_id,
                                                             volume,
                                                             machine=vm)
    if diff > 0:
        remains[resource].append(viol_id)
示例#4
0
def pprint_ippool(subnet, stdout=None, title=None):
    """Pretty print IP Pools of a subnet. Only IPv4 subnets have IP Pools"""

    if int(subnet.ipversion) != 4:
        return 0

    if stdout is None:
        stdout = sys.stdout

    stdout.write("IP Pools of subnet %s:\n\n" % subnet.id)

    for pool in subnet.get_ip_pools():
        size = pool.pool_size
        available = pool.available.count()
        info = OrderedDict([("First_IP", pool.return_start()),
                            ("Last_IP", pool.return_end()), ("Size", size),
                            ("Available", available)])
        pprint_table(stdout, info.items(), None, separator=" | ", title=None)

        reserved = [
            pool.index_to_value(index)
            for index, ip in enumerate(pool.reserved[:size]) if ip is False
        ]

        if reserved != []:
            stdout.write("\nExternally Reserved IPs:\n\n")
            stdout.write(", ".join(reserved) + "\n")

        ip_sum = pool.available[:size] & pool.reserved[:size]
        pprint_pool(None, bitarray_to_map(ip_sum), 80, stdout)
        stdout.write("\n\n")
示例#5
0
def project_fields(project):
    app = project.last_application
    pending_app = (app.id if app and app.state == app.PENDING else None)

    d = OrderedDict([
        ('project id', project.uuid),
        ('name', project.realname),
        ('status', project.state_display()),
        ('pending_app', pending_app),
        ('owner', project.owner),
        ('homepage', project.homepage),
        ('description', project.description),
        ('creation date', project.creation_date),
        ('request end date', project.end_date),
    ])

    deact = project.last_deactivation()
    if deact is not None:
        d['deactivation date'] = deact.date

    d.update([
        ('join policy', project.member_join_policy_display),
        ('leave policy', project.member_leave_policy_display),
        ('max members', units.show(project.limit_on_members_number, None)),
        ('total members', project.members_count()),
    ])

    return d
示例#6
0
def pprint_network(network, display_mails=False, stdout=None, title=None):
    if stdout is None:
        stdout = sys.stdout
    if title is None:
        title = "State of Network %s in DB" % network.id

    ucache = UserCache(ASTAKOS_AUTH_URL, ASTAKOS_TOKEN)
    userid = network.userid

    db_network = OrderedDict([
        ("name", network.name), ("backend-name", network.backend_id),
        ("state", network.state), ("userid", userid),
        ("username", ucache.get_name(userid) if display_mails else None),
        ("public", network.public),
        ("floating_ip_pool", network.floating_ip_pool),
        ("external_router", network.external_router),
        ("drained", network.drained), ("MAC prefix", network.mac_prefix),
        ("flavor", network.flavor), ("link", network.link),
        ("mode", network.mode), ("deleted", network.deleted),
        ("tags", "), ".join(network.backend_tag)), ("action", network.action)
    ])

    pprint_table(stdout,
                 db_network.items(),
                 None,
                 separator=" | ",
                 title=title)
示例#7
0
def app_fields(app):
    d = OrderedDict([
        ('project id', app.chain.uuid),
        ('application id', app.id),
        ('status', app.state_display()),
        ('applicant', app.applicant),
        ('comments for review', app.comments),
        ('request issue date', app.issue_date),
    ])
    if app.name:
        d['name'] = app.name
    if app.owner:
        d['owner'] = app.owner
    if app.homepage:
        d['homepage'] = app.homepage
    if app.description:
        d['description'] = app.description
    if app.start_date:
        d['request start date'] = app.start_date
    if app.end_date:
        d['request end date'] = app.end_date
    if app.member_join_policy:
        d['join policy'] = app.member_join_policy_display
    if app.member_leave_policy:
        d['leave policy'] = app.member_leave_policy_display
    if app.limit_on_members_number:
        d['max members'] = units.show(app.limit_on_members_number, None)

    return d
示例#8
0
def pprint_floating_ip(ip, display_mails=False, stdout=None, title=None):
    if stdout is None:
        stdout = sys.stdout
    if title is None:
        title = "Floating IP %s" % ip.id

    ucache = UserCache(ASTAKOS_AUTH_URL, ASTAKOS_TOKEN)
    userid = ip.userid

    vtype_info = OrderedDict([
        ("id", ip.id),
        ("address", ip.address),
        ("network", ip.network_id),
        ("port", ip.nic_id),
        ("server", ip.nic.machine_id),
        ("userid", userid),
        ("username", ucache.get_name(userid) if
         (display_mails and userid is not None) else None),
        ("project", ip.project),
        ("shared_to_project", ip.shared_to_project),
        ("deleted", ip.deleted),
        ("created", ip.created),
        ("updated", ip.updated),
    ])

    pprint_table(stdout, vtype_info.items(), separator=" | ", title=title)
示例#9
0
def pprint_volume(volume, display_mails=False, stdout=None, title=None):
    if stdout is None:
        stdout = sys.stdout
    if title is None:
        title = "State of volume %s in DB" % volume.id

    ucache = UserCache(ASTAKOS_AUTH_URL, ASTAKOS_TOKEN)
    userid = volume.userid

    volume_type = volume.volume_type
    volume_dict = OrderedDict([
        ("id", volume.id),
        ("size", volume.size),
        ("disk_template", volume_type.template),
        ("disk_provider", volume_type.provider),
        ("server_id", volume.machine_id),
        ("userid", volume.userid),
        ("project", volume.project),
        ("username", ucache.get_name(userid) if display_mails else None),
        ("index", volume.index),
        ("name", volume.name),
        ("state", volume.status),
        ("delete_on_termination", volume.delete_on_termination),
        ("deleted", volume.deleted),
        ("backendjobid", volume.backendjobid),
    ])

    pprint_table(stdout,
                 volume_dict.items(),
                 None,
                 separator=" | ",
                 title=title)
示例#10
0
def pprint_server_in_ganeti(server, print_jobs=False, stdout=None, title=None):
    if stdout is None:
        stdout = sys.stdout
    if title is None:
        title = "State of Server %s in Ganeti" % server.id

    client = server.get_client()
    try:
        server_info = client.GetInstance(server.backend_vm_id)
    except GanetiApiError as e:
        if e.code == 404:
            stdout.write("Server '%s' does not exist in backend '%s'\n" %
                         (server.id, server.backend.clustername))
            return
        raise e
    server.put_client(client)

    GANETI_INSTANCE_FIELDS = ('name', 'oper_state', 'admin_state', 'status',
                              'pnode', 'snode', 'network_port',
                              'disk_template', 'disk_usage', 'oper_ram',
                              'oper_vcpus', 'mtime')
    server_dict = OrderedDict([(k, server_info.get(k))
                               for k in GANETI_INSTANCE_FIELDS])

    pprint_table(stdout,
                 server_dict.items(),
                 None,
                 separator=" | ",
                 title=title)
    stdout.write("\n")

    nics = nics_from_instance(server_info)
    nics_keys = ["ip", "mac", "name", "network"]
    nics_values = [[nic[key] for key in nics_keys] for nic in nics]
    pprint_table(stdout,
                 nics_values,
                 nics_keys,
                 separator=" | ",
                 title="NICs of Server %s in Ganeti" % server.id)

    if not print_jobs:
        return

    client = server.get_client()
    jobs = client.GetJobs(bulk=True)
    server_jobs = filter(
        lambda x: server.backend_vm_id in (" ".join(x.get("summary"))), jobs)

    GANETI_JOB_FIELDS = ('id', 'status', 'summary', 'opresult', 'opstatus',
                         'oplog', 'start_ts', 'end_ts')
    for server_job in server_jobs:
        stdout.write("\n")
        values = [server_job.get(k) for k in GANETI_JOB_FIELDS]
        pprint_table(stdout,
                     zip(GANETI_JOB_FIELDS, values),
                     None,
                     separator=" | ",
                     title="Ganeti Job %s" % server_job["id"])
    server.put_client(client)
示例#11
0
def handle_volume(viol_id,
                  resource,
                  volumes,
                  diff,
                  actions,
                  remains,
                  options=None):
    if "vm" not in actions:
        actions["vm"] = OrderedDict()
    vm_actions = actions["vm"]
    volume_actions = actions["volume"]
    remove_system_volumes = options.get("remove_system_volumes", False)
    cascade_remove = options.get("cascade_remove", False)
    other_removed = set(volume_actions.keys())
    volumes = sorted(volumes, key=sort_volumes(other_removed), reverse=True)
    volume_ids = set(vol.id for vol in volumes)
    machines = set(volume.machine_id for volume in volumes)
    all_volumes = Volume.objects.filter(deleted=False, machine__in=machines)
    all_volumes = _partition_by(lambda vol: vol.machine_id, all_volumes)
    counted = set()

    for volume in volumes:
        if diff < 1:
            break
        if volume.id in counted:
            continue
        if volume.id in other_removed:
            diff -= CHANGE[resource](volume)
            counted.add(volume.id)
            continue
        if not remove_system_volumes and _is_system_volume(volume):
            continue
        if not _is_system_volume(volume):
            diff -= CHANGE[resource](volume)
            volume_actions[volume.id] = volume_remove_action(viol_id, volume)
            counted.add(volume)
            continue
        vm = volume.machine
        sec_volumes = [
            v for v in all_volumes.get(vm.id, []) if v.id != volume.id
        ]
        if sec_volumes and not cascade_remove:
            continue
        volume_actions[volume.id] = volume_remove_action(viol_id, volume)
        diff -= CHANGE[resource](volume)
        counted.add(volume)
        vm_actions[vm.id] = vm_remove_action(viol_id, vm)
        for vol in sec_volumes:
            volume_actions[vol.id] = volume_remove_action(viol_id, vol)
            if vol.id in volume_ids and vol.id not in counted:
                diff -= CHANGE[resource](vol)
                counted.add(vol.id)
    if diff > 0:
        remains[resource].append(viol_id)
示例#12
0
def pprint_port(port, stdout=None, title=None):
    if stdout is None:
        stdout = sys.stdout
    if title is None:
        title = "State of Port %s in DB" % port.id
    port = OrderedDict([("id", port.id), ("name", port.name),
                        ("userid", port.userid), ("server", port.machine_id),
                        ("network", port.network_id),
                        ("device_owner", port.device_owner), ("mac", port.mac),
                        ("state", port.state)])

    pprint_table(stdout, port.items(), None, separator=" | ", title=title)
示例#13
0
def pprint_volume_type(volume_type, stdout=None, title=None):
    if stdout is None:
        stdout = sys.stdout
    if title is None:
        title = "Volume Type %s" % volume_type.id

    vtype_info = OrderedDict([
        ("name", volume_type.name),
        ("disk template", volume_type.disk_template),
        ("deleted", volume_type.deleted),
    ])

    pprint_table(stdout, vtype_info.items(), separator=" | ", title=title)
示例#14
0
文件: pprint.py 项目: vgerak/synnefo
def pprint_volume_type(volume_type, stdout=None, title=None):
    if stdout is None:
        stdout = sys.stdout
    if title is None:
        title = "Volume Type %s" % volume_type.id

    specs_str = ", ".join(str(s) for s in volume_type.specs.all())
    vtype_info = OrderedDict([
        ("name", volume_type.name),
        ("disk template", volume_type.disk_template),
        ("deleted", volume_type.deleted),
        ("specs", specs_str),
    ])

    pprint_table(stdout, vtype_info.items(), separator=" | ", title=title)
示例#15
0
    def __init__(self,
                 hosts=settings.AMQP_HOSTS,
                 max_retries=30,
                 confirms=True,
                 confirm_buffer=200):
        self.hosts = hosts
        shuffle(self.hosts)

        self.max_retries = max_retries
        self.confirms = confirms
        self.confirm_buffer = confirm_buffer

        self.connection = None
        self.channel = None
        self.consumers = {}
        self.unacked = OrderedDict()
示例#16
0
    def handle(self, *args, **options):
        if len(args) != 1:
            raise CommandError("Please provide a component name or ID.")

        identifier = args[0]
        if identifier.isdigit():
            try:
                component = Component.objects.get(id=int(identifier))
            except Component.DoesNotExist:
                raise CommandError('No component found with ID %s.' %
                                   identifier)
        else:
            try:
                component = Component.objects.get(name=identifier)
            except Component.DoesNotExist:
                raise CommandError('No component found named %s.' % identifier)

        kv = OrderedDict([
            ('id', component.id),
            ('name', component.name),
            ('base url', component.base_url),
            ('ui url', component.url),
            ('token', component.auth_token),
            ('token created', component.auth_token_created),
            ('token expires', component.auth_token_expires),
        ])

        utils.pprint_table(self.stdout, [kv.values()],
                           kv.keys(),
                           options["output_format"],
                           vertical=True)

        services = component.service_set.all()

        service_data = []
        for service in services:
            service_data.append((service.id, service.name, service.type))

        if service_data:
            self.stdout.write('\n')
            labels = ('id', 'name', 'type')
            utils.pprint_table(self.stdout,
                               service_data,
                               labels,
                               options["output_format"],
                               title='Registered services')
示例#17
0
文件: pprint.py 项目: vgerak/synnefo
def pprint_server(server, display_mails=False, stdout=None, title=None):
    if stdout is None:
        stdout = sys.stdout
    if title is None:
        title = "State of Server %s in DB" % server.id

    ucache = UserCache(ASTAKOS_AUTH_URL, ASTAKOS_TOKEN)
    userid = server.userid

    try:
        image = get_image(server.imageid, server.userid)['name']
    except:
        image = server.imageid

    server_dict = OrderedDict([
        ("id", server.id),
        ("name", server.name),
        ("userid", server.userid),
        ("username", ucache.get_name(userid) if display_mails else None),
        ("project", server.project),
        ("shared_to_project", server.shared_to_project),
        ("flavor_id", server.flavor_id),
        ("flavor_name", server.flavor.name),
        ("imageid", server.imageid),
        ("image_name", image),
        ("created", server.created),
        ("state", server.operstate),
        ("backend", server.backend),
        ("deleted", server.deleted),
        ("action", server.action),
        ("task", server.task),
        ("rescue", server.rescue),
        ("rescue_image", server.rescue_image),
        ("task_job_id", server.task_job_id),
        ("backendjobid", server.backendjobid),
        ("backendopcode", server.backendopcode),
        ("backendjobstatus", server.backendjobstatus),
        ("backend_time", server.backendtime),
    ])

    pprint_table(stdout,
                 server_dict.items(),
                 None,
                 separator=" | ",
                 title=title)
示例#18
0
def pprint_port(port, display_mails=False, stdout=None, title=None):
    if stdout is None:
        stdout = sys.stdout
    if title is None:
        title = "State of Port %s in DB" % port.id

    ucache = UserCache(ASTAKOS_AUTH_URL, ASTAKOS_TOKEN)
    userid = port.userid

    port = OrderedDict([("id", port.id), ("name", port.name),
                        ("userid", port.userid),
                        ("username",
                         ucache.get_name(userid) if display_mails else None),
                        ("server", port.machine_id),
                        ("network", port.network_id),
                        ("device_owner", port.device_owner), ("mac", port.mac),
                        ("state", port.state)])

    pprint_table(stdout, port.items(), None, separator=" | ", title=title)
示例#19
0
def pprint_subnet_in_db(subnet, stdout=None, title=None):
    if stdout is None:
        stdout = sys.stdout
    if title is None:
        title = "State of Subnet %s in DB" % subnet.id
    info = OrderedDict([
        ("ID", subnet.id),
        ("Network_ID", subnet.network.id),
        # If a user names his subnet "-", what happens then?
        ("User_ID", subnet.userid),
        ("Name", "-" if subnet.name == "" else subnet.name),
        ("IP_Version", subnet.ipversion),
        ("CIDR", subnet.cidr),
        ("Gateway", subnet.gateway),
        ("Public", subnet.public),
        ("DHCP/SLAAC", subnet.dhcp),
        ("Host_Routes", subnet.host_routes),
        ("DNS_Nameservers", subnet.dns_nameservers)
    ])
    pprint_table(stdout, info.items(), None, separator=" | ", title=title)
示例#20
0
    def handle(self, *args, **options):
        if len(args) != 1:
            raise CommandError("Please profile name")

        try:
            profile = Profile.objects.get(name=args[0])
        except Profile.DoesNotExist:
            raise CommandError("Profile does not exist")

        kv = OrderedDict([('id', profile.id),
                          ('is active', str(profile.active)),
                          ('name', profile.name),
                          ('is exclusive', profile.is_exclusive),
                          ('policies', profile.policies),
                          ('groups', profile.groups.all()),
                          ('users', profile.users.all())])

        utils.pprint_table(self.stdout, [kv.values()],
                           kv.keys(),
                           options["output_format"],
                           vertical=True)
示例#21
0
    def handle(self, *args, **options):
        if len(args) != 1:
            raise CommandError("Please provide a service name or ID.")

        identifier = args[0]
        if identifier.isdigit():
            try:
                service = Service.objects.get(id=int(identifier))
            except Service.DoesNotExist:
                raise CommandError('No service found with ID %s.' % identifier)
        else:
            try:
                service = Service.objects.get(name=identifier)
            except Service.DoesNotExist:
                raise CommandError('No service found named %s.' % identifier)

        kv = OrderedDict([
            ('id', service.id),
            ('name', service.name),
            ('component', service.component),
            ('type', service.type),
        ])

        utils.pprint_table(self.stdout, [kv.values()],
                           kv.keys(),
                           options["output_format"],
                           vertical=True)

        self.stdout.write('\n')
        endpoint_data = EndpointData.objects.filter(endpoint__service=service)
        data = []
        for ed in endpoint_data:
            data.append((ed.endpoint_id, ed.key, ed.value))

        labels = ('endpoint', 'key', 'value')
        utils.pprint_table(self.stdout,
                           data,
                           labels,
                           options["output_format"],
                           title='Endpoints')
示例#22
0
文件: pprint.py 项目: vgerak/synnefo
def pprint_flavor(flavor, stdout=None, title=None):
    if stdout is None:
        stdout = sys.stdout
    if title is None:
        title = "Flavor %s" % flavor.name

    flavor_specs = ', '.join([str(spec) for spec in flavor.specs.all()])

    flavor_info = OrderedDict([
        ("id", flavor.id),
        ("name", flavor.name),
        ("cpu", flavor.cpu),
        ("ram", flavor.ram),
        ("disk", flavor.disk),
        ("volume_type", flavor.volume_type_id),
        ("template", flavor.volume_type.disk_template),
        ("allow_create", flavor.allow_create),
        ("public", flavor.public),
        ("specs", flavor_specs),
    ])

    pprint_table(stdout, flavor_info.items(), separator=" | ", title=title)
示例#23
0
def project_fields(project, pending_app):
    app = project.application

    d = OrderedDict([
        ('project id', project.id),
        ('application id', app.id),
        ('name', app.name),
        ('status', project.state_display()),
    ])
    if pending_app is not None:
        d.update([('pending application', pending_app.id)])

    d.update([
        ('owner', app.owner),
        ('applicant', app.applicant),
        ('homepage', app.homepage),
        ('description', app.description),
        ('comments for review', app.comments),
        ('request issue date', app.issue_date),
        ('request start date', app.start_date),
        ('creation date', project.creation_date),
        ('request end date', app.end_date),
    ])

    deact = project.last_deactivation()
    if deact is not None:
        d['deactivation date'] = deact.date

    mem_limit = app.limit_on_members_number
    mem_limit_show = mem_limit if mem_limit is not None else "unlimited"

    d.update([
        ('join policy', app.member_join_policy_display),
        ('leave policy', app.member_leave_policy_display),
        ('max members', mem_limit_show),
        ('total members', project.members_count()),
    ])

    return d
示例#24
0
def app_fields(app):
    mem_limit = app.limit_on_members_number
    mem_limit_show = mem_limit if mem_limit is not None else "unlimited"

    d = OrderedDict([
        ('project id', app.chain),
        ('application id', app.id),
        ('name', app.name),
        ('status', app.state_display()),
        ('owner', app.owner),
        ('applicant', app.applicant),
        ('homepage', app.homepage),
        ('description', app.description),
        ('comments for review', app.comments),
        ('request issue date', app.issue_date),
        ('request start date', app.start_date),
        ('request end date', app.end_date),
        ('join policy', app.member_join_policy_display),
        ('leave policy', app.member_leave_policy_display),
        ('max members', mem_limit_show),
    ])

    return d
示例#25
0
文件: util.py 项目: vgerak/synnefo
def _resources_catalog(as_dict=False):
    """
    `resource_catalog` contains a list of tuples. Each tuple contains the group
    key the resource is assigned to and resources list of dicts that contain
    resource information.
    `resource_groups` contains information about the groups
    """
    # presentation data
    resources_meta = presentation.RESOURCES
    resource_groups = resources_meta.get('groups', {})
    resource_catalog = ()
    resource_keys = []

    # resources in database
    resource_details = map(lambda obj: model_to_dict(obj, exclude=[]),
                           Resource.objects.all())
    # initialize resource_catalog to contain all group/resource information
    for r in resource_details:
        if not r.get('group') in resource_groups:
            resource_groups[r.get('group')] = {'icon': 'unknown'}

    resource_keys = [r.get('str_repr') for r in resource_details]
    resource_catalog = [[
        g, filter(lambda r: r.get('group', '') == g, resource_details)
    ] for g in resource_groups]

    # order groups, also include unknown groups
    groups_order = resources_meta.get('groups_order')
    for g in resource_groups.keys():
        if not g in groups_order:
            groups_order.append(g)

    # order resources, also include unknown resources
    resources_order = resources_meta.get('resources_order')
    for r in resource_keys:
        if not r in resources_order:
            resources_order.append(r)

    # sort catalog groups
    resource_catalog = sorted(resource_catalog,
                              key=lambda g: groups_order.index(g[0]))

    # sort groups
    def groupindex(g):
        return groups_order.index(g[0])

    resource_groups_list = sorted([(k, v) for k, v in resource_groups.items()],
                                  key=groupindex)
    resource_groups = OrderedDict(resource_groups_list)

    # sort resources
    def resourceindex(r):
        return resources_order.index(r['str_repr'])

    for index, group in enumerate(resource_catalog):
        resource_catalog[index][1] = sorted(resource_catalog[index][1],
                                            key=resourceindex)
        if len(resource_catalog[index][1]) == 0:
            resource_catalog.pop(index)
            for gindex, g in enumerate(resource_groups):
                if g[0] == group[0]:
                    resource_groups.pop(gindex)

    # filter out resources which user cannot request in a project application
    for group, resources in list(resource_catalog):
        for resource in resources:
            if not resource.get('ui_visible'):
                resources.remove(resource)

    # cleanup empty groups
    resource_catalog_new = []
    for group, resources in list(resource_catalog):
        if len(resources) == 0:
            resource_groups.pop(group)
        else:
            resource_catalog_new.append((group, resources))

    if as_dict:
        resource_catalog_new = OrderedDict(resource_catalog_new)
        for name, resources in resource_catalog_new.iteritems():
            _rs = OrderedDict()
            for resource in resources:
                _rs[resource.get('name')] = resource
            resource_catalog_new[name] = _rs
        resource_groups = OrderedDict(resource_groups)

    return resource_catalog_new, resource_groups
示例#26
0
    def handle(self, *args, **options):
        write = self.stderr.write
        if options["list_resources"]:
            self.help_resources(options)
            exit()

        fix = options["fix"]
        force = options["force"]
        handlers = self.get_handlers(options["resources"],
                                     options["soft_resources"])
        maxops = options["max_operations"]
        if maxops is not None:
            try:
                maxops = int(maxops)
            except ValueError:
                m = "Expected integer max operations."
                raise CommandError(m)

        shutdown_timeout = options["shutdown_timeout"]
        if shutdown_timeout is not None:
            try:
                shutdown_timeout = int(shutdown_timeout)
            except ValueError:
                m = "Expected integer shutdown timeout."
                raise CommandError(m)

        remove_system_volumes = options["remove_system_volumes"]
        cascade_remove = options["cascade_remove"]

        excluded_users = options['exclude_users']
        excluded_users = set(
            excluded_users.split(',') if excluded_users is not None else [])

        users_to_check = options['users']
        if users_to_check is not None:
            users_to_check = list(
                set(users_to_check.split(',')) - excluded_users)

        try:
            qh_holdings = util.get_qh_users_holdings(users_to_check)
        except errors.AstakosClientException as e:
            raise CommandError(e)

        excluded_projects = options["exclude_projects"]
        excluded_projects = set(
            excluded_projects.split(','
                                    ) if excluded_projects is not None else [])

        projects_to_check = options["projects"]
        if projects_to_check is not None:
            projects_to_check = list(
                set(projects_to_check.split(',')) - excluded_projects)

        try:
            qh_project_holdings = util.get_qh_project_holdings(
                projects_to_check)
        except errors.AstakosClientException as e:
            raise CommandError(e)

        qh_project_holdings = sorted(qh_project_holdings.items())
        qh_holdings = sorted(qh_holdings.items())
        resources = set(h[0] for h in handlers if not h[1])
        dangerous = bool(resources.intersection(DESTROY_RESOURCES))
        if resources:
            self.stderr.write("Checking resources %s...\n" %
                              ",".join(list(resources)))
        resources_soft = set(h[0] for h in handlers if h[1])
        if resources_soft:
            self.stderr.write("Checking resources for soft enforce %s...\n" %
                              ",".join(list(resources_soft)))
        if not resources and not resources_soft:
            self.stderr.write("No resources specified; use '--list-resources' "
                              "to list available resources.\n")
            exit()

        hopts = {
            "cascade_remove": cascade_remove,
            "remove_system_volumes": remove_system_volumes,
        }
        opts = {"shutdown_timeout": shutdown_timeout}
        actions = {}
        overlimit = []
        viol_id = 0
        remains = defaultdict(list)

        if users_to_check is None:
            for resource, is_soft, handle_resource, resource_type in handlers:
                if resource_type not in actions:
                    actions[resource_type] = OrderedDict()
                actual_resources = enforce.get_actual_resources(
                    resource_type, projects=projects_to_check)
                for project, project_quota in qh_project_holdings:
                    if enforce.skip_check(project, projects_to_check,
                                          excluded_projects):
                        continue
                    try:
                        qh = util.transform_project_quotas(project_quota)
                        qh_value, qh_limit, qh_pending = qh[resource]
                    except KeyError:
                        write("Resource '%s' does not exist in Quotaholder"
                              " for project '%s'!\n" % (resource, project))
                        continue
                    if qh_pending:
                        write("Pending commission for project '%s', "
                              "resource '%s'. Skipping\n" %
                              (project, resource))
                        continue
                    diff = qh_value - qh_limit
                    if diff > 0:
                        viol_id += 1
                        overlimit.append((viol_id, "project", project, "",
                                          resource, qh_limit, qh_value))
                        relevant_resources = enforce.pick_project_resources(
                            actual_resources[project],
                            users=users_to_check,
                            excluded_users=excluded_users)
                        handle_resource(viol_id,
                                        resource,
                                        relevant_resources,
                                        diff,
                                        actions,
                                        remains,
                                        options=hopts)

        for resource, is_soft, handle_resource, resource_type in handlers:
            if resource_type not in actions:
                actions[resource_type] = OrderedDict()
            actual_resources = enforce.get_actual_resources(
                resource_type, users_to_check)
            for user, user_quota in qh_holdings:
                if enforce.skip_check(user, users_to_check, excluded_users):
                    continue
                for source, source_quota in user_quota.iteritems():
                    if enforce.skip_check(source, projects_to_check,
                                          excluded_projects):
                        continue
                    try:
                        qh = util.transform_quotas(source_quota)
                        qh_value, qh_limit, qh_pending = qh[resource]
                    except KeyError:
                        write("Resource '%s' does not exist in Quotaholder"
                              " for user '%s' and source '%s'!\n" %
                              (resource, user, source))
                        continue
                    if qh_pending:
                        write("Pending commission for user '%s', source '%s', "
                              "resource '%s'. Skipping\n" %
                              (user, source, resource))
                        continue
                    diff = qh_value - qh_limit
                    if diff > 0:
                        viol_id += 1
                        overlimit.append((viol_id, "user", user, source,
                                          resource, qh_limit, qh_value))
                        relevant_resources = actual_resources[source][user]
                        handle_resource(viol_id,
                                        resource,
                                        relevant_resources,
                                        diff,
                                        actions,
                                        remains,
                                        options=hopts)

        if not overlimit:
            write("No violations.\n")
            return

        headers = ("#", "Type", "Holder", "Source", "Resource", "Limit",
                   "Usage")
        pprint_table(self.stdout,
                     overlimit,
                     headers,
                     options["output_format"],
                     title="Violations")

        if any(actions.values()):
            self.stdout.write("\n")
            if fix:
                if dangerous and not force:
                    write("You are enforcing resources that may permanently "
                          "remove a VM, volume, or IP.\n")
                    self.confirm()
                write("Applying actions. Please wait...\n")
            title = "Applied Actions" if fix else "Suggested Actions"
            log = enforce.perform_actions(actions,
                                          maxops=maxops,
                                          fix=fix,
                                          options=opts)
            headers = ("Type", "ID", "State", "Backend", "Action", "Violation")
            if fix:
                headers += ("Result", )
            pprint_table(self.stdout,
                         log,
                         headers,
                         options["output_format"],
                         title=title)

        def explain(resource):
            if resource == "cyclades.disk":
                if not remove_system_volumes:
                    return (", because this would need to remove system "
                            "volumes; if you want to do so, use the "
                            "--remove-system-volumes option:")
                if not cascade_remove:
                    return (", because this would trigger the removal of "
                            "attached volumes, too; if you want to do "
                            "so, use the --cascade-remove option:")
            elif resource in DESTROY_RESOURCES:
                if not cascade_remove:
                    return (", because this would trigger the removal of "
                            "attached volumes, too; if you want to do "
                            "so, use the --cascade-remove option:")
            return ":"

        if remains:
            self.stderr.write("\n")
            for resource, viols in remains.iteritems():
                self.stderr.write("The following violations for resource '%s' "
                                  "could not be resolved%s\n" %
                                  (resource, explain(resource)))
                self.stderr.write("  %s\n" % ",".join(map(str, viols)))
示例#27
0
文件: units.py 项目: kins299/mycloud
def parse(s):
    n, _ = parse_with_style(s)
    return n


UNITS = {
    'bytes': {
        'DISPLAY': ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'],
        'BASE': 1024,
    }
}

STYLE_TO_EXP = OrderedDict([
    ('b', 0),
    ('kb', 1),
    ('mb', 2),
    ('gb', 3),
    ('tb', 4),
    ('pb', 5),
])

STYLES = STYLE_TO_EXP.keys() + ['auto', 'none']


class StyleError(Exception):
    pass


def show_float(n):
    if n < 1:
        return "%.3f" % n
    if n < 10:
示例#28
0
    def handle(self, *args, **options):
        if len(args) != 1:
            raise CommandError("Please provide a user ID or email")

        identifier = args[0]
        if identifier.isdigit():
            users = AstakosUser.objects.filter(id=int(identifier))
        else:
            try:
                uuid.UUID(identifier)
            except:
                users = AstakosUser.objects.filter(email__iexact=identifier)
            else:
                users = AstakosUser.objects.filter(uuid=identifier)
        if users.count() == 0:
            field = 'id' if identifier.isdigit() else 'email'
            msg = "Unknown user with %s '%s'" % (field, identifier)
            raise CommandError(msg)

        for user in users:
            kv = OrderedDict([
                ('id', user.id),
                ('uuid', user.uuid),
                ('status', user.status_display),
                ('email', user.email),
                ('first name', user.first_name),
                ('last name', user.last_name),
                ('admin', user.is_superuser),
                ('last login', user.last_login),
                ('date joined', user.date_joined),
                ('last update', user.updated),
                #('token', user.auth_token),
                ('token expiration', user.auth_token_expires),
                ('providers', user.auth_providers_display),
                ('groups', [elem.name for elem in user.groups.all()]),
                ('permissions',
                 [elem.codename for elem in user.user_permissions.all()]),
                ('group permissions', user.get_group_permissions()),
                ('email_verified', user.email_verified),
                ('moderated', user.moderated),
                ('rejected', user.is_rejected),
                ('active', user.is_active),
                ('username', user.username),
                ('activation_sent_date', user.activation_sent),
                ('last_login_details', user.last_login_info_display),
            ])

            if get_latest_terms():
                has_signed_terms = user.signed_terms
                kv['has_signed_terms'] = has_signed_terms
                if has_signed_terms:
                    kv['date_signed_terms'] = user.date_signed_terms

            utils.pprint_table(self.stdout, [kv.values()],
                               kv.keys(),
                               options["output_format"],
                               vertical=True)

            if options["list_quotas"] and user.is_accepted():
                unit_style = options["unit_style"]
                check_style(unit_style)

                quotas = get_user_quotas(user)
                if quotas:
                    self.stdout.write("\n")
                    print_data, labels = show_user_quotas(quotas,
                                                          style=unit_style)
                    utils.pprint_table(self.stdout,
                                       print_data,
                                       labels,
                                       options["output_format"],
                                       title="User Quota")

            if options["list_projects"]:
                print_data, labels = ownerships(user)
                if print_data:
                    self.stdout.write("\n")
                    utils.pprint_table(self.stdout,
                                       print_data,
                                       labels,
                                       options["output_format"],
                                       title="Owned Projects")

                print_data, labels = memberships(user)
                if print_data:
                    self.stdout.write("\n")
                    utils.pprint_table(self.stdout,
                                       print_data,
                                       labels,
                                       options["output_format"],
                                       title="Project Memberships")
示例#29
0
class AuthProvider(object):

    __metaclass__ = AuthProviderBase

    module = None
    module_enabled = False
    is_primary = False

    message_tpls = OrderedDict((
        ('title', '{module_title}'),
        ('login_title', '{title} LOGIN'),
        ('method_prompt', '{title} login'),
        ('account_prompt', '{title} account'),
        ('signup_title', '{title}'),
        ('profile_title', '{title}'),
        ('method_details', '{account_prompt}: {identifier}'),
        ('primary_login_prompt', 'Login using {account_prompt}'),
        ('required', '{title} is required. You can assign it '
         'from your profile page'),
        ('login_prompt', ''),
        ('add_prompt', 'Allows you to login using {title}'),
        ('login_extra', ''),
        ('username', '{username}'),
        ('disabled_for_create', 'It seems this is the first time you\'re '
         'trying to access {service_name}. '
         'Unfortunately, we are not accepting new '
         'users at this point.'),
        ('switch_success', 'Account changed successfully.'),
        ('cannot_login', '{title} is not available for login. '
         'Please use one of your other available methods '
         'to login ({available_methods_links}'),

        # icons should end with _icon
        ('module_medium_icon', 'im/auth/icons-medium/{module}.png'),
        ('module_icon', 'im/auth/icons/{module}.png')))

    messages = {}
    module_urls = {}

    remote_authenticate = True
    remote_logout_url = None

    # templates
    primary_login_template = 'im/auth/generic_primary_login.html'
    login_template = 'im/auth/generic_login.html'
    signup_template = 'im/signup.html'
    login_prompt_template = 'im/auth/generic_login_prompt.html'
    signup_prompt_template = 'im/auth/signup_prompt.html'

    default_policies = {
        'login': True,
        'create': True,
        'add': True,
        'remove': True,
        'limit': 1,
        'switch': True,
        'add_groups': [],
        'creation_groups': [],
        'mirror_groups': False,  # Currently used only by LDAP
        'required': False,
        'autoverify': False,
        'automoderate': not astakos_settings.MODERATION_ENABLED
    }

    # Mapping of provider's attributes to attributes of AstakosUser.
    # The second element of the tuple dictates whether the attribute can be
    # changed by the user or is automatically set by the provider in every
    # login.
    # Identifier is used to get the unique user identifier of the third
    # party provider!
    user_attr_map = {
        # 'user field': ('provider field', 'mutable by user')
        'identifier': ('uuid', False),
        'email': ('email', True),
        'first_name': ('first_name', True),
        'last_name': ('last_name', True),
    }

    policies = {}

    def __init__(self, user=None, identifier=None, **provider_params):
        """
        3 ways to initialize (no args, user, user and identifier).

        no args: Used for anonymous unauthenticated users.
        >>> p = auth_providers.get_provider('local')
        >>> # check that global settings allows us to create a new account
        >>> # using `local` provider.
        >>> print p.is_available_for_create()

        user and identifier: Used to provide details about a user's specific
        login method.
        >>> p = auth_providers.get_provider('google', user,
        >>>                                 identifier='1421421')
        >>> # provider (google) details prompt
        >>> print p.get_method_details()
        "Google account: 1421421"
        """

        # handle AnonymousUser instance
        self.user = None
        if user and hasattr(user, 'pk') and user.pk:
            self.user = user

        self.identifier = identifier
        self._instance = None
        if 'instance' in provider_params:
            self._instance = provider_params['instance']
            del provider_params['instance']

        # initialize policies
        self.module_policies = copy.copy(self.default_policies)
        for policy, value in self.policies.iteritems():
            setting_key = "%s_POLICY" % policy.upper()
            if self.has_setting(setting_key):
                self.module_policies[policy] = self.get_setting(setting_key)
            else:
                self.module_policies[policy] = value

        # messages cache
        self.message_tpls_compiled = OrderedDict()

        # module specific messages
        self.message_tpls = OrderedDict(self.message_tpls)
        for key, value in self.messages.iteritems():
            self.message_tpls[key] = value

        self._provider_details = provider_params

        self.resolve_available_methods = True

    def get_provider_model(self):
        from astakos.im.models import AstakosUserAuthProvider as AuthProvider
        return AuthProvider

    def update_last_login_at(self):
        instance = self._instance
        user = instance.user.__class__.objects.get(pk=instance.user.pk)
        date = datetime.now()
        instance.last_login_at = user.last_login = date
        instance.save()
        user.save()

    def remove_from_user(self):
        if not self.get_remove_policy:
            raise Exception("Provider cannot be removed")

        for group_name in self.get_add_groups_policy:
            group = Group.objects.get(name=group_name)
            self.user.groups.remove(group)
            self.log('removed from group due to add_groups_policy %s',
                     group.name)

        self._instance.delete()
        self.log('removed')

    def add_to_user(self, **params):
        # db lock
        objects = self.user.__class__.objects
        self.user = objects.select_for_update().get(pk=self.user.pk)

        if self._instance:
            raise Exception("Cannot add an existing provider")

        create = False
        if self.get_user_active_providers().count() == 0:
            create = True

        if create and not self.get_create_policy:
            raise Exception("Provider not available for create")

        if not self.get_add_policy:
            raise Exception("Provider cannot be added")

        if create:
            for group_name in self.get_creation_groups_policy:
                group, created = Group.objects.get_or_create(name=group_name)
                self.user.groups.add(group)
                self.log("added to %s group due to creation_groups_policy",
                         group_name)

        for group_name in self.get_add_groups_policy:
            group, created = Group.objects.get_or_create(name=group_name)
            self.user.groups.add(group)
            self.log("added to %s group due to add_groups_policy", group_name)

        if self.identifier:
            pending = self.get_provider_model().objects.unverified(
                self.module, identifier=self.identifier)

            if pending:
                user = pending._instance.user
                logger.info("Removing existing unverified user (%r)",
                            user.log_display)
                user.base_project and user.base_project.delete()
                user.delete()

        create_params = {
            'module': self.module,
            'info_data': json.dumps(self.provider_details.get('info', {})),
            'active': True,
            'identifier': self.identifier
        }
        if 'info' in self.provider_details:
            del self.provider_details['info']

        create_params.update(self.provider_details)
        create_params.update(params)
        create = self.user.auth_providers.create(**create_params)
        self.log("created %r" % create_params)
        return create

    def __repr__(self):
        r = "'%r' module" % self.__class__.__name__
        if self.user:
            r += ' (user: %r)' % self.user
        if self.identifier:
            r += '(identifier: %r)' % self.identifier
        return r

    def _message_params(self, **extra_params):
        """
        Retrieve message formating parameters.
        """
        params = {'module': self.module, 'module_title': self.module.title()}
        if self.identifier:
            params['identifier'] = self.identifier

        if self.user:
            for key, val in self.user.__dict__.iteritems():
                params["user_%s" % key.lower()] = val

        if self.provider_details:
            for key, val in self.provider_details.iteritems():
                params["provider_%s" % key.lower()] = val

            if 'info' in self.provider_details:
                if isinstance(self.provider_details['info'], basestring):
                    self.provider_details['info'] = \
                        json.loads(self.provider_details['info'])
                for key, val in self.provider_details['info'].iteritems():
                    params['provider_info_%s' % key.lower()] = val

        # resolve username, handle unexisting defined username key
        if self.user and self.username_key in params:
            params['username'] = params[self.username_key]
        else:
            params['username'] = self.identifier

        branding_params = dict(
            map(lambda k: (k[0].lower(), k[1]),
                branding_utils.get_branding_dict().iteritems()))
        params.update(branding_params)

        if not self.message_tpls_compiled:
            for key, message_tpl in self.message_tpls.iteritems():
                msg = self.messages.get(key, self.message_tpls.get(key))
                override_in_settings = self.get_setting(key)
                if override_in_settings is not None:
                    msg = override_in_settings
                try:
                    tpl = smart_unicode(msg)
                    self.message_tpls_compiled[key] = tpl.format(**params)
                    params.update(self.message_tpls_compiled)
                except KeyError:
                    continue
        else:
            params.update(self.message_tpls_compiled)

        for key, value in self.urls.iteritems():
            params['%s_url' % key] = value

        if self.user and self.resolve_available_methods:
            available_providers = self.user.get_enabled_auth_providers()
            for p in available_providers:
                p.resolve_available_methods = False
                if p.module == self.module and p.identifier == self.identifier:
                    available_providers.remove(p)

            get_msg = lambda p: p.get_method_prompt_msg
            params['available_methods'] = \
                ','.join(map(get_msg, available_providers))

            get_msg = lambda p: "<a href='%s'>%s</a>" % \
                (p.get_login_url, p.get_method_prompt_msg)

            params['available_methods_links'] = \
                ','.join(map(get_msg, available_providers))

        params.update(extra_params)
        return params

    def get_template(self, tpl):
        tpls = [
            'im/auth/%s_%s.html' % (self.module, tpl),
            getattr(self, '%s_template' % tpl)
        ]
        found = None
        for tpl in tpls:
            try:
                found = template.loader.get_template(tpl)
                return tpl
            except template.TemplateDoesNotExist:
                continue
        if not found:
            raise template.TemplateDoesNotExist
        return tpl

    def get_username(self):
        return self.get_username_msg

    def get_user_providers(self):
        return self.user.auth_providers.filter(
            module__in=astakos_settings.IM_MODULES)

    def get_user_active_providers(self):
        return self.user.auth_providers.active().filter(
            module__in=astakos_settings.IM_MODULES)

    def get_user_module_providers(self):
        return self.user.auth_providers.filter(module=self.module)

    def get_user_module_active_providers(self):
        return self.user.auth_providers.active().filter(module=self.module)

    def get_existing_providers(self):
        return ""

    def verified_exists(self):
        return self.get_provider_model().objects.verified(
            self.module, identifier=self.identifier)

    def resolve_policy(self, policy, default=None):

        if policy == 'switch' and default and not self.get_add_policy:
            return not self.get_policy('remove')

        if not self.user:
            return default

        if policy == 'remove' and default is True:
            return self.get_user_active_providers().count() > 1

        if policy == 'add' and default is True:
            limit = self.get_policy('limit')
            if limit <= self.get_user_module_active_providers().count():
                return False

            if self.identifier:
                if self.verified_exists():
                    return False

        return default

    def get_user_policies(self):
        from astakos.im.models import AuthProviderPolicyProfile
        return AuthProviderPolicyProfile.objects.for_user(
            self.user, self.module)

    def get_user_attr_map(self):
        """Get the mapping of provider to user attributes."""
        attr_map = self.user_attr_map
        settings_key = "USER_ATTR_MAP"
        settings_default = self.get_setting(settings_key, attr_map)
        attr_map.update(settings_default)
        return attr_map

    def get_provider_forced_attributes(self):
        """List of attributes that are automatically set by the provider."""
        attr_map = self.get_user_attr_map()
        return [
            attr for attr, (provider_attr, mutable) in attr_map.items()
            if not mutable
        ]

    def get_provider_info_attributes(self):
        """List of providers attributes to be stored in Astakos DB.

        Get list of provider's attributes that will be stored in Astakos DB
        in the 'info_data' field.

        """
        return self.get_setting("PROVIDER_ATTRS", [])

    def get_policy(self, policy):
        module_default = self.module_policies.get(policy)
        settings_key = '%s_POLICY' % policy.upper()
        settings_default = self.get_setting(settings_key, module_default)

        if self.user:
            user_policies = self.get_user_policies()
            settings_default = user_policies.get(policy, settings_default)

        return self.resolve_policy(policy, settings_default)

    def get_message(self, msg, **extra_params):
        """
        Retrieve an auth provider message
        """
        if msg.endswith('_msg'):
            msg = msg.replace('_msg', '')
        params = self._message_params(**extra_params)

        # is message ???
        tpl = self.message_tpls_compiled.get(msg.lower(), None)
        if not tpl:
            msg_key = 'AUTH_PROVIDER_%s' % msg.upper()
            try:
                tpl = getattr(astakos_messages, msg_key)
            except AttributeError:
                try:
                    msg_key = msg.upper()
                    tpl = getattr(astakos_messages, msg_key)
                except AttributeError:
                    tpl = ''

        in_settings = self.get_setting(msg)
        if in_settings:
            tpl = in_settings

        return tpl.format(**params)

    @property
    def urls(self):
        urls = {
            'login': reverse(self.login_view),
            'add': reverse(self.login_view),
            'profile': reverse('edit_profile'),
        }
        if self.user:
            urls.update({
                'resend_activation':
                self.user.get_resend_activation_url(),
            })
        if self.identifier and self._instance:
            urls.update({
                'switch':
                reverse(self.login_view) +
                '?switch_from=%d' % self._instance.pk,
                'remove':
                reverse('remove_auth_provider',
                        kwargs={'pk': self._instance.pk})
            })
        urls.update(self.module_urls)
        return urls

    def get_setting_key(self, name):
        return 'ASTAKOS_AUTH_PROVIDER_%s_%s' % (self.module.upper(),
                                                name.upper())

    def get_global_setting_key(self, name):
        return 'ASTAKOS_AUTH_PROVIDERS_%s' % name.upper()

    def has_global_setting(self, name):
        return hasattr(settings, self.get_global_setting_key(name))

    def has_setting(self, name):
        return hasattr(settings, self.get_setting_key(name))

    def get_setting(self, name, default=None):
        attr = self.get_setting_key(name)
        if not self.has_setting(name):
            return self.get_global_setting(name, default)
        return getattr(settings, attr, default)

    def get_global_setting(self, name, default=None):
        attr = self.get_global_setting_key(name)
        if not self.has_global_setting(name):
            return default
        return getattr(settings, attr, default)

    @property
    def provider_details(self):
        if self._provider_details:
            return self._provider_details

        self._provider_details = {}

        if self._instance:
            self._provider_details = self._instance.__dict__

        if self.user and self.identifier:
            if self.identifier:
                try:
                    self._provider_details = \
                        self.user.get_auth_providers().get(
                            module=self.module,
                            identifier=self.identifier).__dict__
                except Exception:
                    return {}
        return self._provider_details

    def __getattr__(self, key):
        if not key.startswith('get_'):
            return super(AuthProvider, self).__getattribute__(key)

        key = key.replace('get_', '')
        if key.endswith('_msg'):
            return self.get_message(key)

        if key.endswith('_policy'):
            return self.get_policy(key.replace('_policy', ''))

        if key.endswith('_url'):
            key = key.replace('_url', '')
            return self.urls.get(key)

        if key.endswith('_icon'):
            key = key.replace('_msg', '_icon')
            return settings.MEDIA_URL + self.get_message(key)

        if key.endswith('_setting'):
            key = key.replace('_setting', '')
            return self.get_message(key)

        if key.endswith('_template'):
            key = key.replace('_template', '')
            return self.get_template(key)

        return super(AuthProvider, self).__getattribute__(key)

    def is_active(self):
        return self.module_enabled

    @property
    def log_display(self):
        dsp = "%sAuth" % self.module.title()
        if self.user:
            dsp += "[%s]" % self.user.log_display
            if self.identifier:
                dsp += '[%s]' % self.identifier
                if self._instance and self._instance.pk:
                    dsp += '[%d]' % self._instance.pk
        return dsp

    def log(self, msg, *args, **kwargs):
        level = kwargs.pop('level', logging.INFO)
        message = '%s: %s' % (self.log_display, msg)
        logger.log(level, message, *args, **kwargs)
示例#30
0
class AuthProvider(object):

    __metaclass__ = AuthProviderBase

    module = None
    module_enabled = False
    is_primary = False

    message_tpls = OrderedDict((
        ('title', '{module_title}'),
        ('login_title', '{title} LOGIN'),
        ('method_prompt', '{title} login'),
        ('account_prompt', '{title} account'),
        ('signup_title', '{title}'),
        ('profile_title', '{title}'),
        ('method_details', '{account_prompt}: {identifier}'),
        ('primary_login_prompt', 'Login using '),
        ('required', '{title} is required. You can assign it '
         'from your profile page'),
        ('login_prompt', ''),
        ('add_prompt', 'Allows you to login using {title}'),
        ('login_extra', ''),
        ('username', '{username}'),
        ('disabled_for_create', 'It seems this is the first time you\'re '
         'trying to access {service_name}. '
         'Unfortunately, we are not accepting new '
         'users at this point.'),
        ('switch_success', 'Account changed successfully.'),
        ('cannot_login', '{title} is not available for login. '
         'Please use one of your other available methods '
         'to login ({available_methods_links}'),

        # icons should end with _icon
        ('module_medium_icon', 'im/auth/icons-medium/{module}.png'),
        ('module_icon', 'im/auth/icons/{module}.png')))

    messages = {}
    module_urls = {}

    remote_authenticate = True
    remote_logout_url = None

    # templates
    primary_login_template = 'im/auth/generic_primary_login.html'
    login_template = 'im/auth/generic_login.html'
    signup_template = 'im/signup.html'
    login_prompt_template = 'im/auth/generic_login_prompt.html'
    signup_prompt_template = 'im/auth/signup_prompt.html'

    default_policies = {
        'login': True,
        'create': True,
        'add': True,
        'remove': True,
        'limit': 1,
        'switch': True,
        'add_groups': [],
        'creation_groups': [],
        'required': False,
        'automoderate': not astakos_settings.MODERATION_ENABLED
    }

    policies = {}

    def __init__(self, user=None, identifier=None, **provider_params):
        """
        3 ways to initialize (no args, user, user and identifier).

        no args: Used for anonymous unauthenticated users.
        >>> p = auth_providers.get_provider('local')
        >>> # check that global settings allows us to create a new account
        >>> # using `local` provider.
        >>> print p.is_available_for_create()

        user and identifier: Used to provide details about a user's specific
        login method.
        >>> p = auth_providers.get_provider('google', user,
        >>>                                 identifier='1421421')
        >>> # provider (google) details prompt
        >>> print p.get_method_details()
        "Google account: 1421421"
        """

        # handle AnonymousUser instance
        self.user = None
        if user and hasattr(user, 'pk') and user.pk:
            self.user = user

        self.identifier = identifier
        self._instance = None
        if 'instance' in provider_params:
            self._instance = provider_params['instance']
            del provider_params['instance']

        # initialize policies
        self.module_policies = copy.copy(self.default_policies)
        self.module_policies['automoderate'] = not \
            astakos_settings.MODERATION_ENABLED
        for policy, value in self.policies.iteritems():
            setting_key = "%s_POLICY" % policy.upper()
            if self.has_setting(setting_key):
                self.module_policies[policy] = self.get_setting(setting_key)
            else:
                self.module_policies[policy] = value

        # messages cache
        self.message_tpls_compiled = OrderedDict()

        # module specific messages
        self.message_tpls = OrderedDict(self.message_tpls)
        for key, value in self.messages.iteritems():
            self.message_tpls[key] = value

        self._provider_details = provider_params

        self.resolve_available_methods = True

    def get_provider_model(self):
        from astakos.im.models import AstakosUserAuthProvider as AuthProvider
        return AuthProvider

    def remove_from_user(self):
        if not self.get_remove_policy:
            raise Exception("Provider cannot be removed")

        for group_name in self.get_add_groups_policy:
            group = Group.objects.get(name=group_name)
            self.user.groups.remove(group)
            self.log('removed from group due to add_groups_policy %s',
                     group.name)

        self._instance.delete()
        self.log('removed')

    def add_to_user(self, **params):
        if self._instance:
            raise Exception("Cannot add an existing provider")

        create = False
        if self.get_user_providers().count() == 0:
            create = True

        if create and not self.get_create_policy:
            raise Exception("Provider not available for create")

        if not self.get_add_policy:
            raise Exception("Provider cannot be added")

        if create:
            for group_name in self.get_creation_groups_policy:
                group, created = Group.objects.get_or_create(name=group_name)
                self.user.groups.add(group)
                self.log("added to %s group due to creation_groups_policy",
                         group_name)

        for group_name in self.get_add_groups_policy:
            group, created = Group.objects.get_or_create(name=group_name)
            self.user.groups.add(group)
            self.log("added to %s group due to add_groups_policy", group_name)

        if self.identifier:
            pending = self.get_provider_model().objects.unverified(
                self.module, identifier=self.identifier)

            if pending:
                user = pending._instance.user
                logger.info("Removing existing unverified user (%r)",
                            user.log_display)
                user.delete()

        create_params = {
            'module': self.module,
            'info_data': json.dumps(self.provider_details.get('info', {})),
            'active': True,
            'identifier': self.identifier
        }
        if 'info' in self.provider_details:
            del self.provider_details['info']

        create_params.update(self.provider_details)
        create_params.update(params)
        create = self.user.auth_providers.create(**create_params)
        self.log("created %r" % create_params)
        return create

    def __repr__(self):
        r = "'%r' module" % self.__class__.__name__
        if self.user:
            r += ' (user: %r)' % self.user
        if self.identifier:
            r += '(identifier: %r)' % self.identifier
        return r

    def _message_params(self, **extra_params):
        """
        Retrieve message formating parameters.
        """
        params = {'module': self.module, 'module_title': self.module.title()}
        if self.identifier:
            params['identifier'] = self.identifier

        if self.user:
            for key, val in self.user.__dict__.iteritems():
                params["user_%s" % key.lower()] = val

        if self.provider_details:
            for key, val in self.provider_details.iteritems():
                params["provider_%s" % key.lower()] = val

            if 'info' in self.provider_details:
                if isinstance(self.provider_details['info'], basestring):
                    self.provider_details['info'] = \
                        json.loads(self.provider_details['info'])
                for key, val in self.provider_details['info'].iteritems():
                    params['provider_info_%s' % key.lower()] = val

        # resolve username, handle unexisting defined username key
        if self.user and self.username_key in params:
            params['username'] = params[self.username_key]
        else:
            params['username'] = self.identifier

        branding_params = dict(
            map(lambda k: (k[0].lower(), k[1]),
                branding_utils.get_branding_dict().iteritems()))
        params.update(branding_params)

        if not self.message_tpls_compiled:
            for key, message_tpl in self.message_tpls.iteritems():
                msg = self.messages.get(key, self.message_tpls.get(key))
                override_in_settings = self.get_setting(key)
                if override_in_settings is not None:
                    msg = override_in_settings
                try:
                    self.message_tpls_compiled[key] = msg.format(**params)
                    params.update(self.message_tpls_compiled)
                except KeyError, e:
                    continue
        else: