Exemplo n.º 1
0
        public void UnlinkSensor(int id, string sensorId)
        {
            // Disallow access to the service bus for this sensor
            var serviceManagementWrapper = new ServiceManagementWrapper(AcsNamespace, ManagementIssuer, ManagementKey);
            var client = serviceManagementWrapper.CreateManagementServiceClient();

            client.IgnoreResourceNotFoundException = true;

            // Clean up if we already exist as a sensor
            var existingRule = client.Rules.AddQueryOption("$filter", "Description eq '" + string.Format("Add Send claim value for sensor id {0}", sensorId) + "'").FirstOrDefault();

            if (existingRule != null)
            {
                client.DeleteObject(existingRule);
                client.SaveChanges(SaveChangesOptions.Batch);
            }
            serviceManagementWrapper.RemoveServiceIdentity(sensorId);

            // Unlink sensor in our datastore
            var brew = GetBrew(id);

            brew.SensorId     = null;
            brew.LastModified = DateTime.UtcNow;
            BrewRepository.CommitChanges();
        }
Exemplo n.º 2
0
        public static bool CheckServiceIdentityExists(AcsNamespaceDescription namespaceDesc, string serviceIdentityName)
        {
            var acs = new ServiceManagementWrapper(namespaceDesc.Namespace, namespaceDesc.UserName, namespaceDesc.Password);
            var serviceIdentities = acs.RetrieveServiceIdentities();

            return(serviceIdentities.Any(serviceIdentity => serviceIdentity.Name == serviceIdentityName));
        }
Exemplo n.º 3
0
        public static bool CheckRuleGroupHasRules(AcsNamespaceDescription namespaceDesc, string relyingParty, string ruleGroup, int ruleCount)
        {
            var acs   = new ServiceManagementWrapper(namespaceDesc.Namespace, namespaceDesc.UserName, namespaceDesc.Password);
            var rules = acs.RetrieveRules(ruleGroup);

            return((rules != null) && (rules.Count() == ruleCount));
        }
Exemplo n.º 4
0
        public static bool CheckRelyingPartyExists(AcsNamespaceDescription namespaceDesc, string relyingPartyName)
        {
            var acs            = new ServiceManagementWrapper(namespaceDesc.Namespace, namespaceDesc.UserName, namespaceDesc.Password);
            var relyingParties = acs.RetrieveRelyingParties();

            return(relyingParties.Any(relyingParty => relyingParty.Name == relyingPartyName));
        }
Exemplo n.º 5
0
        public void SaveChanges(Action <LogInfo> logAction)
        {
            try
            {
                var managementWrapper = new ServiceManagementWrapper(this.namespaceDesc.Namespace, this.namespaceDesc.UserName, this.namespaceDesc.Password);

                CheckConnection(managementWrapper);

                foreach (var command in this.commands)
                {
                    try
                    {
                        command.Execute(managementWrapper, logAction);
                    }
                    catch (Exception ex1)
                    {
                        if (!LogException(logAction, LogInfoTypeEnum.Error, ex1))
                        {
                            throw;
                        }
                    }
                }
            }
            catch (Exception ex2)
            {
                if (!LogException(logAction, LogInfoTypeEnum.FatalError, ex2))
                {
                    throw;
                }
            }
        }
Exemplo n.º 6
0
        public static void CreateRelyingPartysWithRules(ServiceManagementWrapper acsWrapper)
        {
            var relyingPartyName = "Adatum.SimulatedIssuer.6";

            var ips = new[] { SocialIdentityProviders.WindowsLiveId.DisplayName, SocialIdentityProviders.Google.DisplayName, "Facebook" };

            Console.Write(string.Format("Creating {0} relying party....", relyingPartyName));
            var realmAddress = "https://localhost/Adatum.FederationProvider.6/";
            var replyAddress = "https://localhost/Adatum.FederationProvider.6/Federation.aspx";
            var ruleGroup    = string.Format("Default role group for {0}", relyingPartyName);


            acsWrapper.AddRelyingParty(relyingPartyName, realmAddress, replyAddress, null, null, null, ruleGroup, ips);

            Console.WriteLine("done");


            var relyingParty     = acsWrapper.RetrieveRelyingParties().Single(rp => rp.Name == relyingPartyName);
            var defaultRuleGroup = relyingParty.RelyingPartyRuleGroups.FirstOrDefault();

            acsWrapper.RemoveAllRulesInGroup(defaultRuleGroup.RuleGroup.Name);

            // Social IPs
            CreateGoogleRules(acsWrapper, defaultRuleGroup);
            CreateFacebookRules(acsWrapper, defaultRuleGroup);
            CreateWindowsLiveRules(acsWrapper, defaultRuleGroup);
        }
