SEBA-480 Add authentication to dynamicload and utility apis;
remove legacy tosca api endpoint

Change-Id: I886e2d4af87d24e72d460181beb9d81ffff098cf
diff --git a/VERSION b/VERSION
index c043eea..b1b25a5 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.2.1
+2.2.2
diff --git a/containers/chameleon/Dockerfile.chameleon b/containers/chameleon/Dockerfile.chameleon
index 83df7fd..bfb2026 100644
--- a/containers/chameleon/Dockerfile.chameleon
+++ b/containers/chameleon/Dockerfile.chameleon
@@ -14,7 +14,7 @@
 
 # xosproject/chameleon
 
-FROM xosproject/xos-base:2.2.1
+FROM xosproject/xos-base:2.2.2
 
 # xos-base already has protoc and dependencies installed
 
diff --git a/containers/xos/Dockerfile.client b/containers/xos/Dockerfile.client
index 8208ec9..8253f10 100644
--- a/containers/xos/Dockerfile.client
+++ b/containers/xos/Dockerfile.client
@@ -14,7 +14,7 @@
 
 # xosproject/xos-client
 
-FROM xosproject/xos-libraries:2.2.1
+FROM xosproject/xos-libraries:2.2.2
 
 # Install XOS client
 COPY lib/xos-api /tmp/xos-api
diff --git a/containers/xos/Dockerfile.libraries b/containers/xos/Dockerfile.libraries
index 5a211fa..24f7bdd 100644
--- a/containers/xos/Dockerfile.libraries
+++ b/containers/xos/Dockerfile.libraries
@@ -14,7 +14,7 @@
 
 # xosproject/xos-libraries
 
-FROM xosproject/xos-base:2.2.1
+FROM xosproject/xos-base:2.2.2
 
 # Add libraries
 COPY lib /opt/xos/lib
diff --git a/containers/xos/Dockerfile.synchronizer-base b/containers/xos/Dockerfile.synchronizer-base
index ec745c4..f32b590 100644
--- a/containers/xos/Dockerfile.synchronizer-base
+++ b/containers/xos/Dockerfile.synchronizer-base
@@ -14,7 +14,7 @@
 
 # xosproject/xos-synchronizer-base
 
-FROM xosproject/xos-client:2.2.1
+FROM xosproject/xos-client:2.2.2
 
 COPY xos/synchronizers/new_base /opt/xos/synchronizers/new_base
 COPY xos/xos/logger.py /opt/xos/xos/logger.py
diff --git a/containers/xos/Dockerfile.xos-core b/containers/xos/Dockerfile.xos-core
index 802373b..2e4219d 100644
--- a/containers/xos/Dockerfile.xos-core
+++ b/containers/xos/Dockerfile.xos-core
@@ -14,7 +14,7 @@
 
 # xosproject/xos-core
 
-FROM xosproject/xos-libraries:2.2.1
+FROM xosproject/xos-libraries:2.2.2
 
 # Install XOS
 ADD xos /opt/xos
diff --git a/lib/xos-genx/xosgenx/targets/grpc_api.xtarget b/lib/xos-genx/xosgenx/targets/grpc_api.xtarget
index 4abf3dc..387a2fe 100644
--- a/lib/xos-genx/xosgenx/targets/grpc_api.xtarget
+++ b/lib/xos-genx/xosgenx/targets/grpc_api.xtarget
@@ -6,7 +6,8 @@
 
 from django.contrib.auth import authenticate as django_authenticate
 from xos.exceptions import *
-from apihelper import XOSAPIHelperMixin, translate_exceptions
+from apihelper import XOSAPIHelperMixin
+from decorators import translate_exceptions
 import grpc
 
 class XosService(xos_pb2_grpc.xosServicer, XOSAPIHelperMixin):
