Sanitize all entity names
Only allow string.letters, string.digits, "-" and "_". Fixes-bug: #1295962 Change-Id: I582dfb20d146d7f4f67efe9b0ac33d1841a310a9
This commit is contained in:
@@ -110,7 +110,7 @@ class TestAssemblyController(base.TestCase):
|
||||
def test_assemblies_put(self):
|
||||
uuid, plan_uuid = self._create_assembly()
|
||||
uri = "%s/v1/plans/%s" % (self.client.base_url, plan_uuid)
|
||||
updated_data = {"name": "test_assembly updated",
|
||||
updated_data = {"name": "test_assembly_updated",
|
||||
"description": "A test to create assembly updated",
|
||||
"plan_uri": uri,
|
||||
"project_id": "project_id updated",
|
||||
@@ -125,7 +125,7 @@ class TestAssemblyController(base.TestCase):
|
||||
self._delete_assembly(uuid, plan_uuid)
|
||||
|
||||
def test_assemblies_put_not_found(self):
|
||||
updated_data = {"name": "test_assembly updated",
|
||||
updated_data = {"name": "test_assembly_updated",
|
||||
"description": "A test to create assembly updated",
|
||||
"plan_uri": 'fake_uri',
|
||||
"project_id": "project_id updated",
|
||||
|
||||
@@ -122,7 +122,7 @@ class TestComponentController(base.TestCase):
|
||||
|
||||
def test_components_put(self):
|
||||
uuid, assembly_uuid, plan_uuid = self._create_component()
|
||||
updated_data = {'name': 'test_service updated',
|
||||
updated_data = {'name': 'test_service_updated',
|
||||
'description': 'desc updated',
|
||||
'plan_uri': "%s/v1/plans/%s" % (self.client.base_url,
|
||||
plan_uuid),
|
||||
@@ -135,7 +135,7 @@ class TestComponentController(base.TestCase):
|
||||
self._delete_component(uuid, assembly_uuid, plan_uuid)
|
||||
|
||||
def test_components_put_not_found(self):
|
||||
updated_data = {'name': 'test_service updated',
|
||||
updated_data = {'name': 'test_service_updated',
|
||||
'description': 'desc updated',
|
||||
'plan_uri': "%s/v1/plans/%s" % (self.client.base_url,
|
||||
'not_found'),
|
||||
|
||||
@@ -120,7 +120,7 @@ class TestLanguagePackController(base.TestCase):
|
||||
self.skipTest("Tags update not implemented yet in python-glanceclient")
|
||||
# See http://goo.gl/vg9h6G
|
||||
uuid = self._create_language_pack()
|
||||
updated_data = {"name": "test_language_pack updated",
|
||||
updated_data = {"name": "test_language_pack_updated",
|
||||
"description": "A test to create language_pack update",
|
||||
"language_pack_type": "python",
|
||||
"language_implementation": "py",
|
||||
@@ -145,7 +145,7 @@ class TestLanguagePackController(base.TestCase):
|
||||
self._delete_language_pack(uuid)
|
||||
|
||||
def test_language_packs_put_not_found(self):
|
||||
updated_data = {"name": "test_language_pack updated",
|
||||
updated_data = {"name": "test_language_pack_updated",
|
||||
"description": "A test to create language_pack update",
|
||||
"language_pack_type": "python",
|
||||
"language_implementation": "py",
|
||||
|
||||
@@ -24,7 +24,7 @@ sample_data = {"name": "test_plan",
|
||||
"user_id": "user_id",
|
||||
"type": "plan",
|
||||
"artifacts": [{
|
||||
"name": "No deus",
|
||||
"name": "No_deus",
|
||||
"artifact_type": "application.heroku",
|
||||
"content": {
|
||||
"href": "https://example.com/git/a.git"
|
||||
@@ -98,7 +98,7 @@ class TestPlanController(base.TestCase):
|
||||
|
||||
def test_plans_put(self):
|
||||
uuid = self._create_plan()
|
||||
updated_data = {"name": "test_plan updated",
|
||||
updated_data = {"name": "test_plan_updated",
|
||||
"description": "A test to create plan updated",
|
||||
"type": "plan",
|
||||
"artifacts": []}
|
||||
@@ -110,7 +110,7 @@ class TestPlanController(base.TestCase):
|
||||
self._delete_plan(uuid)
|
||||
|
||||
def test_plans_put_not_found(self):
|
||||
updated_data = {"name": "test_plan updated",
|
||||
updated_data = {"name": "test_plan_updated",
|
||||
"description": "A test to create plan updated",
|
||||
"type": "plan",
|
||||
"artifacts": []}
|
||||
|
||||
@@ -94,7 +94,7 @@ class TestServiceController(base.TestCase):
|
||||
|
||||
def test_services_put(self):
|
||||
uuid = self._create_service()
|
||||
updated_data = {"name": "test_service updated",
|
||||
updated_data = {"name": "test_service_updated",
|
||||
"description": "A test to create service updated",
|
||||
"project_id": "project_id updated",
|
||||
"user_id": "user_id updated",
|
||||
@@ -108,7 +108,7 @@ class TestServiceController(base.TestCase):
|
||||
self._delete_service(uuid)
|
||||
|
||||
def test_services_put_not_found(self):
|
||||
updated_data = {"name": "test_service updated",
|
||||
updated_data = {"name": "test_service_updated",
|
||||
"description": "A test to create service updated",
|
||||
"project_id": "project_id updated",
|
||||
"user_id": "user_id updated",
|
||||
|
||||
@@ -96,11 +96,11 @@ class Plan(api_types.Base):
|
||||
@classmethod
|
||||
def sample(cls):
|
||||
return cls(uri='http://example.com/v1/plans/x1',
|
||||
name='Example plan',
|
||||
name='Example-plan',
|
||||
type='plan',
|
||||
tags=['small'],
|
||||
artifacts=[{
|
||||
'name': 'My python app',
|
||||
'name': 'My-python-app',
|
||||
'artifact_type': 'git_pull',
|
||||
'content': {'href': 'git://example.com/project.git'},
|
||||
'language_pack': str(uuid.uuid4()),
|
||||
@@ -108,7 +108,7 @@ class Plan(api_types.Base):
|
||||
'requirement_type': 'git_pull',
|
||||
'fulfillment': 'id:build'}]}],
|
||||
services=[{
|
||||
'name': 'Build Service',
|
||||
'name': 'Build-Service',
|
||||
'id': 'build',
|
||||
'characteristics': ['python_build_service']}],
|
||||
project_id='1dae5a09ef2b4d8cbf3594b0eb4f6b94',
|
||||
|
||||
@@ -12,10 +12,12 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import string
|
||||
import wsme
|
||||
from wsme import types as wtypes
|
||||
|
||||
from solum.api.controllers import common_types
|
||||
from solum.openstack.common.gettextutils import _
|
||||
|
||||
|
||||
class Base(wtypes.Base):
|
||||
@@ -27,7 +29,17 @@ class Base(wtypes.Base):
|
||||
uuid = wtypes.text
|
||||
"Unique Identifier of the resource"
|
||||
|
||||
name = wsme.wsattr(wtypes.text, mandatory=True)
|
||||
def get_name(self):
|
||||
return self.__name
|
||||
|
||||
def set_name(self, value):
|
||||
allowed_chars = string.letters + string.digits + '-_'
|
||||
for ch in value:
|
||||
if ch not in allowed_chars:
|
||||
raise ValueError(_('Names must only contain a-z,A-Z,0-9,-,_'))
|
||||
self.__name = value
|
||||
|
||||
name = wtypes.wsproperty(str, get_name, set_name, mandatory=True)
|
||||
"Name of the resource."
|
||||
|
||||
type = wtypes.text
|
||||
@@ -45,6 +57,10 @@ class Base(wtypes.Base):
|
||||
user_id = wtypes.text
|
||||
"The user that owns this resource."
|
||||
|
||||
def __init__(self, **kwds):
|
||||
self.__name = wsme.Unset
|
||||
super(Base, self).__init__(**kwds)
|
||||
|
||||
@classmethod
|
||||
def from_db_model(cls, m, host_url):
|
||||
json = m.as_dict()
|
||||
|
||||
@@ -114,7 +114,7 @@ class TestAssemblyAsDict(base.BaseTestCase):
|
||||
('none', dict(data=None)),
|
||||
('one', dict(data={'name': 'foo'})),
|
||||
('full', dict(data={'uri': 'http://example.com/v1/assemblys/x1',
|
||||
'name': 'Example assembly',
|
||||
'name': 'Example-assembly',
|
||||
'type': 'assembly',
|
||||
'project_id': '1dae5a09ef2b4d8cbf3594b0eb4f6b94',
|
||||
'user_id': '55f41cf46df74320b9486a35f5d28a11'}))
|
||||
|
||||
@@ -161,7 +161,7 @@ class TestComponentAsDict(base.BaseTestCase):
|
||||
('none', dict(data=None)),
|
||||
('one', dict(data={'name': 'foo'})),
|
||||
('full', dict(data={'uri': 'http://example.com/v1/components/x1',
|
||||
'name': 'Example component',
|
||||
'name': 'Example-component',
|
||||
'type': 'component',
|
||||
'tags': ['small'],
|
||||
'project_id': '1dae5a09ef2b4d8cbf3594b0eb4f6b94',
|
||||
|
||||
@@ -168,7 +168,7 @@ class TestOperationAsDict(base.BaseTestCase):
|
||||
('none', dict(data=None)),
|
||||
('one', dict(data={'name': 'foo'})),
|
||||
('full', dict(data={'uri': 'http://example.com/v1/operations/x1',
|
||||
'name': 'Example operation',
|
||||
'name': 'Example-operation',
|
||||
'type': 'operation',
|
||||
'project_id': '1dae5a09ef2b4d8cbf3594b0eb4f6b94',
|
||||
'user_id': '55f41cf46df74320b9486a35f5d28a11',
|
||||
|
||||
@@ -149,7 +149,7 @@ class TestPlanAsDict(base.BaseTestCase):
|
||||
('none', dict(data=None)),
|
||||
('one', dict(data={'name': 'foo'})),
|
||||
('full', dict(data={'uri': 'http://example.com/v1/plans/x1',
|
||||
'name': 'Example plan',
|
||||
'name': 'Example-plan',
|
||||
'type': 'plan',
|
||||
'project_id': '1dae5a09ef2b4d8cbf3594b0eb4f6b94',
|
||||
'user_id': '55f41cf46df74320b9486a35f5d28a11'}))
|
||||
|
||||
@@ -162,7 +162,7 @@ class TestServiceAsDict(base.BaseTestCase):
|
||||
('none', dict(data=None)),
|
||||
('one', dict(data={'name': 'foo'})),
|
||||
('full', dict(data={'uri': 'http://example.com/v1/services/x1',
|
||||
'name': 'Example service',
|
||||
'name': 'Example-service',
|
||||
'type': 'service',
|
||||
'tags': ['small'],
|
||||
'project_id': '1dae5a09ef2b4d8cbf3594b0eb4f6b94',
|
||||
|
||||
@@ -73,3 +73,33 @@ class TestTypes(base.BaseTestCase):
|
||||
obj = objects.registry.Component(**data)
|
||||
c = component_api.Component.from_db_model(obj, 'http://test_host')
|
||||
self.assertEqual(assembly_data['uuid'], c.assembly_uuid)
|
||||
|
||||
|
||||
class TestTypeNames(base.BaseTestCase):
|
||||
|
||||
scenarios = [
|
||||
('punct', dict(
|
||||
in_value='.,', expect_ok=False)),
|
||||
('-', dict(
|
||||
in_value='a-b', expect_ok=True)),
|
||||
('_', dict(
|
||||
in_value='a_b', expect_ok=True)),
|
||||
('spaces', dict(
|
||||
in_value='look a space', expect_ok=False)),
|
||||
('special', dict(
|
||||
in_value='$-&', expect_ok=False)),
|
||||
('upper', dict(
|
||||
in_value='ALLGOOD', expect_ok=True)),
|
||||
('lower', dict(
|
||||
in_value='evenbetter', expect_ok=True)),
|
||||
('numbers', dict(
|
||||
in_value='12345', expect_ok=True)),
|
||||
]
|
||||
|
||||
def test_name(self):
|
||||
if self.expect_ok:
|
||||
s = component_api.Component(name=self.in_value)
|
||||
self.assertEqual(self.in_value, s.name)
|
||||
else:
|
||||
self.assertRaises(ValueError, component_api.Component,
|
||||
name=self.in_value)
|
||||
|
||||
@@ -54,7 +54,7 @@ class TestImageAsDict(base.BaseTestCase):
|
||||
('none', dict(data=None)),
|
||||
('one', dict(data={'name': 'foo'})),
|
||||
('full', dict(data={'uri': 'http://example.com/v1/images/x1',
|
||||
'name': 'Example image',
|
||||
'name': 'Example-Image',
|
||||
'type': 'image',
|
||||
'tags': ['small'],
|
||||
'project_id': '1dae5a09ef2b4d8cbf3594b0eb4f6b94',
|
||||
|
||||
Reference in New Issue
Block a user