/// <summary>
        /// Instatiates a DomainService instance along with the DomainServiceContext.
        /// </summary>
        /// <param name="instance">Wrapper representing the instance passed to invocation.</param>
        /// <returns>New DomainService instance.</returns>
        private DomainService GetDomainService(object instance)
        {
            // Create and initialize the DomainService for this request.
            DomainDataServiceContractBehavior.DomainDataServiceInstanceInfo instanceInfo =
                (DomainDataServiceContractBehavior.DomainDataServiceInstanceInfo)instance;

            IServiceProvider     serviceProvider = (IServiceProvider)OperationContext.Current.Host;
            DomainServiceContext context         = new WcfDomainServiceContext(serviceProvider, this.operationType);

            try
            {
                DomainService domainService = DomainService.Factory.CreateDomainService(instanceInfo.DomainServiceType, context);
                instanceInfo.DomainServiceInstance = domainService;
                return(domainService);
            }
            catch (TargetInvocationException tie)
            {
                // If the exception has already been transformed to a DomainServiceException just rethrow it.
                if (tie.InnerException != null)
                {
                    throw new DomainDataServiceException(Resource.DomainDataService_General_Error, tie.InnerException);
                }

                throw new DomainDataServiceException(Resource.DomainDataService_General_Error, tie);
            }
            catch (Exception ex)
            {
                if (ex.IsFatal())
                {
                    throw;
                }
                else
                {
                    // We need to ensure that any time an exception is thrown by the service it is transformed to a
                    // properly sanitized/configured DomainDataService exception.
                    throw new DomainDataServiceException(Resource.DomainDataService_General_Error, ex);
                }
            }
        }
Exemplo n.º 2
0
        public async Task Authorization_Custom_Authorization_On_Invoke()
        {
            // Specifically, the City data is marked so that no one can delete a Zip code
            // from WA unless their user name is WAGuy
            MockUser notWaGuy = new MockUser("notWAGuy");

            notWaGuy.IsAuthenticated = true;

            DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(typeof(CityDomainService));
            DomainOperationEntry     invokeOperation    = serviceDescription.GetInvokeOperation("GetStateIfUser");

            Assert.IsNotNull(invokeOperation, "Could not locate GetStateIfUser Invoke operation");
            DomainOperationEntry getCitiesQuery = serviceDescription.GetQueryMethod("GetCities");

            City city = null;

            // Execute a query to get a City from WA
            using (CityDomainService cities = new CityDomainService())
            {
                // Now prepare for a query to find a Zip in WA
                DomainServiceContext ctxt = new WcfDomainServiceContext(new MockDataService(notWaGuy), DomainOperationType.Query);
                cities.Initialize(ctxt);

                IEnumerable result = (await cities.QueryAsync <City>(new QueryDescription(getCitiesQuery), CancellationToken.None)).Result;

                city = result.OfType <City>().FirstOrDefault(z => z.StateName == "WA");
                Assert.IsNotNull(city, "Could not find a city in WA");
            }

            // Perform an invoke against a method that has a custom auth attribute requiring WaGuy
            // where the user is something else -- should be denied
            using (CityDomainService cities = new CityDomainService())
            {
                // Prepare an invoke to call a method that has a custom auth attribute
                DomainServiceContext ctxt = new WcfDomainServiceContext(new MockDataService(notWaGuy), DomainOperationType.Invoke);
                cities.Initialize(ctxt);

                // verify that even top level exceptions go through
                // the OnError handler
                UnauthorizedAccessException expectedException = null;
                try
                {
                    // cause a domain service not initialized exception
                    await cities.InvokeAsync(new InvokeDescription(invokeOperation, new object[] { city }), CancellationToken.None);
                }
                catch (UnauthorizedAccessException e)
                {
                    expectedException = e;
                }

                Assert.IsNotNull(expectedException, "Expected Invoke to be denied");
                Assert.AreEqual("Access to operation 'GetStateIfUser' was denied.", expectedException.Message);
            }

            // Perform an invoke against a method that has a custom auth attribute requiring WaGuy
            // where the user is correct -- should be allowed
            using (CityDomainService cities = new CityDomainService())
            {
                MockUser waGuy = new MockUser("WAGuy");
                waGuy.IsAuthenticated = true;

                // Prepare an invoke to call a method that has a custom auth attribute
                DomainServiceContext ctxt = new WcfDomainServiceContext(new MockDataService(waGuy), DomainOperationType.Invoke);
                cities.Initialize(ctxt);

                // verify that even top level exceptions go through
                // the OnError handler
                UnauthorizedAccessException expectedException = null;
                try
                {
                    // cause a domain service not initialized exception
                    await cities.InvokeAsync(new InvokeDescription(invokeOperation, new object[] { city }), CancellationToken.None);
                }
                catch (UnauthorizedAccessException e)
                {
                    expectedException = e;
                }

                Assert.IsNull(expectedException, "Expected Invoke to be allowed");
            }
        }
