From 50bc51b64216e3b0003bc89edbebcc9914cbf90d Mon Sep 17 00:00:00 2001 From: Dr Scofield Date: Fri, 25 Jul 2008 10:02:21 +0000 Subject: From: awebb test code for REST handlers. --- .../Rest/Inventory/RestTestServices.cs | 236 +++++++++++++++++++++ .../Rest/Inventory/tests/ITest.cs | 48 +++++ 2 files changed, 284 insertions(+) create mode 100644 OpenSim/ApplicationPlugins/Rest/Inventory/RestTestServices.cs create mode 100644 OpenSim/ApplicationPlugins/Rest/Inventory/tests/ITest.cs diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/RestTestServices.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/RestTestServices.cs new file mode 100644 index 0000000..270a8c7 --- /dev/null +++ b/OpenSim/ApplicationPlugins/Rest/Inventory/RestTestServices.cs @@ -0,0 +1,236 @@ +/* + * Copyright (c) Contributors, http://opensimulator.org/ + * See CONTRIBUTORS.TXT for a full list of copyright holders. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the OpenSim Project nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +using libsecondlife; +using Nini.Config; +using System; +using System.IO; +using System.Collections.Generic; +using System.Reflection; +using System.Threading; +using OpenSim.Framework; +using OpenSim.Framework.Servers; +using OpenSim.Framework.Communications; +using OpenSim.Framework.Communications.Cache; + +namespace OpenSim.ApplicationPlugins.Rest.Inventory +{ + + public class RestTestServices : IRest + { + + private bool enabled = false; + private string qPrefix = "test"; + + // A simple constructor is used to handle any once-only + // initialization of working classes. + + public RestTestServices() + { + + Rest.Log.InfoFormat("{0} Test services initializing", MsgId); + Rest.Log.InfoFormat("{0} Using REST Implementation Version {1}", MsgId, Rest.Version); + + // If a relative path was specified, make it absolute by adding + // the standard prefix, e.g. /admin + + if (!qPrefix.StartsWith(Rest.UrlPathSeparator)) + { + qPrefix = Rest.Prefix + Rest.UrlPathSeparator + qPrefix; + } + + // Load test cases + + loadTests(); + foreach ( ITest test in tests ) + { + test.Initialize(); + } + + // Register interface + + Rest.Plugin.AddPathHandler(DoTests,qPrefix,Allocate); + + // Activate + + enabled = true; + + Rest.Log.InfoFormat("{0} Test services initialization complete", MsgId); + + } + + // Post-construction, pre-enabled initialization opportunity + // Not currently exploited. + + public void Initialize() + { + } + + // Called by the plug-in to halt REST processing. Local processing is + // disabled, and control blocks until all current processing has + // completed. No new processing will be started + + public void Close() + { + enabled = false; + foreach ( ITest test in tests ) + { + test.Close(); + } + Rest.Log.InfoFormat("{0} Test services closing down", MsgId); + } + + // Properties + + internal string MsgId + { + get { return Rest.MsgId; } + } + + #region Interface + + private RequestData Allocate(OSHttpRequest request, OSHttpResponse response) + { + return new RequestData(request, response, qPrefix); + } + + // Inventory Handler + + private void DoTests(RequestData rdata) + { + + if (!enabled) return; + + // Now that we know this is a serious attempt to + // access inventory data, we should find out who + // is asking, and make sure they are authorized + // to do so. We need to validate the caller's + // identity before revealing anything about the + // status quo. Authenticate throws an exception + // via Fail if no identity information is present. + // + // With the present HTTP server we can't use the + // builtin authentication mechanisms because they + // would be enforced for all in-bound requests. + // Instead we look at the headers ourselves and + // handle authentication directly. + + try + { + if (!rdata.IsAuthenticated) + { + rdata.Fail(Rest.HttpStatusCodeNotAuthorized, Rest.HttpStatusDescNotAuthorized); + } + } + catch (RestException e) + { + if (e.statusCode == Rest.HttpStatusCodeNotAuthorized) + { + Rest.Log.WarnFormat("{0} User not authenticated", MsgId); + Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId, rdata.request.Headers.Get("Authorization")); + } + else + { + Rest.Log.ErrorFormat("{0} User authentication failed", MsgId); + Rest.Log.DebugFormat("{0} Authorization header: {1}", MsgId, rdata.request.Headers.Get("Authorization")); + } + throw (e); + } + + // Check that a test was specified + + if (rdata.parameters.Length < 1) + { + Rest.Log.DebugFormat("{0} Insufficient parameters", MsgId); + rdata.Fail(Rest.HttpStatusCodeBadRequest, Rest.HttpStatusDescBadRequest); + } + + // Select the test + + foreach (ITest test in tests) + { + if (!rdata.handled) + test.Execute(rdata); + } + + } + + #endregion Interface + + private static bool testsLoaded = false; + private static List classes = new List(); + private static List tests = new List(); + private static Type[] parms = new Type[1]; + private static Object[] args = new Object[1]; + + static RestTestServices() + { + Module[] mods = Assembly.GetExecutingAssembly().GetModules(); + foreach (Module m in mods) + { + Type[] types = m.GetTypes(); + foreach (Type t in types) + { + if (t.GetInterface("ITest") != null) + { + classes.Add(t); + } + } + } + } + + /// + /// This routine loads all of the handlers discovered during + /// instance initialization. Each handler is responsible for + /// registering itself with this handler. + /// I was not able to make this code work in a constructor. + /// + private void loadTests() + { + lock(tests) + { + if (!testsLoaded) + { + parms[0] = this.GetType(); + args[0] = this; + + ConstructorInfo ci; + Object ht; + + foreach (Type t in classes) + { + ci = t.GetConstructor(parms); + ht = ci.Invoke(args); + tests.Add((ITest)ht); + } + testsLoaded = true; + } + } + } + } +} diff --git a/OpenSim/ApplicationPlugins/Rest/Inventory/tests/ITest.cs b/OpenSim/ApplicationPlugins/Rest/Inventory/tests/ITest.cs new file mode 100644 index 0000000..a3f1d14 --- /dev/null +++ b/OpenSim/ApplicationPlugins/Rest/Inventory/tests/ITest.cs @@ -0,0 +1,48 @@ +/* +* Copyright (c) Contributors, http://opensimulator.org/ +* See CONTRIBUTORS.TXT for a full list of copyright holders. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions are met: +* * Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* * Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* * Neither the name of the OpenSim Project nor the +* names of its contributors may be used to endorse or promote products +* derived from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY +* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY +* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*/ + +using System; + +namespace OpenSim.ApplicationPlugins.Rest.Inventory +{ + + /// + /// This interface represents the boundary between the general purpose + /// REST plugin handling, and the functionally specific handlers. The + /// handler knows only to initialzie and terminate all such handlers + /// that it finds. + /// + + internal interface ITest + { + void Initialize(); + void Execute(RequestData rdata); + void Close(); + } + +} -- cgit v1.1