Exemplo n.º 7
0
        public static bool CheckIdentityProviderExists(AcsNamespaceDescription namespaceDesc, string idpDisplayName)
        {
            var acs = new ServiceManagementWrapper(namespaceDesc.Namespace, namespaceDesc.UserName, namespaceDesc.Password);
            var identityProviders = acs.RetrieveIdentityProviders();

            return(identityProviders.Any(provider => provider.DisplayName == idpDisplayName));
        }
Exemplo n.º 8
0
        public static bool CheckRuleGroupHasRule(AcsNamespaceDescription namespaceDesc, string relyingParty, string ruleGroup, string ruleDescription)
        {
            var acs   = new ServiceManagementWrapper(namespaceDesc.Namespace, namespaceDesc.UserName, namespaceDesc.Password);
            var rules = acs.RetrieveRules(ruleGroup);

            return(rules.Any(rule => rule.Description.Equals(ruleDescription)));
        }
Exemplo n.º 9
0
        /// <summary>
        /// Creates the management service client.
        /// </summary>
        /// <returns></returns>
        protected ManagementService CreateManagementServiceClient()
        {
            var serviceManagementWrapper = new ServiceManagementWrapper(ServiceNamespace, ServiceNamespaceManagementUserName, ServiceNamespaceManagementUserKey);
            var client = serviceManagementWrapper.CreateManagementServiceClient();

            client.IgnoreResourceNotFoundException = true;
            return(client);
        }
Exemplo n.º 10
0
        public static bool CheckRuleGroupExists(AcsNamespaceDescription namespaceDesc, string relyingParty, string ruleGroup)
        {
            var acs            = new ServiceManagementWrapper(namespaceDesc.Namespace, namespaceDesc.UserName, namespaceDesc.Password);
            var relyingParties = acs.RetrieveRelyingParties();

            return(relyingParties.Where(rp => rp.Name == relyingParty).Select(
                       rp => rp.RelyingPartyRuleGroups.Any(rg => rg.RuleGroup.Name == ruleGroup)).FirstOrDefault());
        }
Exemplo n.º 11
0
        public static bool CheckRelyingPartyHasKeys(AcsNamespaceDescription namespaceDesc, string relyingParty, int keyCount)
        {
            var acs    = new ServiceManagementWrapper(namespaceDesc.Namespace, namespaceDesc.UserName, namespaceDesc.Password);
            var client = acs.CreateManagementServiceClient();

            var count = client.RelyingPartyKeys.Where(k => k.RelyingParty.Name.Equals(relyingParty)).Count();

            return(count == keyCount);
        }
Exemplo n.º 12
0
        public static void CreateIdentityProviders(ServiceManagementWrapper acsWrapper)
        {
            acsWrapper.AddGoogleIdentityProvider();

            acsWrapper.AddYahooIdentityProvider();

            CreateIdentityProvider(LitwareIdentityProvider, @"..\..\..\Litware.SimulatedIssuer.7\FederationMetadata\2007-06\FederationMetadata.xml", acsWrapper);

            CreateIdentityProvider(AdatumIdentityProvider, @"..\..\..\Adatum.SimulatedIssuer.7\FederationMetadata\2007-06\FederationMetadata.xml", acsWrapper);
        }