Exemplo n.º 3
0
        public async Task Authorization_Custom_Authorization_On_Custom_Update()
        {
            // Specifically, the City data is marked so that no one can delete a Zip code
            // from WA unless their user name is WAGuy
            MockUser notWaGuy = new MockUser("notWAGuy");

            notWaGuy.IsAuthenticated = true;

            DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(typeof(CityDomainService));
            City city = null;

            // Execute a query to get a City from WA
            using (CityDomainService cities = new CityDomainService())
            {
                DomainOperationEntry getCitiesQuery = serviceDescription.GetQueryMethod("GetCities");

                // Now prepare for a query to find a Zip in WA
                DomainServiceContext ctxt = new WcfDomainServiceContext(new MockDataService(notWaGuy), DomainOperationType.Query);
                cities.Initialize(ctxt);

                IEnumerable result = (await cities.QueryAsync <City>(new QueryDescription(getCitiesQuery), CancellationToken.None)).Result;

                city = result.OfType <City>().FirstOrDefault(z => z.StateName == "WA");
                Assert.IsNotNull(city, "Could not find a city in WA");
            }


            using (CityDomainService cities = new CityDomainService())
            {
                // Now prepare for a submit to invoke AssignCityZoneIfAuthorized as a named update method
                DomainServiceContext ctxt = new WcfDomainServiceContext(new MockDataService(notWaGuy), DomainOperationType.Submit);
                cities.Initialize(ctxt);

                // Prepare an attempt to delete this with a user whose name is not WAGuy
                // This should fail due to a custom auth attribute
                List <ChangeSetEntry> entries = new List <ChangeSetEntry>();

                ChangeSetEntry entry = new ChangeSetEntry();
                entry.DomainOperationEntry = serviceDescription.GetCustomMethod(typeof(City), "AssignCityZoneIfAuthorized");
                entry.EntityActions        = new EntityActionCollection {
                    { "AssignCityZoneIfAuthorized", new object[] { "SomeZone" } }
                };
                entry.Operation = DomainOperation.Update;
                entry.Entity    = city;
                entries.Add(entry);

                UnauthorizedAccessException exception = null;
                try
                {
                    await ChangeSetProcessor.ProcessAsync(cities, entries);
                }
                catch (UnauthorizedAccessException ex)
                {
                    exception = ex;
                }
                Assert.IsNotNull(exception, "Expected failure attempting to perform custom method on WA with inappropriate user name");
                Assert.AreEqual("Only one user is authorized to execute operation 'AssignCityZoneIfAuthorized', and it isn't you.", exception.Message);
            }

            // Now do that again but with a user who is WAGuy -- it should succeed
            using (CityDomainService cities = new CityDomainService())
            {
                MockUser waGuy = new MockUser("WAGuy");
                waGuy.IsAuthenticated = true;

                // Now prepare for a submit to invoke AssignCityZoneIfAuthorized as a named update method
                DomainServiceContext ctxt = new WcfDomainServiceContext(new MockDataService(waGuy), DomainOperationType.Submit);
                cities.Initialize(ctxt);

                // Prepare an attempt to delete this with a user whose name is not WAGuy
                // This should fail due to a custom auth attribute

                // Prepare a submit to call the AssignCityZoneIfAuthorized with an unauthorized user
                List <ChangeSetEntry> entries = new List <ChangeSetEntry>();

                ChangeSetEntry entry = new ChangeSetEntry();
                entry.DomainOperationEntry = serviceDescription.GetCustomMethod(typeof(City), "AssignCityZoneIfAuthorized");
                entry.EntityActions        = new EntityActionCollection {
                    { "AssignCityZoneIfAuthorized", new object[] { "SomeZone" } }
                };
                entry.Operation = DomainOperation.Update;
                entry.Entity    = city;
                entries.Add(entry);

                Exception exception = null;
                try
                {
                    await ChangeSetProcessor.ProcessAsync(cities, entries);
                }
                catch (UnauthorizedAccessException ex)
                {
                    exception = ex;
                }
                Assert.IsNull(exception, "Expected success attempting to delete a zip from WA with inappropriate user name");
            }
        }
