void UpdateCachedDropBox() { StringBuilder errors = new StringBuilder(); dropBoxManager = new DropBoxManager(properties); foreach (DropBoxUpdate update in cachedDropBoxUpdates) { try { UpdateDropBoxPermissionsNow(update.State, update.User); } catch (Exception e) { properties.Store.LogException(e); errors.AppendFormat(SlkCulture.GetResources().ErrorSavingDropBoxPermissions, update.State, update.User.LoginName); } } if (errors.Length > 0) { throw new SafeToDisplayException(errors.ToString()); } dropBoxManager = null; }
void CheckUserIsLearner() { if (Assignment.Store.CurrentUserId != LearnerId) { throw new SafeToDisplayException(SlkCulture.GetResources().SubmitAssignmentNotLearner); } }
/// <summary>Saves the assignment.</summary> /// <remarks> /// <para> /// When creating a self-assigned assignment, take care to ensure that /// <r>AssignmentProperties.AutoReturn</r> is <n>true</n>, otherwise the learner assignments /// will never reach /// <a href="Microsoft.SharePointLearningKit.LearnerAssignmentState.Enumeration.htm">LearnerAssignmentState.Final</a> /// state. /// </para> /// <para> /// <b>Security:</b>  If <pr>slkRole</pr> is /// <a href="Microsoft.SharePointLearningKit.SlkRole.Enumeration.htm">SlkRole.Instructor</a>, /// this operation fails if the <a href="SlkApi.htm#AccessingSlkStore">current user</a> doesn't /// have SLK /// <a href="Microsoft.SharePointLearningKit.SlkSPSiteMapping.InstructorPermission.Property.htm">instructor</a> /// permissions on <pr>destinationSPWeb</pr>. Also fails if the current user doesn't have access to the /// package/file. /// </para> /// </remarks> /// <param name="web">The <c>SPWeb</c> to create the assignment in.</param> /// <param name="slkRole">The <c>SlkRole</c> to use when creating the assignment. Use /// <c>SlkRole.Learner</c> to create a self-assigned assignment, i.e. an assignment with /// no instructors for which the current learner is the only learner. Otherwise, use /// <c>SlkRole.Instructor</c>.</param> public void Save(SPWeb web, SlkRole slkRole) { // Verify that the web is in the site if (web.Site.ID != Store.SPSiteGuid) { throw new InvalidOperationException(SlkCulture.GetResources().SPWebDoesNotMatchSlkSPSite); } if (Id == null) { SaveNewAssignment(web, slkRole); } else { UpdateAssignment(web); } if (customPropertiesItem != null) { customPropertiesItem["Title"] = Id.GetKey().ToString(); foreach (AssignmentProperty property in Properties) { customPropertiesItem[property.Name] = property.Value; } customPropertiesItem.ParentList.ParentWeb.AllowUnsafeUpdates = true; customPropertiesItem.Update(); } }
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); }); }
/// <summary> /// Returns an <c>AssignmentProperties</c> object populated with default information for /// a new assignment based on a given e-learning package or non-e-learning document. /// This method doesn't actually create the assignment -- it just returns information that /// can be used as defaults for a form that a user would fill in to create a new assignment. /// </summary> /// <remarks> /// <para> /// If <paramref name="slkRole"/> is <c>SlkRole.Learner</c>, default properties for a /// self-assigned assignment are returned. In this case, the returned /// <c>AssignmentProperties</c> will contain no users in /// <c>AssignmentProperties.Instructors</c>, and <c>AssignmentProperties.Learners</c> will /// contain only the current user. /// </para> /// <para> /// <b>Security:</b>  If <pr>slkRole</pr> is /// <a href="Microsoft.SharePointLearningKit.SlkRole.Enumeration.htm">SlkRole.Instructor</a>, /// this operation fails if the <a href="SlkApi.htm#AccessingSlkStore">current user</a> doesn't /// have SLK /// <a href="Microsoft.SharePointLearningKit.SlkSPSiteMapping.InstructorPermission.Property.htm">instructor</a> /// permissions on <pr>destinationSPWeb</pr>. Also fails if the current user doesn't have access to the /// package/file. /// </para> /// </remarks> /// <param name="store"></param> /// <param name="destinationSPWeb">The <c>SPWeb</c> that the assignment would be assigned in.</param> /// <param name="slkRole">The <c>SlkRole</c> for which information is to be retrieved. /// Use <c>SlkRole.Learner</c> to get default information for a self-assigned assignment, /// i.e. an assignment with no instructors for which the current learner is the only /// learner. Otherwise, use <c>SlkRole.Instructor</c>.</param> /// <returns></returns> public static AssignmentProperties CreateNewAssignmentObject(ISlkStore store, SPWeb destinationSPWeb, SlkRole slkRole) { // Security checks: Fails if the user isn't an instructor on the web if SlkRole=Instructor // (verified by EnsureInstructor). Fails if the user doesn't have access to the // package (verified by calling RegisterPackage or by accessing // the properties of the non-elearning file). // Check parameters if (destinationSPWeb == null) { throw new ArgumentNullException("destinationSPWeb"); } // Verify that the web is in the site if (destinationSPWeb.Site.ID != store.SPSiteGuid) { throw new InvalidOperationException(SlkCulture.GetResources().SPWebDoesNotMatchSlkSPSite); } UserItemIdentifier currentUserId = store.CurrentUserId; AssignmentProperties assignment = new AssignmentProperties(null, store); assignment.StartDate = DateTime.Today; // midnight today assignment.DueDate = null; assignment.EmailChanges = store.Settings.EmailSettings.DefaultEmailingOn; assignment.CreatedById = currentUserId; store.AddCustomProperties(assignment, destinationSPWeb); // Role checking and determine if self assigned bool isSelfAssigned; if (slkRole == SlkRole.Instructor) { store.EnsureInstructor(destinationSPWeb); isSelfAssigned = false; } else if (slkRole == SlkRole.Learner) { isSelfAssigned = true; } else { throw new ArgumentException(SlkCulture.GetResources().InvalidSlkRole, "slkRole"); } assignment.ShowAnswersToLearners = isSelfAssigned; assignment.AutoReturn = isSelfAssigned; if (isSelfAssigned) { assignment.Learners.Add(new SlkUser(currentUserId, destinationSPWeb.CurrentUser)); } else { assignment.Instructors.Add(new SlkUser(currentUserId, destinationSPWeb.CurrentUser)); } return(assignment); }
/// <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>Throws an exception if this computer isn't part of a SharePoint farm, or the caller doesn't /// have the necessary permissions to access instances of this class.</summary> static internal void CheckPermissions() { SPFarm farm = SPFarm.Local; if (farm == null) { throw new InvalidOperationException(SlkCulture.GetResources().SharePointFarmNotFound); } else if (!farm.CurrentUserIsAdministrator()) { throw new SafeToDisplayException(SlkCulture.GetResources().NotSharePointAdmin); } }
void CheckUserIsInstructor() { UserItemIdentifier current = Assignment.Store.CurrentUserId; foreach (SlkUser instructor in Assignment.Instructors) { if (instructor.UserId == current) { return; } } throw new SafeToDisplayException(SlkCulture.GetResources().ChangeLearnerAssignmentNotInstructor); }
/// <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); } }
void VerifyIsValidSelfAssigned() { // set <currentUserId> to the UserItemIdentifier of the current user; note that this // requires a round trip to the database UserItemIdentifier currentUserId = Store.CurrentUserId; // verify that <properties> specify no instructors and that the current user is the // only learner if (Instructors.Count != 0) { throw new UnauthorizedAccessException(SlkCulture.GetResources().InvalidSelfAssignment); } if ((Learners.Count != 1) || (Learners[0].UserId != currentUserId)) { throw new UnauthorizedAccessException(SlkCulture.GetResources().InvalidSelfAssignment); } }
void SaveNewAssignment(SPWeb web, SlkRole slkRole) { // Security checks: If assigning as an instructor, fails if user isn't an instructor on // the web (implemented by calling EnsureInstructor). Fails if the user doesn't have access to the package/file if (web == null) { throw new ArgumentNullException("web"); } if (PackageFormat == null && Location == null) { throw new InvalidOperationException(SlkCulture.GetResources().InvalidNewAssignment); } SPSiteGuid = web.Site.ID; SPWebGuid = web.ID; VerifyRole(web, slkRole); Id = Store.CreateAssignment(this); if (isSelfAssigned == false) { //Update the MRU list Store.AddToUserWebList(web); } if (IsNonELearning) { DropBoxManager dropBoxMgr = new DropBoxManager(this); Microsoft.SharePoint.Utilities.SPUtility.ValidateFormDigest(); dropBoxMgr.CreateAssignmentFolder(); } if (EmailChanges) { using (AssignmentEmailer emailer = new AssignmentEmailer(this, Store.Settings.EmailSettings, web)) { emailer.SendNewEmail(Learners); } } }
/// <summary>Makes the assignment be a no package assignemnt.</summary> public void MakeNoPackageAssignment(string title) { Location = Package.NoPackageLocation.ToString(); if (String.IsNullOrEmpty(Title)) { if (string.IsNullOrEmpty(title)) { Title = SlkCulture.GetResources().NoPackageTitle; } else { Title = title; } } if (Description == null) { Description = String.Empty; } return; }
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); }
////////////////////////////////////////////////////////////////////////////////////////////// // Internal Methods // /// <summary> /// Initializes an instance of this class. /// </summary> /// /// <param name="viewColumnName">The value to use for the <c>ViewColumnName</c> property. /// </param> /// /// <param name="oper">The value to use for the <c>Operator</c> property. Note that /// if this value is "IsNull" or "IsNotNull" then /// <c>LearningStoreConditionOperator.Equal</c> or /// <c>LearningStoreConditionOperator.NotEqual</c>, respectively, is used for the /// <c>Operator</c> property; in this case <c>null</c> should be used for /// <paramref name="value"/>.</param> /// /// <param name="value">The value to use for the <c>Value</c> property.</param> /// /// <param name="macroName">The value to use for the <c>MacroName</c> property.</param> /// /// <param name="noConditionOnNull">The value to use for the <c>NoConditionOnNull</c> property. /// </param> /// /// <param name="lineNumber">The line number of the "<Condition>" element with the /// XML file.</param> /// /// <remarks> /// Note that one of <paramref name="value"/> and <paramref name="macroName"/> must be /// non-null unless <paramref name="oper"/> equals "IsNull" or "IsNotNull". /// </remarks> /// internal ConditionDefinition(string viewColumnName, string oper, string value, string macroName, bool noConditionOnNull, int lineNumber) { // store state m_viewColumnName = viewColumnName; switch (oper) { case "Equal": m_operator = LearningStoreConditionOperator.Equal; break; case "GreaterThan": m_operator = LearningStoreConditionOperator.GreaterThan; break; case "GreaterThanEqual": m_operator = LearningStoreConditionOperator.GreaterThanEqual; break; case "LessThan": m_operator = LearningStoreConditionOperator.LessThan; break; case "LessThanEqual": m_operator = LearningStoreConditionOperator.LessThanEqual; break; case "NotEqual": m_operator = LearningStoreConditionOperator.NotEqual; break; case "IsNull": m_operator = LearningStoreConditionOperator.Equal; if ((value != null) || (macroName != null)) { throw new ArgumentException(SlkCulture.GetResources().SlkUtilitiesValueNullifIsNull, "operator"); } break; case "IsNotNull": m_operator = LearningStoreConditionOperator.NotEqual; if ((value != null) || (macroName != null)) { throw new ArgumentException(SlkCulture.GetResources().SlkUtilitiesValueNullifIsNotNull, "operator"); } break; } m_value = value; if (string.IsNullOrEmpty(macroName) == false) { MacroResolver.ValidateMacro(macroName); } m_macroName = macroName; m_noConditionOnNull = noConditionOnNull; m_lineNumber = lineNumber; // only one of <value> and <macroName> may be provided if ((value != null) && (macroName != null)) { throw new ArgumentException(SlkCulture.GetResources().SlkUtilitiesOneValueNonNull, "value"); } // if <noConditionOnNull> is true, <macroName> must be provided if (noConditionOnNull && (macroName == null)) { throw new ArgumentException(SlkCulture.GetResources().SlkUtilitiesMacroNameNotProvided, "noConditionOnNull"); } }
/// <summary> /// Initializes an instance of this class. /// </summary> /// /// <param name="internalErrorCode">An internal error code, e.g. "APP1001".</param> /// internal InternalErrorException(string internalErrorCode) : base(String.Format(SlkCulture.GetCulture(), SlkCulture.GetResources().InternalError, internalErrorCode)) { }
/// <summary> /// Initializes an instance of this class, by formatting an error message and prepending /// the line number within the XML file. /// </summary> /// /// <param name="lineNumber">The line number (within the XML file) to include in the /// exception message.</param> /// /// <param name="format">A <c>String.Format</c>-style format string.</param> /// /// <param name="args">Formatting arguments.</param> /// internal SlkSettingsException(int lineNumber, string format, params object[] args) : base(String.Format(SlkCulture.GetCulture(), SlkCulture.GetResources().SlkUtilitiesSettingsException, lineNumber, String.Format(SlkCulture.GetCulture(), format, args))) { }
/// <summary> /// Initializes an instance of this class, by formatting an error message and prepending /// the line number within the XML file. /// </summary> /// /// <param name="xmlReader">The line number of the exception message will include the /// current line number of this <c>XmlReader</c>.</param> /// /// <param name="format">A <c>String.Format</c>-style format string.</param> /// /// <param name="args">Formatting arguments.</param> /// internal SlkSettingsException(XmlReader xmlReader, string format, params object[] args) : base(String.Format(SlkCulture.GetCulture(), SlkCulture.GetResources().SlkUtilitiesSettingsException, ((IXmlLineInfo)xmlReader).LineNumber, String.Format(SlkCulture.GetCulture(), format, args))) { }
/// <summary>Sets the location of the package.</summary> /// <remarks>Security checks:Fails if the user doesn't have access to the package/file</remarks> /// <param name="location">The MLC SharePoint location string that refers to the e-learning /// package or non-e-learning document to assign. Use /// <c>SharePointPackageStore.GetLocation</c> to construct this string.</param> /// <param name="organizationIndex">The zero-based index of the organization within the /// e-learning content to assign; this is the value that's used as an index to /// <c>ManifestReader.Organizations</c>. If the content being assigned is a non-e-learning /// document, use <c>null</c> for <paramref name="organizationIndex"/>.</param> /// <param name="title">Any title that has been passed in.</param> public void SetLocation(SharePointFileLocation location, Nullable <int> organizationIndex, string title) { if (location == null) { throw new ArgumentNullException("location"); } if (location.ToString() == Package.NoPackageLocation.ToString()) { MakeNoPackageAssignment(title); return; } // Access the properties of the file to verify that the user has access to the file SPFile file = location.LoadFile(); System.Collections.Hashtable fileProperties = file.Properties; // set <rootActivityId> to the ID of the organization, or null if a non-e-learning document is being assigned if (organizationIndex != null) { using (Package package = new Package(Store, file, location)) { package.Register(); RootActivityId = package.FindRootActivity(organizationIndex.Value); bool existingTitle = (string.IsNullOrEmpty(Title) == false); if (existingTitle == false) { Title = package.Title; } if (string.IsNullOrEmpty(Description)) { Description = package.Description; } // validate <organizationIndex> if ((organizationIndex.Value < 0) || (organizationIndex.Value >= package.Organizations.Count)) { throw new SafeToDisplayException(SlkCulture.GetResources().InvalidOrganizationIndex); } PackageFormat = package.PackageFormat; // set <organizationNodeReader> to refer to the organization OrganizationNodeReader organizationNodeReader = package.Organizations[organizationIndex.Value]; // if there is more than one organization, append the organization title, if any if (existingTitle == false && package.Organizations.Count > 1) { if (!String.IsNullOrEmpty(organizationNodeReader.Title)) { SlkCulture culture = new SlkCulture(); Title = culture.Format(culture.Resources.SlkPackageAndOrganizationTitle, Title, organizationNodeReader.Title); } } // set <pointsPossible> to the points-possible value stored in the manifest, or null if none switch (PackageFormat) { case Microsoft.LearningComponents.PackageFormat.Lrm: PointsPossible = organizationNodeReader.PointsPossible; break; case Microsoft.LearningComponents.PackageFormat.V1p3: PointsPossible = 100; break; default: PointsPossible = null; break; } } } else // Non-elearning content { RootActivityId = null; Location = location.ToString(); if (string.IsNullOrEmpty(Title)) { Title = file.Title; if (String.IsNullOrEmpty(Title)) { Title = System.IO.Path.GetFileNameWithoutExtension(file.Name); } } if (string.IsNullOrEmpty(Description)) { Description = string.Empty; } if (PointsPossible == null) { PointsPossible = null; // "Points Possible" defaults to null for non-e-learning content PackageWarnings = null; // no package warnings PackageFormat = null; // non-e-learning package } } }