Exemplo n.º 13
0
        private static void CreateContosoRules(ServiceManagementWrapper acsWrapper)
        {
            Console.Write("Creating Contoso mapping rules....");

            var identityProviderName = "Windows Live ID";
            var relyingParty         = acsWrapper.RetrieveRelyingParties().Single(rp => rp.Name == "Contoso");
            var defaultRuleGroup     = relyingParty.RelyingPartyRuleGroups.FirstOrDefault();

            // remove rules
            acsWrapper.RemoveAllRulesInGroup(defaultRuleGroup.RuleGroup.Name);

            // add name
            acsWrapper.AddSimpleRuleToRuleGroup(
                defaultRuleGroup.RuleGroup.Name,
                identityProviderName,
                ClaimTypes.NameIdentifier,
                null,
                ClaimTypes.Name,
                "rick");

            // add organization
            acsWrapper.AddSimpleRuleToRuleGroupWithoutSpecifyInputClaim(
                defaultRuleGroup.RuleGroup.Name,
                identityProviderName,
                Fabrikam.ClaimTypes.Organization,
                "Contoso");

            // add cost center
            acsWrapper.AddSimpleRuleToRuleGroupWithoutSpecifyInputClaim(
                defaultRuleGroup.RuleGroup.Name,
                identityProviderName,
                Fabrikam.ClaimTypes.CostCenter,
                Contoso.CostCenters.SingleCostCenter);

            // add role
            acsWrapper.AddSimpleRuleToRuleGroupWithoutSpecifyInputClaim(
                defaultRuleGroup.RuleGroup.Name,
                identityProviderName,
                ClaimTypes.Role,
                Fabrikam.Roles.ShipmentCreator);

            // given name
            acsWrapper.AddSimpleRuleToRuleGroupWithoutSpecifyInputClaim(
                defaultRuleGroup.RuleGroup.Name,
                identityProviderName,
                ClaimTypes.GivenName,
                "Rick");

            // surname
            acsWrapper.AddSimpleRuleToRuleGroupWithoutSpecifyInputClaim(defaultRuleGroup.RuleGroup.Name,
                                                                        identityProviderName,
                                                                        ClaimTypes.Surname,
                                                                        "Rico");
            Console.WriteLine("done.");
        }
Exemplo n.º 14
0
        public static void CreateEnrollmentRelyingParty(string[] identityProviders, ServiceManagementWrapper acsWrapper)
        {
            Console.Write("Creating f-shipping.Enrollment relying party....");

            var realmAddress = "https://localhost/f-shipping.Enrollment.7";
            var replyAddress = "https://localhost/f-shipping.Enrollment.7/FederationResult";
            var ruleGroup    = "Default rule group for f-Shipping.Enrollment.7";

            acsWrapper.AddRelyingParty("f-Shipping.Enrollment.7", realmAddress, replyAddress, null, null, null, ruleGroup, identityProviders);

            Console.WriteLine("done");
        }
Exemplo n.º 15
0
 private static void CheckConnection(ServiceManagementWrapper managementWrapper)
 {
     try
     {
         managementWrapper.GetTokenFromACS();
     }
     catch (Exception ex)
     {
         throw new Exception("A token could not be retrieved from ACS, there might be connection problems or errors in the configuration." +
                             Environment.NewLine + "Please check the namespace, username and password provided.", ex);
     }
 }
Exemplo n.º 16
0
        private static void CreateAOrderRelyingPartyWithRules(ServiceManagementWrapper acsWrapper)
        {
            var ips = new[] { LitwareIdentityProvider };

            Console.Write(string.Format("Creating {0} relying party....", AOrderRelyingParty));
            var ruleGroup = string.Format("Default role group for {0}", AOrderRelyingParty);

            byte[] key = Convert.FromBase64String(TokenKey);
            acsWrapper.AddRelyingPartyWithSymmetricKey(AOrderRelyingParty, AOrderRealmAddress, "https://break_here", key, TokenType.SWT, 30, ruleGroup, ips);
            Console.WriteLine("done");
            CreateAOrderRules(acsWrapper);
        }
Exemplo n.º 17
0
        private static void CreateYahooRules(ServiceManagementWrapper acsWrapper, RelyingPartyRuleGroup defaultRuleGroup)
        {
            Console.Write("Creating Yahoo! mapping rules....");
            var name = SocialIdentityProviders.Yahoo.HomeRealm;

            // pass name
            acsWrapper.AddPassThroughRuleToRuleGroup(defaultRuleGroup.RuleGroup.Name, name, ClaimTypes.Name);

            // pass nameidentifier
            acsWrapper.AddPassThroughRuleToRuleGroup(defaultRuleGroup.RuleGroup.Name, name, ClaimTypes.NameIdentifier);

            Console.WriteLine("done.");
        }
