Реализация решения для классификации сайтов SharePoint

Примечание.

Информацию о классификации сайта SharePoint Online см. в статье «Современная» классификация сайтов SharePoint.

Даже при грамотном управлении сайты SharePoint могут чрезмерно увеличиваться в размерах и выходить из-под контроля. Сайты создаются по мере необходимости, но редко удаляются. Обход контента при поиске затрудняют неиспользуемые семейства веб-сайтов, а поиск выдает устаревшие и нерелевантные результаты. Классификация сайта позволяет находить и сохранять важные данных.

В данной статье описано использование примера Core.SiteClassification для развертывания решения для классификации, а также использование политики сайтов SharePoint для принудительного удаления. Вы можете интегрировать это решение в существующее решение для подготовки сайта для более эффективного управления вашими веб-сайтами.

Перед началом работы

Чтобы приступить к работе, скачайте пример Core.SiteClassification из проекта «Шаблоны и методики разработки для Office 365» на портале GitHub.

Примечание.

Код, приведенный в этой статье, предоставляется "как есть" без какой-либо явной или подразумеваемой гарантии, включая подразумеваемые гарантии пригодности для какой-либо цели, для продажи или гарантии отсутствия нарушения прав иных правообладателей.

Определение и настройка политик для сайта

Первоначально вам нужно определить и настроить политики для сайта, которые будут доступны для всех ваших коллекций сайтов. Пример Core.SiteClassification относится к SharePoint Online MT, но его также можно использовать в SharePoint Online (выделенная среда) или на локальном сервере SharePoint. Политики сайтов настраиваются в Центре типов контента, который в SharePoint Online MT находится в https://[tenantname]/sites/contentTypeHub.

Чтобы настроить политики сайтов, перейдите в Параметры>Администрирование семейства веб-сайтов>Политики сайта>Создание. Откроется страница Новая политика сайта. Дополнительные сведения о политике веб-сайта см. в статье Обзор политик сайта в SharePoint Server.

На странице Новая политика сайта введите следующие сведения в полях:

  • Имя: HBI

  • Описание: Это суперсекретная информация.

  • Установите переключатель Удалять сайты автоматически.

  • Для Событие удаления: используйте Дата создания + 1 год.

  • Выберите Отправлять уведомление по электронной почте владельцам веб-сайтов заблаговременно до удаления: поставьте флажок и назначьте значение 1 месяц.

  • Выберите Отправлять контрольные уведомления каждый: поставьте флажок и задайте значение 14 дней.

  • Выберите Владельцы сайтов могут отложить предстоящих удаление на: поставьте флажок и задайте значение 1 месяц.

  • Установите флажок После закрытия семейство сайтов будет доступно только для чтения.

Повторите эти действия еще два раза для названий MBI и LBI. Используйте различные параметры для политик удаления или хранения. Когда все будет готово, вы можете публиковать новые политики.

Вставка настраиваемого действия

Вы можете вставить настраиваемое действие для классификации сайтов на страницу Параметры и значок шестеренки SharePoint. Данное действие доступно только для пользователей, имеющих разрешение ManageWeb. Дополнительные сведения см. в статье Расположения и идентификаторы дополнительных действий по умолчанию.

/// <summary>
/// Adds a custom Action to a Site Collection.
/// </summary>
/// <param name="ctx">The Authenticated client context.</param>
/// <param name="hostUrl">The provider-hosted URL for the application</param>

static void AddCustomAction(ClientContext ctx, string hostUrl)
{
    var _web = ctx.Web;
    ctx.Load(_web);
    ctx.ExecuteQuery();

    // You only want the action to show up if you have manage web permissions.
    BasePermissions _manageWebPermission = new BasePermissions();
    _manageWebPermission.Set(PermissionKind.ManageWeb);

    CustomActionEntity _entity = new CustomActionEntity()
    {
        Group = "SiteTasks",
        Location = "Microsoft.SharePoint.SiteSettings",
        Title = "Site Classification",
        Sequence = 1000,
        Url = string.Format(hostUrl, ctx.Url),
        Rights = _manageWebPermission,
    };

    CustomActionEntity _siteActionSC = new CustomActionEntity()
    {
        Group = "SiteActions",
        Location = "Microsoft.SharePoint.StandardMenu",
        Title = "Site Classification",
        Sequence = 1000,
        Url = string.Format(hostUrl, ctx.Url),
        Rights = _manageWebPermission
    };
    _web.AddCustomAction(_entity);
    _web.AddCustomAction(_siteActionSC);
}

Настраиваемая классификация сайтов

Вы можете использовать страницу Изменение сведений о сайте, чтобы задать следующие параметры конкретной классификации:

  • Аудитория: выберите корпорация, организация, или группа.

  • Классификация безопасности: выберите одну из категорий классификации, которые вы ввели, например, LBI.

  • Дата окончания срока действия: переопределите установленную по умолчанию дату окончания срока действия, которая рассчитывается на основании введенной ранее классификации.

