static void CreateDatabase(SlkSPSiteMapping mapping, string databaseName, string appPoolAccountName, string databaseSchema)
        {
            // restrict the characters in <databaseName>
            if (!Regex.Match(databaseName, @"^\w+$").Success)
            {
                throw new SafeToDisplayException(SlkCulture.GetResources().InvalidDatabaseName, databaseName);
            }

            // if <appPoolAccountName> is null, set it to the name of the application pool account
            // (e.g. "NT AUTHORITY\NETWORK SERVICE"); set <appPoolSid> to its SID
            byte[] appPoolSid = null;
            if (appPoolAccountName == null)
            {
                using (SPSite site = new SPSite(mapping.SPSiteGuid))
                {
                    appPoolAccountName = site.WebApplication.ApplicationPool.Username;
                }
            }

            NTAccount          appPoolAccount = new NTAccount(appPoolAccountName);
            SecurityIdentifier securityId     =
                (SecurityIdentifier)appPoolAccount.Translate(typeof(SecurityIdentifier));

            appPoolSid = new byte[securityId.BinaryLength];
            securityId.GetBinaryForm(appPoolSid, 0);

            SlkUtilities.ImpersonateAppPool(delegate()
            {
                CreateDatabase(mapping.DatabaseServerConnectionString, databaseName,
                               mapping.DatabaseConnectionString, appPoolAccountName,
                               appPoolSid, databaseSchema);
            });
        }
        int DeleteMapping(out string output)
        {
            string guidValue = Value("guid");

            if (string.IsNullOrEmpty(guidValue))
            {
                output = FormatString(culture.Resources.StsMissingParameter, "guid");
                return((int)ErrorCodes.SyntaxError);
            }

            Guid guid = new Guid(guidValue);

            // set <mapping> to the mapping between <spSiteGuid> and the LearningStore connection information for that SPSite
            SlkSPSiteMapping mapping = SlkSPSiteMapping.GetMapping(guid);

            if (mapping == null)
            {
                output = FormatString(culture.Resources.StsInvalidGuid, guid);
                return((int)ErrorCodes.GeneralError);
            }
            else
            {
                mapping.Delete();
                output = FormatString(culture.Resources.StsMappingDeleted, guid);
                return(0);
            }
        }
        /// <summary>
        /// Retrieves the SLK Settings XML for a given SPSite.
        /// </summary>
        ///
        /// <param name="spSiteGuid">The GUID of the SPSite to retrieve SLK Settings for.</param>
        ///
        /// <returns>
        /// A string containing SLK Settings XML, or null if <pr>spSiteGuid</pr> is not configured for
        /// use with SLK.
        /// </returns>
        ///
        /// <remarks>
        /// This method is static so it can used outside the context of IIS.  Only SharePoint
        /// administrators can perform this function.
        /// </remarks>
        ///
        /// <exception cref="SafeToDisplayException">
        /// An error occurred that can be displayed to a browser user.
        /// </exception>
        ///
        public static string GetSettingsXml(Guid spSiteGuid)
        {
            // only SharePoint administrators can perform this action
            CheckPermissions();

            // set <mapping> to the mapping between <spSiteGuid> and the LearningStore connection
            // information for that SPSite
            SlkSPSiteMapping mapping = SlkSPSiteMapping.GetMapping(spSiteGuid);

            if (mapping == null)
            {
                return(null);
            }

            // return the SLK Settings XML for this SPSite
            LearningStore learningStore = new LearningStore(mapping.DatabaseConnectionString,
                                                            String.Empty, ImpersonationBehavior.UseOriginalIdentity);

            using (LearningStorePrivilegedScope privilegedScope = new LearningStorePrivilegedScope())
            {
                LearningStoreJob   job   = learningStore.CreateJob();
                LearningStoreQuery query = learningStore.CreateQuery(Schema.SiteSettingsItem.ItemTypeName);
                query.AddColumn(Schema.SiteSettingsItem.SettingsXml);
                query.AddCondition(Schema.SiteSettingsItem.SiteGuid, LearningStoreConditionOperator.Equal, spSiteGuid);
                job.PerformQuery(query);
                DataRowCollection dataRows = job.Execute <DataTable>().Rows;
                if (dataRows.Count != 1)
                {
                    throw new SafeToDisplayException(LoadCulture(spSiteGuid).Resources.SlkSettingsNotFound, spSiteGuid);
                }
                DataRow dataRow = dataRows[0];
                return((string)dataRow[0]);
            }
        }
        int EnumMappings(out string output)
        {
            System.Text.StringBuilder builder = new System.Text.StringBuilder();

            foreach (SlkSPSiteMapping mapping in SlkSPSiteMapping.GetMappings())
            {
                string siteLabel = null;
                try
                {
                    using (SPSite spSite = new SPSite(mapping.SPSiteGuid))
                    {
                        siteLabel = spSite.Url;
                    }
                }
                catch (System.IO.FileNotFoundException)
                {
                    SPFarm           farm   = SPFarm.Local;
                    SPWebApplication webApp = farm.GetObject(mapping.SPSiteGuid) as SPWebApplication;
                    siteLabel = webApp.Name;
                }

                builder.AppendFormat(culture.Resources.StsEnumMappingLine, siteLabel, mapping.SPSiteGuid, mapping.DatabaseServer, mapping.DatabaseName);
                builder.AppendLine();
            }

            output = builder.ToString();
            return(0);
        }