Exemplo n.º 18
0
        private static void Main()
        {
            var acs = new ServiceManagementWrapper(AcsServiceNamespace, AcsUsername, AcsPassword);

            Console.WriteLine("Setting up ACS namespace:" + AcsServiceNamespace);
            CleanupIdentityProviders(acs);
            CleanupRelyingParties(acs);
            CreateIdentityProviders(acs);
            CreateAOrderRelyingPartyWithRules(acs);

            Console.WriteLine("Setup complete. Press any key to exit.");
            Console.ReadKey();
        }
Exemplo n.º 19
0
        private static void CreateFacebookRules(ServiceManagementWrapper acsWrapper, RelyingPartyRuleGroup defaultRuleGroup)
        {
            Console.Write("Creating Facebook mapping rules....");
            var name = "Facebook";

            // pass name
            acsWrapper.AddPassThroughRuleToRuleGroup(defaultRuleGroup.RuleGroup.Name, name, ClaimTypes.Name);

            // pass nameidentifier
            acsWrapper.AddPassThroughRuleToRuleGroup(defaultRuleGroup.RuleGroup.Name, name, ClaimTypes.NameIdentifier);

            Console.WriteLine("done.");
        }
Exemplo n.º 20
0
        private static void CleanupRelyingParties(ServiceManagementWrapper acsWrapper)
        {
            Console.Write("Cleaning up relying parties...");
            var rps = acsWrapper.RetrieveRelyingParties();

            foreach (var rp in rps)
            {
                if (rp.Name != "AccessControlManagement")
                {
                    acsWrapper.RemoveRelyingParty(rp.Name);
                }
            }
            Console.WriteLine("done");
        }
Exemplo n.º 21
0
        private static void CleanupIdentityProviders(ServiceManagementWrapper acsWrapper)
        {
            Console.Write("Cleaning up identity providers...");
            var ips = acsWrapper.RetrieveIdentityProviders();

            foreach (var ip in ips)
            {
                if (ip.DisplayName != SocialIdentityProviders.WindowsLiveId.DisplayName)
                {
                    acsWrapper.RemoveIssuer(ip.DisplayName);
                }
            }
            Console.WriteLine("done");
        }
Exemplo n.º 22
0
        private static void CreateWindowsLiveRules(ServiceManagementWrapper acsWrapper, RelyingPartyRuleGroup defaultRuleGroup)
        {
            Console.Write("Creating Windows Live ID mapping rules....");

            var name = SocialIdentityProviders.WindowsLiveId.DisplayName;

            // pass nameidentifier
            acsWrapper.AddPassThroughRuleToRuleGroup(defaultRuleGroup.RuleGroup.Name, name, ClaimTypes.NameIdentifier);

            // pass name
            acsWrapper.AddPassThroughRuleToRuleGroup(defaultRuleGroup.RuleGroup.Name, name, ClaimTypes.NameIdentifier, ClaimTypes.Name);

            Console.WriteLine("done.");
        }
