summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Babinsky <mbabinsk@redhat.com>2016-06-23 18:23:00 +0200
committerMartin Basti <mbasti@redhat.com>2016-07-01 09:37:25 +0200
commit974eb7b5efd20ad2195b0ad578637ab31f4c1df4 (patch)
tree4e9893aded56953876550d1588ca26887ec98c6f
parente6fc8f84d3ad5fc4c030ad592a3d743c02393439 (diff)
downloadfreeipa-974eb7b5efd20ad2195b0ad578637ab31f4c1df4.tar.gz
freeipa-974eb7b5efd20ad2195b0ad578637ab31f4c1df4.tar.xz
freeipa-974eb7b5efd20ad2195b0ad578637ab31f4c1df4.zip
ipalib: introduce Principal parameter
This patch introduces a separate Principal parameter that allows the framework to syntactically validate incoming/outcoming principals by using a single shared codebase. https://fedorahosted.org/freeipa/ticket/3864 Reviewed-By: David Kupka <dkupka@redhat.com> Reviewed-By: Jan Cholasta <jcholast@redhat.com>
-rw-r--r--ipaclient/remote_plugins/schema.py2
-rw-r--r--ipalib/parameters.py37
-rw-r--r--ipalib/rpc.py6
-rw-r--r--ipapython/ipaldap.py6
-rwxr-xr-xmakeapi1
-rw-r--r--pylint_plugins.py3
6 files changed, 54 insertions, 1 deletions
diff --git a/ipaclient/remote_plugins/schema.py b/ipaclient/remote_plugins/schema.py
index 8ce26e608..8ebc3a9f8 100644
--- a/ipaclient/remote_plugins/schema.py
+++ b/ipaclient/remote_plugins/schema.py
@@ -31,6 +31,7 @@ if six.PY3:
_TYPES = {
'DN': DN,
'DNSName': DNSName,
+ 'Principal': unicode,
'NoneType': type(None),
'Sequence': collections.Sequence,
'bool': bool,
@@ -45,6 +46,7 @@ _PARAMS = {
'Decimal': parameters.Decimal,
'DN': parameters.DNParam,
'DNSName': parameters.DNSNameParam,
+ 'Principal': parameters.Principal,
'bool': parameters.Bool,
'bytes': parameters.Bytes,
'datetime': parameters.DateTime,
diff --git a/ipalib/parameters.py b/ipalib/parameters.py
index a08113460..1581b7dca 100644
--- a/ipalib/parameters.py
+++ b/ipalib/parameters.py
@@ -115,9 +115,11 @@ from ipalib.errors import PasswordMismatch, Base64DecodeError
from ipalib.constants import TYPE_ERROR, CALLABLE_ERROR, LDAP_GENERALIZED_TIME_FORMAT
from ipalib.text import Gettext, FixMe
from ipalib.util import json_serialize, validate_idna_domain
+from ipapython import kerberos
from ipapython.dn import DN
from ipapython.dnsutil import DNSName
+
def _is_null(value):
return not value and value != 0 # NOTE: False == 0
@@ -1970,3 +1972,38 @@ class Dict(Param):
type = dict
type_error = _("must be dictionary")
+
+
+class Principal(Param):
+ """
+ Kerberos principal name
+ """
+
+ type = kerberos.Principal
+ type_error = _('must be Kerberos principal')
+ kwargs = Param.kwargs + (
+ ('require_service', bool, False),
+ )
+
+ @property
+ def allowed_types(self):
+ return (self.type, unicode)
+
+ def _convert_scalar(self, value, index=None):
+ if isinstance(value, unicode):
+ try:
+ value = kerberos.Principal(value)
+ except ValueError:
+ raise ConversionError(
+ name=self.get_param_name(),
+ error=_("Malformed principal: '%(value)s'") % dict(
+ value=value))
+
+ return super(Principal, self)._convert_scalar(value)
+
+ def _rule_require_service(self, _, value):
+ if self.require_service and not value.is_service:
+ raise ValidationError(
+ name=self.get_param_name(),
+ error=_("Service principal is required")
+ )
diff --git a/ipalib/rpc.py b/ipalib/rpc.py
index a549f0226..1c002895e 100644
--- a/ipalib/rpc.py
+++ b/ipalib/rpc.py
@@ -66,6 +66,7 @@ from ipalib.krb_utils import KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN, KRB5KRB_AP_ERR_TKT
KRB5_FCC_PERM, KRB5_FCC_NOFILE, KRB5_CC_FORMAT, \
KRB5_REALM_CANT_RESOLVE, KRB5_CC_NOTFOUND, get_principal
from ipapython.dn import DN
+from ipapython.kerberos import Principal
from ipalib.capabilities import VERSION_WITHOUT_CAPABILITIES
from ipalib import api
@@ -194,6 +195,9 @@ def xml_wrap(value, version):
else:
return unicode(value)
+ if isinstance(value, Principal):
+ return unicode(value)
+
assert type(value) in (unicode, float, bool, type(None)) + six.integer_types
return value
@@ -316,6 +320,8 @@ def json_encode_binary(val, version):
return {'__dns_name__': unicode(val)}
else:
return unicode(val)
+ elif isinstance(val, Principal):
+ return unicode(val)
else:
return val
diff --git a/ipapython/ipaldap.py b/ipapython/ipaldap.py
index 9258fafe1..704e71a94 100644
--- a/ipapython/ipaldap.py
+++ b/ipapython/ipaldap.py
@@ -42,6 +42,7 @@ from ipapython.ipautil import (
from ipapython.ipa_log_manager import log_mgr
from ipapython.dn import DN
from ipapython.dnsutil import DNSName
+from ipapython.kerberos import Principal
if six.PY3:
unicode = str
@@ -686,6 +687,8 @@ class LDAPClient(object):
'idnssoamname': DNSName,
'idnssoarname': DNSName,
'dnszoneidnsname': DNSName,
+ 'krbcanonicalname': Principal,
+ 'krbprincipalname': Principal,
'nsds5replicalastupdatestart': unicode,
'nsds5replicalastupdateend': unicode,
'nsds5replicalastinitstart': unicode,
@@ -847,7 +850,8 @@ class LDAPClient(object):
return 'TRUE'
else:
return 'FALSE'
- elif isinstance(val, (unicode, six.integer_types, Decimal, DN)):
+ elif isinstance(val, (unicode, six.integer_types, Decimal, DN,
+ Principal)):
return value_to_utf8(val)
elif isinstance(val, DNSName):
return val.to_text()
diff --git a/makeapi b/makeapi
index 594b8dbae..515dd6eb6 100755
--- a/makeapi
+++ b/makeapi
@@ -71,6 +71,7 @@ PARAM_IGNORED_KW_ATTRIBUTES = (
'pattern_errmsg',
'precision',
'primary_key',
+ 'require_service',
'query',
'sortorder',
)
diff --git a/pylint_plugins.py b/pylint_plugins.py
index 26a4efb6a..bf357737c 100644
--- a/pylint_plugins.py
+++ b/pylint_plugins.py
@@ -186,6 +186,9 @@ ipa_class_members = {
'only_absolute',
'only_relative',
],
+ 'ipalib.parameters.Principal': [
+ 'require_service',
+ ],
'ipalib.plugable.API': [
fake_api_env,
] + NAMESPACE_ATTRS + LOGGING_ATTRS,