Опции Диапазон аудитории и Классификация сайта доступны для поиска и будут иметь управляемые свойства, связанные с ними, когда будет выполнен обход. Вы можете использовать эти свойства для поиска определенных типов сайтов с помощью настраиваемого скрытого списка внутри семейства веб-сайтов. Этот список реализован в проекте Core.SiteClassification.Common класса SiteManagerImpl.

private void CreateSiteClassificationList(ClientContext ctx)
{
  var _newList = new ListCreationInformation()
    {
    Title = SiteClassificationList.SiteClassificationListTitle,
    Description = SiteClassificationList.SiteClassificationDesc,
    TemplateType = (int)ListTemplateType.GenericList,
    Url = SiteClassificationList.SiteClassificationUrl,
    QuickLaunchOption = QuickLaunchOptions.Off
    };

  if(!ctx.Web.ContentTypeExistsById(SiteClassificationContentType.SITEINFORMATION_CT_ID))
    {
    // Content type.
    ContentType _contentType = ctx.Web.CreateContentType(SiteClassificationContentType.SITEINFORMATION_CT_NAME,
    SiteClassificationContentType.SITEINFORMATION_CT_DESC,
    SiteClassificationContentType.SITEINFORMATION_CT_ID,
    SiteClassificationContentType.SITEINFORMATION_CT_GROUP);

    FieldLink _titleFieldLink = _contentType.FieldLinks.GetById(new Guid("fa564e0f-0c70-4ab9-b863-0177e6ddd247"));
    titleFieldLink.Required = false;
    contentType.Update(false);

    // Key field.
    ctx.Web.CreateField(SiteClassificationFields.FLD_KEY_ID, 
      SiteClassificationFields.FLD_KEY_INTERNAL_NAME, 
      FieldType.Text, 
      SiteClassificationFields.FLD_KEY_DISPLAY_NAME, 
      SiteClassificationFields.FIELDS_GROUPNAME);

    // Value field.
    ctx.Web.CreateField(SiteClassificationFields.FLD_VALUE_ID, 
      SiteClassificationFields.FLD_VALUE_INTERNAL_NAME, 
      FieldType.Text, 
      SiteClassificationFields.FLD_VALUE_DISPLAY_NAME, 
      SiteClassificationFields.FIELDS_GROUPNAME);

    // Add Key field to content type.
    ctx.Web.AddFieldToContentTypeById(SiteClassificationContentType.SITEINFORMATION_CT_ID, 
      SiteClassificationFields.FLD_KEY_ID.ToString(), 
      true);

    // Add Value field to content type.
    ctx.Web.AddFieldToContentTypeById(SiteClassificationContentType.SITEINFORMATION_CT_ID,
      SiteClassificationFields.FLD_VALUE_ID.ToString(),
      true);
    }

  var _list = ctx.Web.Lists.Add(_newList);

  list.Hidden = true;
  list.ContentTypesEnabled = true;
  list.Update();
  ctx.Web.AddContentTypeToListById(SiteClassificationList.SiteClassificationListTitle,
    SiteClassificationContentType.SITEINFORMATION_CT_ID, true);
  this.CreateCustomPropertiesInList(_list);
  ctx.ExecuteQuery();
  this.RemoveFromQuickLaunch(ctx, SiteClassificationList.SiteClassificationListTitle);

}

По умолчанию при создании списка, стандартного или с помощью CSOM, список доступен в меню Последнее. Однако список должен быть скрыт. Приведенный ниже код удаляет элемент из меню Последнее.

private void RemoveFromQuickLaunch(ClientContext ctx, string listName)
  {
  Site _site = ctx.Site;
  Web _web = _site.RootWeb;

  ctx.Load(_web, x => x.Navigation, x => x.Navigation.QuickLaunch);
  ctx.ExecuteQuery();

  var _vNode = from NavigationNode _navNode in _web.Navigation.QuickLaunch
      where _navNode.Title == "Recent"
      select _navNode;

  NavigationNode _nNode = _vNode.First<NavigationNode>();
  ctx.Load(_nNode.Children);
  ctx.ExecuteQuery();
  var vcNode = from NavigationNode cn in _nNode.Children
     where cn.Title == listName
     select cn;
  NavigationNode _cNode = vcNode.First<NavigationNode>();
 _cNode.DeleteObject();
  ctx.ExecuteQuery();    
  }

Пример Core.SiteClassification предоставляет вероятность того, что администратор сайта или кто-то, обладающий разрешением, может удалить новый список. При обращении к этой странице список создается еще раз, но пример не задает исходные значения свойств. Вы можете избежать этого, увеличив пример, чтобы изменить разрешения для списка, чтобы только у администраторов семейства сайта был доступ. Кроме того, вы можете использовать PnP пример Core.SiteEnumeration, чтобы выполнять проверки списка и соответствующим образом уведомлять администраторов сайта.