Exemplo n.º 23
0
        private static void CreateEnrollmentRules(ServiceManagementWrapper acsWrapper)
        {
            var name = "f-Shipping.Enrollment.7";

            var rp = acsWrapper.RetrieveRelyingParties().Single(r => r.Name == name);
            var defaultRuleGroup = rp.RelyingPartyRuleGroups.FirstOrDefault();

            acsWrapper.RemoveAllRulesInGroup(defaultRuleGroup.RuleGroup.Name);

            // Social IP
            CreateGoogleRules(acsWrapper, defaultRuleGroup);
            CreateYahooRules(acsWrapper, defaultRuleGroup);
            CreateWindowsLiveRules(acsWrapper, defaultRuleGroup);
        }
        public ActionResult CreateTenantWithSocialProvider(string OrganizationName, HttpPostedFileBase logoFile)
        {
            string organizationInternalName = SanitizeString(OrganizationName);

            if (this.IsOrganizationNameValid(organizationInternalName))
            {
                var ipName = ClaimHelper.GetCurrentUserClaim(Fabrikam.ClaimTypes.IdentityProvider).Value;
                if (ipName == SocialIdentityProviders.WindowsLiveId.HomeRealm)
                {
                    ipName = SocialIdentityProviders.WindowsLiveId.DisplayName;
                }
                Organization organization = new Organization {
                    Name = organizationInternalName, DisplayName = OrganizationName, HomeRealm = ipName, LogoPath = "~/Content/images/generic-logo.png"
                };

                if (logoFile != null && logoFile.ContentLength > 0)
                {
                    var imageFolderRelativePath = "~/Content/images/";
                    var imageFolderAbsolutePath = Server.MapPath("~/");
                    imageFolderAbsolutePath = string.Concat(imageFolderAbsolutePath, "..\\f-shipping.7\\Content\\images\\");
                    var fileName     = string.Concat(organizationInternalName, "-logo.png");
                    var fileFullPath = string.Concat(imageFolderAbsolutePath, fileName);
                    logoFile.SaveAs(fileFullPath);
                    organization.LogoPath = string.Concat(imageFolderRelativePath, fileName);
                }

                OrganizationRepository organizationRepository = new OrganizationRepository();
                organizationRepository.AddOrganization(organization);
                ServiceManagementWrapper acsWrapper = new ServiceManagementWrapper(acsServiceNamespace, acsUsername, acsPassword);

                var relayingPartyName = organizationInternalName;
                var realmAddress      = string.Format("https://localhost/f-shipping.7/{0}", organizationInternalName);
                var replyAddress      = string.Format("https://localhost/f-shipping.7/{0}/FederationResult", organizationInternalName);
                var ruleGroup         = string.Format("Default role group for {0}", organizationInternalName);
                var socialProviders   = new string[] { ipName };

                acsWrapper.AddRelyingParty(organizationInternalName, realmAddress, replyAddress, null, null, null, ruleGroup, socialProviders);

                var nameIdentifierValue = ClaimHelper.GetCurrentUserClaim(ClaimTypes.NameIdentifier).Value;

                CreateRulesForTenantWithSocialIP(organizationInternalName, ipName, acsWrapper, ruleGroup, nameIdentifierValue);

                return(View("CompleteEnrollment"));
            }
            return(View("EnrollWithSocialProvider", new EnrollmentViewModel {
                ErrorMessage = "Organization name not valid", OrganizationName = OrganizationName
            }));
        }
Exemplo n.º 25
0
        private static void Main()
        {
            var acs = new ServiceManagementWrapper(AcsServiceNamespace, AcsUsername, AcsPassword);

            Console.WriteLine("Setting up ACS namespace:" + AcsServiceNamespace);

            CleanupRelyingParty(acs);

            acs.RemoveIdentityProvider("Google");
            acs.AddGoogleIdentityProvider();
            acs.RemoveIdentityProvider("Facebook");
            acs.AddFacebookIdentityProvider("Facebook", "Your Facebook Application Id", "Your Facebook Application Secret");

            CreateRelyingPartysWithRules(acs);

            Console.WriteLine("Setup complete. Press any key to exit.");
            Console.ReadKey();
        }