diff --git a/xos/core/core-onboard.yaml b/xos/core/core-onboard.yaml
deleted file mode 100644
index 21385a0..0000000
--- a/xos/core/core-onboard.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-tosca_definitions_version: tosca_simple_yaml_1_0
-
-description: Onboard XOS Core
-
-imports:
-   - custom_types/xos.yaml
-
-topology_template:
-  node_templates:
-    servicecontroller#core:
-      type: tosca.nodes.ServiceController
-      properties:
-          base_url: file:///opt/xos/core
-          xproto: core/models
diff --git a/xos/coreapi/apihelper.py b/xos/coreapi/apihelper.py
index 6e0109c..005bed3 100644
--- a/xos/coreapi/apihelper.py
+++ b/xos/coreapi/apihelper.py
@@ -13,30 +13,20 @@
 # limitations under the License.
 
 from __future__ import print_function
-from apistats import REQUEST_COUNT
-import base64
+from authhelper import XOSAuthHelperMixin
 import datetime
 import inspect
 import pytz
-import threading
-import time
 from protos import xos_pb2
 from google.protobuf.empty_pb2 import Empty
-import grpc
 
-from django.contrib.auth import authenticate as django_authenticate
 from django.db.models import F, Q
 from core.models import Site, User, XOSBase
 from xos.exceptions import (
-    XOSNotAuthenticated,
     XOSPermissionDenied,
     XOSNotFound,
-    XOSValidationError,
 )
 
-from importlib import import_module
-from django.conf import settings
-
 from xosconfig import Config
 from multistructlog import create_logger
 
@@ -65,132 +55,17 @@
     site=xos_anonymous_site,
 )
 
-SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
 