Example #5
0
        /// <summary>Finds all Slk members of a site.</summary>
        /// <param name="web">The site to get the members for.</param>
        /// <param name="store">The ISlkStore to use.</param>
        /// <param name="instructorsOnly">Whether to only get instructors or not.</param>
        public void FindAllSlkMembers(SPWeb web, ISlkStore store, bool instructorsOnly)
        {
            if (web == null)
            {
                throw new ArgumentNullException("web");
            }

            this.store = store;

            // keep track of when this method started, for timeout purposes
            startTime = DateTime.Now;

            // Verify that the SPWeb is in the SPSite associated with this SlkStore, because if it
            // isn't then the code below below may be using the wrong SLK instructor and learner
            // permission names; for example, the SPSite of this SlkStore may name the instructor
            // permission "SLK Instructor", but <web> may be in a different SPSite which might name
            // the instructor permission "SLK Teacher"
            if (web.Site.ID != store.SPSiteGuid)
            {
                throw new InvalidOperationException(culture.Resources.SPWebDoesNotMatchSlkSPSite);
            }

            // Security checks: Fails if the user isn't an instructor and a Reader (implemented by EnsureInstructor)
            // since we use SPSecurity.RunWithElevatedPrivileges, we need to make sure the current user is an instructor
            if (instructorsOnly == false)
            {
                store.EnsureInstructor(web);
            }

            SlkSPSiteMapping mapping        = store.Mapping;
            SPRoleDefinition instructorRole = FindRole(web, mapping.InstructorPermission);
            SPRoleDefinition learnerRole    = FindRole(web, mapping.LearnerPermission);

            domainGroupEnumeratorType     = store.Settings.DomainGroupEnumeratorType;
            domainGroupEnumeratorAssembly = store.Settings.DomainGroupEnumeratorAssembly;

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {
                using (SPSite site2 = new SPSite(web.Url))
                {
                    using (SPWeb elevatedWeb = site2.OpenWeb())
                    {
                        IterateWebRoles(elevatedWeb, instructorRole, learnerRole, instructorsOnly, store.Settings.HideDisabledUsers);
                    }
                }
            });

            store.AssignUserItemIdentifier(users.Values);

            // populate the Users property of each item in <learnerGroups>
            foreach (SlkGroup learnerGroup in learnerGroups)
            {
                foreach (string userKey in learnerGroup.UserKeys)
                {
                    learnerGroup.AddUser(users[userKey]);
                }
            }

            learnerGroups.Sort();
        }
        /// <summary>Loads SLK configuration information from WSS and LearningStore, in a form that's
        /// suitable for copying to Configure.aspx form fields. </summary>
        ///
        /// <param name="spSiteGuid">The GUID of the SPSite to retrieve configuration information
        ///     from.</param>
        ///
        /// <returns>An AdministrationConfiguration.</returns>
        ///
        /// <remarks>
        /// This method is static so it can used outside the context of IIS.  Only SharePoint
        /// administrators can perform this function.
        /// </remarks>
        ///
        /// <exception cref="SafeToDisplayException">
        /// An error occurred that can be displayed to a browser user.
        /// </exception>
        ///
        public static AdministrationConfiguration LoadConfiguration(Guid spSiteGuid)
        {
            AdministrationConfiguration configuration = new AdministrationConfiguration(spSiteGuid);

            // only SharePoint administrators can perform this action
            CheckPermissions();

            // set <mapping> to the mapping between <spSiteGuid> and the LearningStore connection
            // information for that SPSite
            SlkSPSiteMapping mapping = SlkSPSiteMapping.GetMapping(spSiteGuid);

            // set "out" parameters based on <mappingExists> and <mapping>
            if (mapping != null)
            {
                // the mapping exists -- set "out" parameters based on <mapping>
                configuration.DatabaseServer       = mapping.DatabaseServer;
                configuration.DatabaseName         = mapping.DatabaseName;
                configuration.InstructorPermission = mapping.InstructorPermission;
                configuration.LearnerPermission    = mapping.LearnerPermission;

                // The below given condition will be true only during the migration of SLK from
                // 'SLK without Observer role' to 'SLK with Observer role' implementation
                if (mapping.ObserverPermission == null)
                {
                    mapping.ObserverPermission = LoadCulture(spSiteGuid).Resources.DefaultSlkObserverPermissionName;
                }
                configuration.ObserverPermission = mapping.ObserverPermission;
            }
            else
            {
                SlkCulture        siteCulture    = LoadCulture(spSiteGuid);
                AppResourcesLocal adminResources = SlkCulture.GetResources();

                configuration.IsNewConfiguration = true;
                mapping = SlkSPSiteMapping.CreateMapping(spSiteGuid);
                // the mapping doesn't exist -- set "out" parameters to default values
                SPWebService adminWebService = SlkAdministration.GetAdminWebService();
                configuration.DatabaseServer       = adminWebService.DefaultDatabaseInstance.Server.Address;
                configuration.DatabaseName         = adminResources.DefaultSlkDatabaseName;
                mapping.DatabaseServer             = configuration.DatabaseServer;
                mapping.DatabaseName               = configuration.DatabaseName;
                configuration.InstructorPermission = siteCulture.Resources.DefaultSlkInstructorPermissionName;
                configuration.LearnerPermission    = siteCulture.Resources.DefaultSlkLearnerPermissionName;
                configuration.ObserverPermission   = siteCulture.Resources.DefaultSlkObserverPermissionName;
            }

            // set "out" parameters that need to be computed
            bool createDatabaseResult = false;

            SlkUtilities.ImpersonateAppPool(delegate()
            {
                createDatabaseResult = !DatabaseExists(mapping.DatabaseServerConnectionString, mapping.DatabaseName);
            });
            configuration.CreateDatabase = createDatabaseResult;

            return(configuration);
        }
        /// <summary>
        /// Retrieves the SPSite-to-LearningStore mapping represented by a given SPSite GUID.  If no
        /// such mapping exists, a new mapping object is created -- in that case, the caller should
        /// set the properties of the <c>SlkSPSiteMapping</c> object to their correct values and then
        /// call <c>Update</c> to store the mapping into the SharePoint configuration database.
        /// </summary>
        /// <param name="spSiteGuid">The GUID of the SPSite to retrieve a mapping for.</param>
        /// <returns>
        /// <c>true</c> if an existing mapping was found; <c>false</c> if a new mapping is created.
        /// In the latter case, the new mapping is not stored in the SharePoint configuration
        /// database until <c>Update</c> is called.
        /// </returns>
        ///
        public static SlkSPSiteMapping GetMapping(Guid spSiteGuid)
        {
            SlkSPSiteMappingCollection mappingCollection = GetMappingInfo();

            // set <mapping> to the SlkSPSiteMapping corresponding to <spSiteGuid>
            string           persistedObjectName = String.Format(CultureInfo.InvariantCulture, PersistedObjectNameFormat, spSiteGuid);
            SlkSPSiteMapping mapping             = mappingCollection.GetValue <SlkSPSiteMapping>(persistedObjectName);

            return(mapping);
        }
        /// <summary>
        /// Saves SLK configuration information.  This method accepts information in a form that's
        /// compatible with Configure.aspx form fields.
        /// </summary>
        ///
        /// <param name="spSiteGuid">The GUID of the SPSite being configured.</param>
        ///
        /// <param name="databaseServer">The name of the database server to associate with the
        ///     specified SPSite.  By default, integrated authentication is used to connect to the
        ///     database; to use a SQL Server user ID and password instead, append the appropriate
        ///     connection string information to the database server name -- for example, instead of
        ///     "MyServer", use "MyServer;user id=myacct;password=mypassword".  For security reasons,
        ///     integrated authentication is strongly recommended.</param>
        ///
        /// <param name="databaseName">The name of the database to associate with the specified
        ///     SPSite.  This database must exist if <paramref name="schemaToCreateDatabase"/> is
        ///     <c>null</c>, and must not exist if <paramref name="schemaToCreateDatabase"/> is
        ///     non-<c>null</c>, otherwise an error message is returned.</param>
        ///
        /// <param name="schemaToCreateDatabase">If non-<c>null</c>, this is the SlkSchema.sql file
        ///     containing the schema of the database, and an SLK database named
        ///     <paramref name="databaseName"/> is created using this schema.  If <c>null</c>,
        ///     <paramref name="databaseName"/> specifies an existing database.</param>
        ///
        /// <param name="instructorPermission">The name of the SharePoint permission that
        ///     identifies instructors.</param>
        ///
        /// <param name="learnerPermission">The name of the SharePoint permission that
        ///     identifies learners.</param>
        ///
        /// <param name="observerPermission">The name of the SharePoint permission that
        ///     identifies observers.</param>
        ///
        /// <param name="createPermissions">If <c>true</c>, the permissions specified by
        ///     <paramref name="instructorPermission"/> and <paramref name="learnerPermission"/>
        ///     are added to the root SPWeb of the specified SPSite (if they don't already
        ///     exist).</param>
        ///
        /// <param name="settingsFileContents">If not <c>null</c>, this is the contents of a SLK
        ///     Settings file to associate with this SPSite.  If <c>null</c>, the previous SLK
        ///     Settings file is used if one exists, or the default SLK settings file is used if a
        ///     database is being created.</param>
        ///
        /// <param name="defaultSettingsFileContents">The contents of the default SLK Settings file.
        ///     Must not be <n>null</n>.</param>
        ///
        /// <param name="appPoolAccountName">The name of the application pool account; for example,
        ///     "NT AUTHORITY\NETWORK SERVICE".  If <n>null</n>, then the current Windows identity is
        ///     used, or, if the current identity is impersonated, the original Windows identity is
        ///     used.</param>
        ///
        /// <remarks>
        /// This method is static so it can used outside the context of IIS.  Only SharePoint
        /// administrators can perform this function.
        /// </remarks>
        ///
        /// <exception cref="SafeToDisplayException">
        /// An error occurred that can be displayed to a browser user.
        /// </exception>
        ///

        public static void SaveConfiguration(Guid spSiteGuid, string databaseServer,
                                             string databaseName, string schemaToCreateDatabase, string instructorPermission,
                                             string learnerPermission, string observerPermission, bool createPermissions, string settingsFileContents,
                                             string defaultSettingsFileContents, string appPoolAccountName)
        {
            CheckParameters(databaseServer, databaseName, instructorPermission, learnerPermission, observerPermission, defaultSettingsFileContents);
            // only SharePoint administrators can perform this action
            CheckPermissions();

            // set <mapping> to the mapping between <spSiteGuid> and the LearningStore connection information for that SPSite
            SlkSPSiteMapping mapping = SlkSPSiteMapping.GetMapping(spSiteGuid);

            if (mapping == null)
            {
                mapping = SlkSPSiteMapping.CreateMapping(spSiteGuid);
            }

            mapping.DatabaseServer       = databaseServer;
            mapping.DatabaseName         = databaseName;
            mapping.InstructorPermission = instructorPermission;
            mapping.LearnerPermission    = learnerPermission;
            mapping.ObserverPermission   = observerPermission;

            if (mapping.IsDirty)
            {
                mapping.Update();
            }

            // create the database if specified
            if (schemaToCreateDatabase != null)
            {
                CreateDatabase(mapping, databaseName, appPoolAccountName, schemaToCreateDatabase);
            }

            // create permissions if specified
            if (createPermissions)
            {
                SlkCulture culture = LoadCulture(spSiteGuid);

                // create the permissions if they don't exist yet
                CreatePermission(spSiteGuid, instructorPermission, culture.Resources.SlkInstructorPermissionDescription, 0);
                CreatePermission(spSiteGuid, learnerPermission, culture.Resources.SlkLearnerPermissionDescription, 0);
                CreatePermission(spSiteGuid, observerPermission, culture.Resources.SlkObserverPermissionDescription, 0);
            }

            UpdateSlkSettings(mapping.DatabaseConnectionString, spSiteGuid, settingsFileContents, defaultSettingsFileContents);
        }
        /// <summary>
        /// Returns the SPSite-to-LearningStore mapping represented by a given SPSite GUID.  If no
        /// such mapping exists, an exception is thrown.
        /// </summary>
        ///
        /// <param name="site">The SPSite to retrieve a mapping for.</param>
        ///
        /// <exception cref="SlkNotConfiguredException">
        /// SLK is not configured for SharePoint site collection.
        /// (This configuration is performed in SharePoint Central Administration.)
        /// </exception>
        ///
        public static SlkSPSiteMapping GetRequiredMapping(SPSite site)
        {
            SlkSPSiteMapping mapping = GetMapping(site.ID);

            if (mapping == null)
            {
                mapping = GetMapping(site.WebApplication.Id);
            }

            if (mapping == null)
            {
                throw new SlkNotConfiguredException(SlkCulture.GetResources().SlkNotEnabled);
            }
            else
            {
                return(mapping);
            }
        }
        private static SlkSettings LoadSettings(SlkSPSiteMapping mapping, SPSite site, XmlSchema xmlSchema)
        {
            // create a LearningStore. Read is in privileged scope so irrelevant what key is.
            // Cannot use current user as may be be called in a page PreInit event when it's not necessarily valid
            string        learningStoreKey = "SHAREPOINT\\System";
            LearningStore learningStore    = new LearningStore(mapping.DatabaseConnectionString, learningStoreKey, ImpersonationBehavior.UseOriginalIdentity);

            // read the SLK Settings file from the database into <settings>
            SlkSettings settings;

            using (LearningStorePrivilegedScope privilegedScope = new LearningStorePrivilegedScope())
            {
                LearningStoreJob   job   = learningStore.CreateJob();
                LearningStoreQuery query = learningStore.CreateQuery(Schema.SiteSettingsItem.ItemTypeName);
                query.AddColumn(Schema.SiteSettingsItem.SettingsXml);
                query.AddColumn(Schema.SiteSettingsItem.SettingsXmlLastModified);
                query.AddCondition(Schema.SiteSettingsItem.SiteGuid, LearningStoreConditionOperator.Equal, mapping.SPSiteGuid);
                job.PerformQuery(query);
                DataRowCollection dataRows = job.Execute <DataTable>().Rows;
                if (dataRows.Count != 1)
                {
                    throw new SafeToDisplayException(SlkCulture.GetResources().SlkSettingsNotFound, site.Url);
                }
                DataRow  dataRow                 = dataRows[0];
                string   settingsXml             = (string)dataRow[0];
                DateTime settingsXmlLastModified = ((DateTime)dataRow[1]);
                using (StringReader stringReader = new StringReader(settingsXml))
                {
                    XmlReaderSettings xmlSettings = new XmlReaderSettings();
                    xmlSettings.Schemas.Add(xmlSchema);
                    xmlSettings.ValidationType = ValidationType.Schema;
                    using (XmlReader xmlReader = XmlReader.Create(stringReader, xmlSettings))
                    {
                        settings = new SlkSettings(xmlReader, settingsXmlLastModified);
                    }
                }
            }

            return(settings);
        }
        /// <summary>Get the anonymous store.</summary>
        /// <param name="site">The site to get the settings for.</param>
        /// <returns></returns>
        public static AnonymousSlkStore GetStore(SPSite site)
        {
            Guid siteId = site.ID;
            // set <httpContext> to the current HttpContext (null if none)
            HttpContext httpContext = HttpContext.Current;

            // if an AnonymousSlkStore corresponding to <spSiteGuid> is cached, retrieve it, otherwise
            // create one
            string            cacheItemName = null;
            AnonymousSlkStore anonymousSlkStore;

            if (httpContext != null)
            {
                cacheItemName     = String.Format(CultureInfo.InvariantCulture, "SlkStore_{0}", siteId);
                anonymousSlkStore = (AnonymousSlkStore)httpContext.Cache.Get(cacheItemName);
                if (anonymousSlkStore != null)
                {
                    return(anonymousSlkStore);
                }
            }

            // set <mapping> to the SlkSPSiteMapping corresponding to <siteId>; if no such
            // mapping, exists, a SafeToDisplayException is thrown
            SlkSPSiteMapping mapping = SlkSPSiteMapping.GetRequiredMapping(site);

            // load "SlkSettings.xsd" from a resource into <xmlSchema>
            XmlSchema xmlSchema;

            using (StringReader schemaStringReader = new StringReader(SlkCulture.GetDefaultResources().SlkSettingsSchema))
            {
                xmlSchema = XmlSchema.Read(schemaStringReader,
                                           delegate(object sender2, ValidationEventArgs e2)
                {
                    // ignore warnings (already displayed when SLK Settings file was uploaded)
                });
            }

            SlkSettings settings = null;

            try
            {
                settings = LoadSettings(mapping, site, xmlSchema);
            }
            catch (SqlException)
            {
                // Try again in case temporary error
                try
                {
                    settings = LoadSettings(mapping, site, xmlSchema);
                }
                catch (SqlException e)
                {
                    SlkCulture culture = new SlkCulture(CultureInfo.InvariantCulture);
                    SlkStore.LogError(culture.Resources.SlkSettingsSqlErrorLoad + " {0}", culture, e);
                    throw new SafeToDisplayException(culture.Resources.SlkSettingsSqlErrorLoad);
                }
            }

            // create and (if possible) cache the new AnonymousSlkStore object
            anonymousSlkStore = new AnonymousSlkStore(siteId, mapping, settings);
            DateTime cacheExpirationTime = DateTime.Now.AddSeconds(HttpContextCacheTime);

            if (httpContext != null)
            {
                httpContext.Cache.Add(cacheItemName, anonymousSlkStore, null, cacheExpirationTime,
                                      System.Web.Caching.Cache.NoSlidingExpiration,
                                      System.Web.Caching.CacheItemPriority.Normal, null);
            }

            return(anonymousSlkStore);
        }
        ///////////////////////////////////////////////////////////////////////////////////////////////
        // Public Methods
        //

        /// <summary>
        /// Initializes an instance of this class.
        /// </summary>
        ///
        /// <param name="spSiteGuid">The value to use to initialize the <c>SPSiteGuid</c> property.
        ///     </param>
        ///
        /// <param name="mapping">The value to use to initialize the <c>Mapping</c> property.
        ///     </param>
        ///
        /// <param name="settings">The value to use to initialize the <c>Settings</c> property.
        ///     </param>
        ///
        public AnonymousSlkStore(Guid spSiteGuid, SlkSPSiteMapping mapping, SlkSettings settings)
        {
            m_spSiteGuid = spSiteGuid;
            m_mapping    = mapping;
            m_settings   = settings;
        }