Exemplo n.º 26
0
        public static void CreateRelyingPartysWithRules(ServiceManagementWrapper acsWrapper)
        {
            var ips = new[] { AdatumIdentityProvider };

            CreateRelyingParty("Adatum", ips, acsWrapper);
            CreateAdatumRules(acsWrapper);

            ips = new[] { LitwareIdentityProvider };
            CreateRelyingParty("Litware", ips, acsWrapper);
            CreateLitwareRules(acsWrapper);

            ips = new[] { SocialIdentityProviders.WindowsLiveId.DisplayName };
            CreateRelyingParty("Contoso", ips, acsWrapper);
            CreateContosoRules(acsWrapper);

            ips = new[] { SocialIdentityProviders.WindowsLiveId.DisplayName, SocialIdentityProviders.Google.DisplayName, SocialIdentityProviders.Yahoo.DisplayName };
            CreateEnrollmentRelyingParty(ips, acsWrapper);
            CreateEnrollmentRules(acsWrapper);
        }
        // POST
        public ActionResult CreateTenantManually(string organizationName, string issuerName, string iPStsAddress, string adminClaimType, string adminClaimValue, HttpPostedFileBase certificateFile, HttpPostedFileBase logoFile, string costCenterClaimType)
        {
            string organizationInternalName = this.SanitizeString(organizationName);

            if (this.IsOrganizationNameValid(organizationInternalName))
            {
                Organization organization = new Organization {
                    Name = organizationInternalName, DisplayName = organizationName, LogoPath = "~/Content/images/generic-logo.png"
                };

                if (logoFile != null && logoFile.ContentLength > 0)
                {
                    var imageFolderRelativePath = "~/Content/images/";
                    var imageFolderAbsolutePath = Server.MapPath("~/");
                    imageFolderAbsolutePath = string.Concat(imageFolderAbsolutePath, "..\\f-shipping.7\\Content\\images\\");
                    var fileName     = string.Concat(organizationInternalName, "-logo.png");
                    var fileFullPath = string.Concat(imageFolderAbsolutePath, fileName);
                    logoFile.SaveAs(fileFullPath);
                    organization.LogoPath = string.Concat(imageFolderRelativePath, fileName);
                }

                OrganizationRepository organizationRepository = new OrganizationRepository();
                organizationRepository.AddOrganization(organization);
                ServiceManagementWrapper acsWrapper = new ServiceManagementWrapper(acsServiceNamespace, acsUsername, acsPassword);

                // add the new IP
                var    identityProviderName = issuerName;
                byte[] signingCertBytes     = new byte[certificateFile.InputStream.Length];
                certificateFile.InputStream.Read(signingCertBytes, 0, (int)certificateFile.InputStream.Length);
                acsWrapper.AddIdentityProviderManually(identityProviderName, iPStsAddress, WebSSOProtocolType.WsFederation, signingCertBytes, null);

                var ruleGroup = string.Format("Default role group for {0}", organizationInternalName);

                this.CreateRelyingParty(organizationInternalName, identityProviderName, ruleGroup, acsWrapper);
                this.CreateRulesForTenantWithOwnIP(organizationInternalName, identityProviderName, acsWrapper, ruleGroup, adminClaimType, adminClaimValue, costCenterClaimType);


                return(View("CompleteEnrollment"));
            }
            return(View("EnrollManually", new EnrollmentViewModel {
                ErrorMessage = "Organization name not valid", OrganizationName = organizationName
            }));
        }
        public ActionResult JoinNow()
        {
            ServiceManagementWrapper acs = new ServiceManagementWrapper(acsServiceNamespace, acsUsername, acsPassword);

            var ips = acs.RetrieveIdentityProviders();

            var listItems = new List <SelectListItem>();

            foreach (var ip in ips)
            {
                if (ip.IsSocial())
                {
                    listItems.Add(new SelectListItem {
                        Text = ip.LoginLinkName, Value = ip.DisplayName.Split(' ')[0]
                    });
                }
            }

            return(this.View(listItems));
        }
Exemplo n.º 29
0
        private void AddRelyingParty(ServiceManagementWrapper acsWrapper, Action <LogInfo> logAction)
        {
            var tokenLifetime = this.relyingPartySpec.TokenLifetime();

            byte[]   signingCertBytes     = null;
            string   signingCertPassword  = null;
            DateTime?signingCertStartDate = null;
            DateTime?signingCertEndDate   = null;

            var signingCert = this.relyingPartySpec.SigningCertificate();

            if (signingCert != null)
            {
                signingCertBytes     = signingCert.Bytes();
                signingCertPassword  = signingCert.Password();
                signingCertStartDate = signingCert.StartDate();
                signingCertEndDate   = signingCert.EndDate();
            }

            this.LogMessage(logAction, string.Format("Adding Relying Party '{0}'", this.relyingPartySpec.Name()));
            acsWrapper.AddRelyingPartyWithKey(
                this.relyingPartySpec.Name(),
                this.relyingPartySpec.RealmAddress(),
                this.relyingPartySpec.ReplyAddress(),
                this.relyingPartySpec.SymmetricKey(),
                this.relyingPartySpec.GetTokenType(),
                (tokenLifetime == 0 ? Constants.RelyingPartyTokenLifetime : tokenLifetime),
                signingCertBytes,
                signingCertPassword,
                signingCertStartDate,
                signingCertEndDate,
                this.relyingPartySpec.EncryptionCertificate(),
                string.Empty,
                this.relyingPartySpec.AllowedIdentityProviders().ToArray());
            this.LogSavingChangesMessage(logAction);
        }