Проверка списка подтверждения также реализована в классе SiteManagerImpl OneNote для в члене Initialize.

internal void Initialize(ClientContext ctx)
{
try {
       	 var _web = ctx.Web;
         var lists = _web.Lists;
         ctx.Load(_web);
         ctx.Load(lists, lc => lc.Where(l => l.Title == SiteClassificationList.SiteClassificationListTitle));
         ctx.ExecuteQuery();
                
          if (lists.Count == 0) {
                this.CreateSiteClassificationList(ctx); 
          }
      }
      catch(Exception _ex)
         {

         }
     }
}

Добавление индикатора классификации на страницу сайта

Вы можете добавить индикатор на страницу сайта, чтобы отобразить ее классификацию. В примере Core.SiteClassification показано, как изображение, показывающее классификацию, встраивается рядом с полем Название сайта. В более ранних версиях SharePoint для этого использовался контроль делегирования на сервера. Хотя вы можете использовать пользовательскую мастер-страницу с JavaScript, в этом примере используется внедренный шаблон JavaScript. Когда вы изменяете Политику сайта на странице Изменение информации о сайте, изменяется индикатор сайта, демонстрирующий небольшой прямоугольник с разными фоновыми цветами для каждого варианта классификации.

Следующий метод определяется в проекте Core.SiteClassificationWeb, скриптах и classifier.js. Эти изображения хранятся на веб-сайте Microsoft Azure. Необходимо изменить жестко прописанные URL-адреса в соответствии с вашей средой.

function setClassifier() {
    if (!classified)
    {
        var clientContext = SP.ClientContext.get_current();
        var query = "<View><Query><Where><Eq><FieldRef Name='SC_METADATA_KEY'/><Value Type='Text'>sc_BusinessImpact</Value></Eq></Where></Query><ViewFields><FieldRef Name='ID'/><FieldRef Name='SC_METADATA_KEY'/><FieldRef Name='SC_METADATA_VALUE'/></ViewFields></View>";
        var list = clientContext.get_web().get_lists().getByTitle("Site Information");
        clientContext.load(list);
        var camlQuery = new SP.CamlQuery();
        camlQuery.set_viewXml(query);
        var listItems = list.getItems(camlQuery);
        clientContext.load(listItems);

        clientContext.executeQueryAsync(Function.createDelegate(this, function (sender, args) {
            var listItemInfo;
            var listItemEnumerator = listItems.getEnumerator();

            while (listItemEnumerator.moveNext()) {
                listItemInfo = listItemEnumerator.get_current().get_item('SC_METADATA_VALUE');
                
                var pageTitle = $('#pageTitle')[0].innerHTML;
                if (pageTitle.indexOf("img") > -1) {
                    classified = true;
                }
                else {
                    var siteClassification = listItemInfo;
                    if (siteClassification == "HBI") {
                        var img = $("<a href='http://insertyourpolicy' target=_blank><img id=classifer name=classifer src='https://spmanaged.azurewebsites.net/content/img/hbi.png' title='Site contains personally identifiable information (PII), or unauthorized release of information on this site would cause severe or catastrophic loss to Contoso.' alt='Site contains personally identifiable information (PII), or unauthorized release of information on this site would cause severe or catastrophic loss to Contoso.'></a>");
                        $('#pageTitle').prepend(img);
                        classified = true;
                    }
                    else if (siteClassification == "MBI") {
                        var img = $("<a href='http://insertyourpolicy' target=_blank><img id=classifer name=classifer src='https://spmanaged.azurewebsites.net/content/img/mbi.png' title='Unauthorized release of information on this site would cause severe impact to Contoso.' alt='Unauthorized release of information on this site would cause severe impact to Contoso.'></a>");
                        $('#pageTitle').prepend(img);
                        classified = true;
                    }
                    else if (siteClassification == "LBI") {
                        var img = $("<a href='http://insertyourpolicy' target=_blank><img id=classifer name=classifer src='https://spmanaged.azurewebsites.net/content/img/lbi.png' title='Limited or no impact to Contoso if publically released.' alt='Limited or no impact to Contoso if publically released.'></a>");
                        $('#pageTitle').prepend(img);
                        classified = true;
                    }
                }
            }
        }));
    }

Альтернативный метод

Вы межете использовать метод расширения Web.AddIndexedPropertyBagKey в файле ObjectPropertyBagEntry.cs в основные OfficeDevPnP для хранения значений классификации в контейнерах свойства сайта, а не список. Метод позволяет выполнять поиск или обход контейнеров свойств.

См. также