+class XOSAPIHelperMixin(XOSAuthHelperMixin):
+    """ This helper contains several functions used to implement the autogenerated core API.
+        It translates between the gRPC representation of objects and the django representation
+        of objects. It implements functions that handle the heavy lifting of the
+        create/read/update/delete functions.
 
-def translate_exceptions(model, method):
-    """ this decorator translates XOS exceptions to grpc status codes """
-
-    def decorator(function):
-        def wrapper(*args, **kwargs):
-            try:
-                return function(*args, **kwargs)
-            except Exception as e:
-
-                import traceback
-
-                tb = traceback.format_exc()
-                print(tb)
-                # TODO can we propagate it over the APIs?
-
-                if "context" in kwargs:
-                    context = kwargs["context"]
-                else:
-                    context = args[2]
-
-                if hasattr(e, "json_detail"):
-                    context.set_details(e.json_detail)
-                elif hasattr(e, "detail"):
-                    context.set_details(e.detail)
-
-                if isinstance(e, XOSPermissionDenied):
-                    REQUEST_COUNT.labels(
-                        "xos-core", model, method, grpc.StatusCode.PERMISSION_DENIED
-                    ).inc()
-                    context.set_code(grpc.StatusCode.PERMISSION_DENIED)
-                elif isinstance(e, XOSValidationError):
-                    REQUEST_COUNT.labels(
-                        "xos-core", model, method, grpc.StatusCode.INVALID_ARGUMENT
-                    ).inc()
-                    context.set_code(grpc.StatusCode.INVALID_ARGUMENT)
-                elif isinstance(e, XOSNotAuthenticated):
-                    REQUEST_COUNT.labels(
-                        "xos-core", model, method, grpc.StatusCode.UNAUTHENTICATED
-                    ).inc()
-                    context.set_code(grpc.StatusCode.UNAUTHENTICATED)
-                elif isinstance(e, XOSNotFound):
-                    REQUEST_COUNT.labels(
-                        "xos-core", model, method, grpc.StatusCode.NOT_FOUND
-                    ).inc()
-                    context.set_code(grpc.StatusCode.NOT_FOUND)
-                raise
-
-        return wrapper
-
-    return decorator
-
-
-bench_tStart = time.time()
-bench_ops = 0
-
-
-def benchmark(function):
-    """ this decorator will report gRPC benchmark statistics every 10 seconds """
-
-    def wrapper(*args, **kwargs):
-        global bench_tStart
-        global bench_ops
-        result = function(*args, **kwargs)
-        bench_ops = bench_ops + 1
-        elap = time.time() - bench_tStart
-        if elap >= 10:
-            print("performance %d" % (bench_ops / elap))
-            bench_ops = 0
-            bench_tStart = time.time()
-        return result
-
-    return wrapper
-
-
-class CachedAuthenticator(object):
-    """ Django Authentication is very slow (~ 10 ops/second), so cache
-        authentication results and reuse them.
+        Inherits authentication functionality from AuthHelperMixin.
     """
 
     def __init__(self):
-        self.cached_creds = {}
-        self.timeout = 10  # keep cache entries around for 10s
-        # lock to keep multiple callers from trimming at the same time
-        self.lock = threading.Lock()
-
-    def authenticate(self, username, password):
-        self.trim()
-
-        key = "%s:%s" % (username, password)
-        cred = self.cached_creds.get(key, None)
-        if cred:
-            user = User.objects.filter(id=cred["user_id"])
-            if user:
-                user = user[0]
-                # print "cached authenticated %s:%s as %s" % (username,
-                # password, user)
-                return user
-
-        user = django_authenticate(username=username, password=password)
-        if user:
-            # print "django authenticated %s:%s as %s" % (username, password,
-            # user)
-            self.cached_creds[key] = {
-                "timeout": time.time() + self.timeout,
-                "user_id": user.id,
-            }
-
-        return user
-
-    def trim(self):
-        """ Delete all cache entries that have expired """
-        self.lock.acquire()
-        for (k, v) in list(self.cached_creds.items()):
-            if time.time() > v["timeout"]:
-                del self.cached_creds[k]
-        self.lock.release()
-
-
-cached_authenticator = CachedAuthenticator()
-
-
-class XOSAPIHelperMixin(object):
-    def __init__(self):
         import django.apps
 
         self.models = {}
@@ -686,32 +561,3 @@
         except BaseException:
             log.exception("Exception in apihelper.filter")
             raise
-
-    def authenticate(self, context, required=True):
-        for (k, v) in context.invocation_metadata():
-            if k.lower() == "authorization":
-                (method, auth) = v.split(" ", 1)
-                if method.lower() == "basic":
-                    auth = base64.b64decode(auth)
-                    (username, password) = auth.split(":")
-                    user = cached_authenticator.authenticate(
-                        username=username, password=password
-                    )
-                    if not user:
-                        raise XOSPermissionDenied(
-                            "failed to authenticate %s:%s" % (username, password)
-                        )
-                    return user
-            elif k.lower() == "x-xossession":
-                s = SessionStore(session_key=v)
-                id = s.get("_auth_user_id", None)
-                if not id:
-                    raise XOSPermissionDenied("failed to authenticate token %s" % v)
-                user = User.objects.get(id=id)
-                log.info("authenticated sessionid %s as %s" % (v, user))
-                return user
-
-        if required:
-            raise XOSNotAuthenticated("This API requires authentication")
-
-        return None
diff --git a/xos/coreapi/authhelper.py b/xos/coreapi/authhelper.py
new file mode 100644
index 0000000..8ffc966
--- /dev/null
+++ b/xos/coreapi/authhelper.py
@@ -0,0 +1,115 @@
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import print_function
+import base64
+from importlib import import_module
+import threading
+import time
+
+from django.conf import settings
+from django.contrib.auth import authenticate as django_authenticate
+from core.models import Site, User, XOSBase
+from xos.exceptions import (
+    XOSNotAuthenticated,
+    XOSPermissionDenied,
+    XOSNotFound,
+    XOSValidationError,
+)
+
+from xosconfig import Config
+from multistructlog import create_logger
+
+log = create_logger(Config().get("logging"))
+
+
+SessionStore = import_module(settings.SESSION_ENGINE).SessionStore
+
+
+class CachedAuthenticator(object):
+    """ Django Authentication is very slow (~ 10 ops/second), so cache
+        authentication results and reuse them.
+    """
+
+    def __init__(self):
+        self.cached_creds = {}
+        self.timeout = 10  # keep cache entries around for 10s
+        # lock to keep multiple callers from trimming at the same time
+        self.lock = threading.Lock()
+
+    def authenticate(self, username, password):
+        self.trim()
+
+        key = "%s:%s" % (username, password)
+        cred = self.cached_creds.get(key, None)
+        if cred:
+            user = User.objects.filter(id=cred["user_id"])
+            if user:
+                user = user[0]
+                # print "cached authenticated %s:%s as %s" % (username,
+                # password, user)
+                return user
+
+        user = django_authenticate(username=username, password=password)
+        if user:
+            # print "django authenticated %s:%s as %s" % (username, password,
+            # user)
+            self.cached_creds[key] = {
+                "timeout": time.time() + self.timeout,
+                "user_id": user.id,
+            }
+
+        return user
+
+    def trim(self):
+        """ Delete all cache entries that have expired """
+        self.lock.acquire()
+        for (k, v) in list(self.cached_creds.items()):
+            if time.time() > v["timeout"]:
+                del self.cached_creds[k]
+        self.lock.release()
+
+
+cached_authenticator = CachedAuthenticator()
+
+
+class XOSAuthHelperMixin(object):
+    def authenticate(self, context, required=True):
+        for (k, v) in context.invocation_metadata():
+            if k.lower() == "authorization":
+                (method, auth) = v.split(" ", 1)
+                if method.lower() == "basic":
+                    auth = base64.b64decode(auth)
+                    (username, password) = auth.split(":")
+                    user = cached_authenticator.authenticate(
+                        username=username, password=password
+                    )
+                    if not user:
+                        raise XOSPermissionDenied(
+                            "failed to authenticate %s:%s" % (username, password)
+                        )
+                    return user
+            elif k.lower() == "x-xossession":
+                s = SessionStore(session_key=v)
+                id = s.get("_auth_user_id", None)
+                if not id:
+                    raise XOSPermissionDenied("failed to authenticate token %s" % v)
+                user = User.objects.get(id=id)
+                log.info("authenticated sessionid %s as %s" % (v, user))
+                return user
+
+        if required:
+            raise XOSNotAuthenticated("This API requires authentication")
+
+        return None
diff --git a/xos/coreapi/decorators.py b/xos/coreapi/decorators.py
new file mode 100644
index 0000000..bd543ca
--- /dev/null
+++ b/xos/coreapi/decorators.py
@@ -0,0 +1,113 @@
+# Copyright 2017-present Open Networking Foundation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from __future__ import print_function
+from apistats import REQUEST_COUNT
+import time
+import grpc
+
+from xos.exceptions import (
+    XOSNotAuthenticated,
+    XOSPermissionDenied,
+    XOSNotFound,
+    XOSValidationError,
+)
+
+from xosconfig import Config
+from multistructlog import create_logger
+
+log = create_logger(Config().get("logging"))
+
+
+def translate_exceptions(model, method):
+    """ this decorator translates XOS exceptions to grpc status codes """
+
+    def decorator(function):
+        def wrapper(*args, **kwargs):
+            try:
+                return function(*args, **kwargs)
+            except Exception as e:
+
+                import traceback
+
+                tb = traceback.format_exc()
+                print(tb)
+                # TODO can we propagate it over the APIs?
+
+                if "context" in kwargs:
+                    context = kwargs["context"]
+                else:
+                    context = args[2]
+
+                if hasattr(e, "json_detail"):
+                    context.set_details(e.json_detail)
+                elif hasattr(e, "detail"):
+                    context.set_details(e.detail)
+
+                if isinstance(e, XOSPermissionDenied):
+                    REQUEST_COUNT.labels(
+                        "xos-core", model, method, grpc.StatusCode.PERMISSION_DENIED
+                    ).inc()
+                    context.set_code(grpc.StatusCode.PERMISSION_DENIED)
+                elif isinstance(e, XOSValidationError):
+                    REQUEST_COUNT.labels(
+                        "xos-core", model, method, grpc.StatusCode.INVALID_ARGUMENT
+                    ).inc()
+                    context.set_code(grpc.StatusCode.INVALID_ARGUMENT)
+                elif isinstance(e, XOSNotAuthenticated):
+                    REQUEST_COUNT.labels(
+                        "xos-core", model, method, grpc.StatusCode.UNAUTHENTICATED
+                    ).inc()
+                    context.set_code(grpc.StatusCode.UNAUTHENTICATED)
+                elif isinstance(e, XOSNotFound):
+                    REQUEST_COUNT.labels(
+                        "xos-core", model, method, grpc.StatusCode.NOT_FOUND
+                    ).inc()
+                    context.set_code(grpc.StatusCode.NOT_FOUND)
+                raise
+
+        return wrapper
+
+    return decorator
+
+
+bench_tStart = time.time()
+bench_ops = 0
+
+
+def benchmark(function):
+    """ this decorator will report gRPC benchmark statistics every 10 seconds """
+
+    def wrapper(*args, **kwargs):
+        global bench_tStart
+        global bench_ops
+        result = function(*args, **kwargs)
+        bench_ops = bench_ops + 1
+        elap = time.time() - bench_tStart
+        if elap >= 10:
+            print("performance %d" % (bench_ops / elap))
+            bench_ops = 0
+            bench_tStart = time.time()
+        return result
+
+    return wrapper
+
+
+def require_authentication(function):
+    def wrapper(self, request, context):
+        self.authenticate(context, required=True)
+        result = function(self, request, context)
+        return result
+
+    return wrapper
diff --git a/xos/coreapi/grpc_server.py b/xos/coreapi/grpc_server.py
index 340f8c3..915e2c3 100644
--- a/xos/coreapi/grpc_server.py
+++ b/xos/coreapi/grpc_server.py
@@ -32,8 +32,7 @@
 Config.init()
 log = create_logger(Config().get("logging"))
 
-from xos_dynamicload_api import DynamicLoadService
-from protos import schema_pb2, schema_pb2_grpc, dynamicload_pb2_grpc
+from protos import schema_pb2, schema_pb2_grpc
 
 SERVER_KEY = "/opt/cord_profile/core_api_key.pem"
 SERVER_CERT = "/opt/cord_profile/core_api_cert.pem"
@@ -127,6 +126,18 @@
         except BaseException:
             log.exception("Failed to initialize django")
 
+    def register_dynamicload(self):
+        from xos_dynamicload_api import DynamicLoadService
+        from protos import dynamicload_pb2_grpc
+
+        dynamic_load_service = DynamicLoadService(self.thread_pool, self)
+        self.register(
+            "dynamicload",
+            dynamicload_pb2_grpc.add_dynamicloadServicer_to_server,
+            dynamic_load_service,
+        )
+        dynamic_load_service.set_django_apps(self.django_apps)
+
     def register_core(self):
         from xos_grpc_api import XosService
         from protos import xos_pb2_grpc
@@ -164,21 +175,20 @@
             SchemaService(self.thread_pool),
         )
 
-        dynamic_load_service = DynamicLoadService(self.thread_pool, self)
-        self.register(
-            "dynamicload",
-            dynamicload_pb2_grpc.add_dynamicloadServicer_to_server,
-            dynamic_load_service,
-        )
+        if self.model_status != 0:
+            log.error("Models are boken. Please remove the synchronizer causing the problem and restart the core.")
+            sys.exit(-1)
 
-        if self.model_status == 0:
-            self.init_django()
+        self.init_django()
 
-        if self.django_initialized:
-            dynamic_load_service.set_django_apps(self.django_apps)
-            self.register_core()
-            self.register_utility()
-            self.register_modeldefs()
+        if not self.django_initialized:
+            log.error("Django is boken. Please remove the synchronizer causing the problem and restart the core.")
+            sys.exit(-1)
+
+        self.register_dynamicload()
+        self.register_core()
+        self.register_utility()
+        self.register_modeldefs()
 
         # open port
         self.server.add_insecure_port("[::]:%s" % self.port)
diff --git a/xos/coreapi/xos_dynamicload_api.py b/xos/coreapi/xos_dynamicload_api.py
index fd46056..284c114 100644
--- a/xos/coreapi/xos_dynamicload_api.py
+++ b/xos/coreapi/xos_dynamicload_api.py
@@ -18,6 +18,8 @@
 from xosutil.autodiscover_version import autodiscover_version_of_main
 from dynamicbuild import DynamicBuilder
 from apistats import REQUEST_COUNT, track_request_time
+from authhelper import XOSAuthHelperMixin
+from decorators import translate_exceptions, require_authentication
 import grpc
 import semver
 import re
@@ -26,12 +28,13 @@
 
 log = create_logger(Config().get("logging"))
 
-class DynamicLoadService(dynamicload_pb2_grpc.dynamicloadServicer):
+class DynamicLoadService(dynamicload_pb2_grpc.dynamicloadServicer, XOSAuthHelperMixin):
     def __init__(self, thread_pool, server):
         self.thread_pool = thread_pool
         self.server = server
         self.django_apps = None
         self.django_apps_by_name = {}
+        XOSAuthHelperMixin.__init__(self)
 
     def stop(self):
         pass
@@ -60,6 +63,8 @@
                 self.django_app_models[app.name] = django_models
 
     @track_request_time("DynamicLoad", "LoadModels")
+    @translate_exceptions("DynamicLoad", "LoadModels")
+    @require_authentication
     def LoadModels(self, request, context):
         try:
 
@@ -164,6 +169,8 @@
             context.set_details(code_names.get(status, "UNKNOWN"))
 
     @track_request_time("DynamicLoad", "UnloadModels")
+    @translate_exceptions("DynamicLoad", "UnloadModels")
+    @require_authentication
     def UnloadModels(self, request, context):
         try:
             builder = DynamicBuilder()
@@ -191,6 +198,8 @@
             raise e
 
     @track_request_time("DynamicLoad", "GetLoadStatus")
+    @translate_exceptions("DynamicLoad", "GetLoadStatus")
+    @require_authentication
     def GetLoadStatus(self, request, context):
         try:
             builder = DynamicBuilder()
@@ -233,6 +242,8 @@
             raise e
 
     @track_request_time("DynamicLoad", "GetConvenienceMethods")
+    @translate_exceptions("DynamicLoad", "GetConvenienceMethods")
+    @require_authentication
     def GetConvenienceMethods(self, request, context):
         # self.authenticate(context, required=True)
         try:
diff --git a/xos/coreapi/xos_utility_api.py b/xos/coreapi/xos_utility_api.py
index 41ca4d0..1d2ec96 100644
--- a/xos/coreapi/xos_utility_api.py
+++ b/xos/coreapi/xos_utility_api.py
@@ -15,7 +15,8 @@
 import inspect
 from apistats import REQUEST_COUNT, track_request_time
 import grpc
-from apihelper import XOSAPIHelperMixin, translate_exceptions
+from authhelper import XOSAuthHelperMixin
+from decorators import translate_exceptions, require_authentication
 from xos.exceptions import XOSNotAuthenticated
 from core.models import ServiceInstance
 from django.db.models import F, Q
@@ -64,10 +65,10 @@
     return matches
 
 
-class UtilityService(utility_pb2_grpc.utilityServicer, XOSAPIHelperMixin):
+class UtilityService(utility_pb2_grpc.utilityServicer, XOSAuthHelperMixin):
     def __init__(self, thread_pool):
         self.thread_pool = thread_pool
-        XOSAPIHelperMixin.__init__(self)
+        XOSAuthHelperMixin.__init__(self)
 
     def stop(self):
         pass
@@ -109,61 +110,6 @@
         REQUEST_COUNT.labels("xos-core", "Utilities", "Login", grpc.StatusCode.OK).inc()
         return Empty()
 
-    # FIXME are we still using these?
-    @translate_exceptions("Utilities", "RunTosca")
-    @track_request_time("Utilities", "RunTosca")
-    def RunTosca(self, request, context):
-        user = self.authenticate(context, required=True)
-
-        sys_path_save = sys.path
-        try:
-            sys.path.append(toscadir)
-            from tosca.engine import XOSTosca
-
-            xt = XOSTosca(request.recipe, parent_dir=toscadir, log_to_console=False)
-            xt.execute(user)
-        except BaseException:
-            response = utility_pb2.ToscaResponse()
-            response.status = response.ERROR
-            response.messages = traceback.format_exc()
-            return response
-        finally:
-            sys.path = sys_path_save
-
-        response = utility_pb2.ToscaResponse()
-        response.status = response.SUCCESS
-        response.messages = "\n".join(xt.log_msgs)
-
-        return response
-
-    @translate_exceptions("Utilities", "DestryTosca")
-    @track_request_time("Utilities", "DestryTosca")
-    def DestroyTosca(self, request, context):
-        user = self.authenticate(context, required=True)
-
-        sys_path_save = sys.path
-        try:
-            sys.path.append(toscadir)
-            from tosca.engine import XOSTosca
-
-            xt = XOSTosca(request.recipe, parent_dir=toscadir, log_to_console=False)
-            xt.destroy(user)
-        except BaseException:
-            response = utility_pb2.ToscaResponse()
-            response.status = response.ERROR
-            response.messages = traceback.format_exc()
-            return response
-        finally:
-            sys.path = sys_path_save
-
-        response = utility_pb2.ToscaResponse()
-        response.status = response.SUCCESS
-        response.messages = "\n".join(xt.log_msgs)
-
-        return response
-
-    # end FIXME
-
     @translate_exceptions("Utilities", "NoOp")
     @track_request_time("Utilities", "NoOp")
     def NoOp(self, request, context):
@@ -172,8 +118,8 @@
 
     @translate_exceptions("Utilities", "AuthenticatedNoOp")
     @track_request_time("Utilities", "AuthenticatedNoOp")
+    @require_authentication
     def AuthenticatedNoOp(self, request, context):
-        self.authenticate(context, required=True)
         REQUEST_COUNT.labels(
             "xos-core", "Utilities", "AuthenticatedNoOp", grpc.StatusCode.OK
         ).inc()
@@ -181,6 +127,7 @@
 
     @translate_exceptions("Utilities", "ListDirtyModels")
     @track_request_time("Utilities", "ListDirtyModels")
+    @require_authentication
     def ListDirtyModels(self, request, context):
         dirty_models = utility_pb2.ModelList()
 
@@ -208,6 +155,7 @@
 
     @translate_exceptions("Utilities", "SetDirtyModels")
     @track_request_time("Utilities", "SetDirtyModels")
+    @require_authentication
     def SetDirtyModels(self, request, context):
         user = self.authenticate(context, required=True)
 
@@ -245,6 +193,7 @@
 
     @translate_exceptions("Utilities", "GetXproto")
     @track_request_time("Utilities", "GetXproto")
+    # TODO(smbaker): Tosca engine calls this without authentication
     def GetXproto(self, request, context):
         res = utility_pb2.XProtos()
 
@@ -280,6 +229,7 @@
 
     @translate_exceptions("Utilities", "GetPopulatedServiceInstances")
     @track_request_time("Utilities", "GetPopulatedServiceInstances")
+    @require_authentication
     def GetPopulatedServiceInstances(self, request, context):
         """
         Return a service instance with provider and subsciber service instance ids