Exemplo n.º 4
0
        public async Task Authorization_Custom_Authorization_On_CUD()
        {
            // Specifically, the City data is marked so that no one can delete a Zip code
            // from WA unless their user name is WAGuy
            MockUser notWaGuy = new MockUser("notWAGuy");

            notWaGuy.IsAuthenticated = true;

            DomainServiceDescription serviceDescription = DomainServiceDescription.GetDescription(typeof(CityDomainService));
            Zip zip = null;

            // First execute a query to get some zips
            DomainOperationEntry getZipsQuery = serviceDescription.GetQueryMethod("GetZips");
            DomainServiceContext ctxt;

            using (CityDomainService cities = new CityDomainService())
            {
                // Now prepare for a query to find a Zip in WA
                ctxt = new WcfDomainServiceContext(new MockDataService(notWaGuy), DomainOperationType.Query);
                cities.Initialize(ctxt);
                IEnumerable result = (await cities.QueryAsync <Zip>(new QueryDescription(getZipsQuery), CancellationToken.None)).Result;

                zip = result.OfType <Zip>().FirstOrDefault(z => z.StateName == "WA");
                Assert.IsNotNull(zip, "Could not find a zip code in WA");
            }

            // Prepare a submit to delete this zip from a user who is not authorized
            using (CityDomainService cities = new CityDomainService())
            {
                // Now prepare for a query to find a Zip in WA
                ctxt = new WcfDomainServiceContext(new MockDataService(notWaGuy), DomainOperationType.Submit);
                cities.Initialize(ctxt);

                // Prepare an attempt to delete this with a user whose name is not WAGuy
                // This should fail due to a custom auth attribute
                List <ChangeSetEntry> entries = new List <ChangeSetEntry>();

                ChangeSetEntry entry = new ChangeSetEntry(1, zip, zip, DomainOperation.Delete);
                entries.Add(entry);
                UnauthorizedAccessException exception = null;
                try
                {
                    await ChangeSetProcessor.ProcessAsync(cities, entries);
                }
                catch (UnauthorizedAccessException ex)
                {
                    exception = ex;
                }
                Assert.IsNotNull(exception, "Expected failure attempting to delete a zip from WA with inappropriate user name");
                Assert.AreEqual("Only one user can delete zip codes from that state, and it isn't you.", exception.Message);
            }

            // Now do that again but with a user who is WAGuy -- it should succeed
            using (CityDomainService cities = new CityDomainService())
            {
                MockUser waGuy = new MockUser("WAGuy");
                waGuy.IsAuthenticated = true;

                // Now try a submit where the user *is* Mathew to validate we succeed
                ctxt = new WcfDomainServiceContext(new MockDataService(waGuy), DomainOperationType.Submit);
                cities.Initialize(ctxt);
                List <ChangeSetEntry> entries = new List <ChangeSetEntry>();

                ChangeSetEntry entry = new ChangeSetEntry(1, zip, zip, DomainOperation.Delete);
                entries.Add(entry);
                Exception exception = null;
                try
                {
                    await ChangeSetProcessor.ProcessAsync(cities, entries);
                }
                catch (UnauthorizedAccessException ex)
                {
                    exception = ex;
                }
                Assert.IsNull(exception, "Expected success attempting to delete a zip from WA with inappropriate user name");
            }
        }