/usr/lib/python2.7/dist-packages/maasserver/models/sshkey.py is in python-django-maas 1.5+bzr2252-0ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | # Copyright 2012 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
""":class:`SSHKey` and friends."""
from __future__ import (
absolute_import,
print_function,
unicode_literals,
)
str = None
__metaclass__ = type
__all__ = [
'SSHKey',
]
from cgi import escape
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.db.models import (
ForeignKey,
Manager,
TextField,
)
from django.utils.safestring import mark_safe
from maasserver import (
DefaultMeta,
logger,
)
from maasserver.models.cleansave import CleanSave
from maasserver.models.timestampedmodel import TimestampedModel
from twisted.conch.ssh.keys import Key
class SSHKeyManager(Manager):
"""A utility to manage the colletion of `SSHKey`s."""
def get_keys_for_user(self, user):
"""Return the text of the ssh keys associated with a user."""
return SSHKey.objects.filter(user=user).values_list('key', flat=True)
def validate_ssh_public_key(value):
"""Validate that the given value contains a valid SSH public key."""
try:
key = Key.fromString(value)
except Exception:
# twisted.conch.ssh.keys.Key.fromString raises all sorts of exceptions.
# Here, we catch them all and return a ValidationError since this
# method only aims at validating keys and not return the exact cause of
# the failure.
logger.exception("Invalid SSH public key")
raise ValidationError("Invalid SSH public key.")
else:
if not key.isPublic():
raise ValidationError(
"Invalid SSH public key (this key is a private key).")
HELLIPSIS = '…'
def get_html_display_for_key(key, size):
"""Return a compact HTML representation of this key with a boundary on
the size of the resulting string.
A key typically looks like this: 'key_type key_string comment'.
What we want here is display the key_type and, if possible (i.e. if it
fits in the boundary that `size` gives us), the comment. If possible we
also want to display a truncated key_string. If the comment is too big
to fit in, we simply display a cropped version of the whole string.
:param key: The key for which we want an HTML representation.
:type name: unicode
:param size: The maximum size of the representation. This may not be
met exactly.
:type size: int
:return: The HTML representation of this key.
:rtype: unicode
"""
key = key.strip()
key_parts = key.split(' ', 2)
if len(key_parts) == 3:
key_type = key_parts[0]
key_string = key_parts[1]
comment = key_parts[2]
room_for_key = (
size - (len(key_type) + len(comment) + len(HELLIPSIS) + 2))
if room_for_key > 0:
return '%s %.*s%s %s' % (
escape(key_type, quote=True),
room_for_key,
escape(key_string, quote=True),
HELLIPSIS,
escape(comment, quote=True))
if len(key) > size:
return '%.*s%s' % (
size - len(HELLIPSIS),
escape(key, quote=True),
HELLIPSIS)
else:
return escape(key, quote=True)
MAX_KEY_DISPLAY = 50
class SSHKey(CleanSave, TimestampedModel):
"""An `SSHKey` represents a user public SSH key.
Users will be able to access allocated nodes using any of their
registered keys.
:ivar user: The user which owns the key.
:ivar key: The SSH public key.
"""
objects = SSHKeyManager()
user = ForeignKey(User, null=False, editable=False)
key = TextField(
null=False, editable=True, validators=[validate_ssh_public_key])
class Meta(DefaultMeta):
verbose_name = "SSH key"
unique_together = ('user', 'key')
def unique_error_message(self, model_class, unique_check):
if unique_check == ('user', 'key'):
return "This key has already been added for this user."
return super(
SSHKey, self).unique_error_message(model_class, unique_check)
def __unicode__(self):
return self.key
def display_html(self):
"""Return a compact HTML representation of this key.
:return: The HTML representation of this key.
:rtype: unicode
"""
return mark_safe(get_html_display_for_key(self.key, MAX_KEY_DISPLAY))
|