diff --git a/xos/tosca/README.md b/xos/tosca/README.md
deleted file mode 100644
index 593269a..0000000
--- a/xos/tosca/README.md
+++ /dev/null
@@ -1,2 +0,0 @@
-The only definitions defined here are used to onboard services.
-TOSCA defintions for models are autogenerate from xProto.
\ No newline at end of file
diff --git a/xos/tosca/__init__.py b/xos/tosca/__init__.py
deleted file mode 100644
index b0fb0b2..0000000
--- a/xos/tosca/__init__.py
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
diff --git a/xos/tosca/custom_types/xos.yaml b/xos/tosca/custom_types/xos.yaml
deleted file mode 100644
index 42e3379..0000000
--- a/xos/tosca/custom_types/xos.yaml
+++ /dev/null
@@ -1,213 +0,0 @@
-
-# Copyright 2017-present Open Networking Foundation
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-tosca_definitions_version: tosca_simple_yaml_1_0
-
-node_types:
-
-    tosca.nodes.ServiceController:
-        derived_from: tosca.nodes.Root
-        description: >
-            An XOS Service Controller.
-        properties:
-            no-delete:
-                type: boolean
-                default: false
-                description: Do not allow Tosca to delete this object
-            no-create:
-                type: boolean
-                default: false
-                description: Do not allow Tosca to create this object
-            no-update:
-                type: boolean
-                default: false
-                description: Do not allow Tosca to update this object
-            replaces:
-                type: string
-                required: false
-                descrption: Replaces/renames this object
-            base_url:
-                type: string
-                required: false
-                description: Base url, to allow resources to use relative URLs
-            version:
-                type: string
-                required: false
-                description: Version number of this Service Controller
-            provides:
-                type: string
-                required: false
-                description: Comma-separated list of things provided
-            requires:
-                type: string
-                required: false
-                description: Comma-separated list of requirements
-            xproto:
-                type: string
-                required: false
-                description: url of xproto
-            models:
-                type: string
-                required: false
-                description: url of models.py
-            admin:
-                type: string
-                required: false
-                description: url of admin.py
-            django_library:
-                type: string
-                required: false
-                description: libraries used by admin or models
-            admin_template:
-                type: string
-                required: false
-                description: url of admin html template
-            synchronizer:
-                type: string
-                required: false
-                description: url of synchronizer manifest
-            synchronizer_run:
-                type: string
-                required: false
-                description: synchronizer run command
-            synchronizer_config:
-                type: string
-                required: false
-                description: synchronizer config filename
-            # NOTE: I am deprecated, I've not been removed yet not to break everything
-            tosca_custom_types:
-                type: string
-                required: false
-                description: url of tosca custom_types
-            # NOTE: I am deprecated, I've not been removed yet not to break everything
-            tosca_resource:
-                type: string
-                required: false
-                description: url of tosca resource
-            rest_service:
-                type: string
-                required: false
-                description: url of REST API service file
-            rest_tenant:
-                type: string
-                required: false
-                description: url of REST API tenant file
-            private_key:
-                type: string
-                required: false
-                description: private key
-            public_key:
-                type: string
-                required: false
-                description: public key
-            vendor_js:
-                type: string
-                required: false
-                description: third-party javascript files
-            image:
-                type: string
-                required: false
-                description: Image name for refactored synchronizer containers
-            no_build:
-                type: boolean
-                required: false
-                description: If true then refactored synchronizer container image is assumed
-            no_deploy:
-                type: boolean
-                required: false
-                description: If true then synchronizer container will not be added to docker-compose
-
-    tosca.nodes.Library:
-        derived_from: tosca.nodes.Root
-        description: >
-            An XOS Library.
-        properties:
-            no-delete:
-                type: boolean
-                default: false
-                description: Do not allow Tosca to delete this object
-            no-create:
-                type: boolean
-                default: false
-                description: Do not allow Tosca to create this object
-            no-update:
-                type: boolean
-                default: false
-                description: Do not allow Tosca to update this object
-            replaces:
-                type: string
-                required: false
-                descrption: Replaces/renames this object
-            base_url:
-                type: string
-                required: false
-                description: Base url, to allow resources to use relative URLs
-            version:
-                type: string
-                required: false
-                description: Version number of this Service Controller
-            provides:
-                type: string
-                required: false
-                description: Comma-separated list of things provided
-            requires:
-                type: string
-                required: false
-                description: Comma-separated list of requirements
-            models:
-                type: string
-                required: false
-                description: url of models.py
-            admin:
-                type: string
-                required: false
-                description: url of admin.py
-            django_library:
-                type: string
-                required: false
-                description: libraries used by admin or models
-            admin_template:
-                type: string
-                required: false
-                description: url of admin html template
-            tosca_custom_types:
-                type: string
-                required: false
-                description: url of tosca custom_types
-            tosca_resource:
-                type: string
-                required: false
-                description: url of tosca resource
-            rest_service:
-                type: string
-                required: false
-                description: url of REST API service file
-            rest_tenant:
-                type: string
-                required: false
-                description: url of REST API tenant file
-            private_key:
-                type: string
-                required: false
-                description: private key
-            public_key:
-                type: string
-                required: false
-                description: public key
-            vendor_js:
-                type: string
-                required: false
-                description: third-party javascript files
\ No newline at end of file