Exemplo n.º 30
0
        public void LinkSensor(int id, string sensorId)
        {
            // Has a sensor already been linked?
            var brewWithSensor = BrewRepository.GetAll().FirstOrDefault(b => b.SensorId == sensorId);

            if (brewWithSensor != null && brewWithSensor.Id != id)
            {
                throw new ArgumentException(
                          string.Format("The sensor with id {0} can not be linked to the brew because the sensor has already been linked to another brew.", sensorId), "sensorId");
            }

            // Get the brew
            var brew = GetBrew(id);

            // First unlink the current sensor
            if (!string.IsNullOrEmpty(brew.SensorId))
            {
                UnlinkSensor(id, brew.SensorId);
            }

            // Link sensor in our datastore
            brew.SensorId     = sensorId;
            brew.LastModified = DateTime.UtcNow;
            BrewRepository.CommitChanges();

            // We want a custom identity for the sensor which only allows sending to the service bus.
            var serviceManagementWrapper = new ServiceManagementWrapper(AcsNamespace, ManagementIssuer, ManagementKey);
            var client = serviceManagementWrapper.CreateManagementServiceClient();

            client.IgnoreResourceNotFoundException = true;

            // Clean up if we already exist as a sensor
            var existingRule = client.Rules.AddQueryOption("$filter", "Description eq '" + string.Format("Add Send claim value for sensor id {0}", sensorId) + "'").FirstOrDefault();

            if (existingRule != null)
            {
                client.DeleteObject(existingRule);
                client.SaveChanges(SaveChangesOptions.Batch);
            }
            serviceManagementWrapper.RemoveServiceIdentity(sensorId);

            // Create a new identity
            var serviceIdentity = new ServiceIdentity
            {
                Name        = sensorId,
                Description = string.Format("Sensor id: {0}", sensorId)
            };
            var serviceIdentityKey = new ServiceIdentityKey
            {
                DisplayName = string.Format("Credentials for {0}", sensorId),
                Value       = Encoding.UTF8.GetBytes(sensorId),
                Type        = IdentityKeyTypes.Symmetric.ToString(),
                Usage       = IdentityKeyUsages.Password.ToString(),
                StartDate   = DateTime.UtcNow,
                EndDate     = DateTime.UtcNow.AddMonths(2) // sensors can be linked for up to 2 months
            };

            // Process modifications to the namespace
            client.AddToServiceIdentities(serviceIdentity);
            client.AddRelatedObject(serviceIdentity, "ServiceIdentityKeys", serviceIdentityKey);
            client.SaveChanges(SaveChangesOptions.Batch);

            // Add a Send claim
            var issuer    = client.Issuers.AddQueryOption("$filter", "Name eq 'LOCAL AUTHORITY'").FirstOrDefault();
            var ruleGroup = client.RuleGroups.AddQueryOption("$filter", "Name eq 'Default Rule Group for ServiceBus'").FirstOrDefault();
            var rule      = new Rule
            {
                Description      = string.Format("Add Send claim value for sensor id {0}", sensorId),
                InputClaimType   = "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier",
                InputClaimValue  = sensorId,
                OutputClaimType  = "net.windows.servicebus.action",
                OutputClaimValue = "Send",
                IssuerId         = issuer.Id,
                RuleGroupId      = ruleGroup.Id,
                RuleGroup        = ruleGroup,
                Issuer           = issuer
            };

            client.AddToRules(rule);
            client.SaveChanges(SaveChangesOptions.Batch);
        }