Программирование

Главная | Другие дисциплины
small logoПРОГРАММИРОВАНИЕ

 

Уровень доступа к данным

Уровень доступа к данным используется для формирования специфичного для базы данных кода с отделением подробной информации из базы данных от уровня бизнес-логики.  Это разделение позволяет одновременно использовать различные базы данных, не требуя изменений на уровнях представления и бизнес-логики.  Для реализации уровня доступа к данным используется комплект прикладных блоков доступа к данным (Data Access Application Blocks, DAAB). 

DAAB является компонентом .NET, содержащим оптимизированный код доступа к данным для формирования команд базе данных SQL Server.  Использование DAAB уменьшает объем пользовательского кода, необходимого для создания, тестирования и обслуживания доступа к базе данных.  Запросы доступа к базе данных могут быть уменьшены до одной строки кода вместо обычных  шести или более строк.

DataSet ds = SqlHelper.ExecuteDataset(

ConfigurationSettings.AppSettings[Web.Global.CfgKeyConnString],

   CommandType.StoredProcedure, "ListAllProjects"); 

В вышеприведенном коде вызывается хранимая процедура "ListAllProjects", и набор результатов присваивается DataSet.  Этот запрос требует написания только одной строки кода.  И наоборот, написание кода без использования DAAB и непосредственно ADO.NET (System.Data) требует ввода шести строк.

   SqlConnection myConnection = new SqlConnection(

   ConfigurationSettings.AppSettings[Web.Global.CfgKeyConnString]);

 

   SqlCommand myCommand = new SqlCommand("ListAllProjects", myConnection);

   myCommand.CommandType = CommandType.StoredProcedure;

   SqlDataAdapter myDataAdapter = new SqlDataAdapter(myCommand);

   DataSet myDataSet = new DataSet();

   myDataAdapter.Fill(myDataSet);

ExecuteDataSet в сравнении с ExecuteReader

Во всем коде приложение Time Tracker использует метод ExecuteDataSet там, где обычно используется ExecuteReader.

DataReader – это прикрепленная программа чтения, обеспечивающая однонаправленный просмотр данных. Поскольку программы DataReader однонаправленны, они обеспечивают очень быстрое чтение данных.  Недостатком является то, что в DAAB метод ExecuteDataReader сильно связан с SQL Server, тогда как ExecuteDataSet – общий для всех баз данных.  Кроме того, после использования DataReader его необходимо явно закрыть.

Уровень бизнес-логики

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

Безопасность в определении данных, доступных и недоступных для просмотра пользователем, достигается путем использования уровня бизнес-логики и хранимых процедур.  Например, менеджер проекта может просматривать записи времени только тех консультантов, которые являются членами проектов, принадлежащих данному менеджеру.  Поэтому метод TimeEntry.List получает в качестве параметра UserID пользователя, выполняющего запрос.  Имя пользователя (UserName) передается в базовую хранимую процедуру через уровень доступа к данным, и только те данные, которые доступны для просмотра этому пользователю на основании его роли, возвращаются на уровень бизнес-логики.

Приложение Time Tracker использует облегченные классы для обертывания информации, возвращаемой с уровня доступа к базе данных.  Класс TimeEntry служит хорошим примером одного из классов, используемых в приложении Time Tracker.

TimeEntry

Класс TimeEntry инкапсулирует все подробности записей времени.

Открытые свойства

Имя

Тип

CategoryID

Integer

CategoryName

String

CategoryShortName

String

Day

String

Description

String

Duration

Decimal

EntryDate

Datetime

EntryLogID

Integer

ProjectID

Integer

ProjectName

String

Конструкторы

·         TimeEntry ()

·         TimeEntry (entryLogID)

·         TimeEntry (entryLogID, userName, projectID, categoryID, taskDate, description, duration)

Статические методы

·         GetEntries (userName, startDate, endDate): возвращает список всех записей времени для пользователя с указанным UserName за определенный период времени.

·         Remove (): удаляет запись времени из базы данных.

Методы

·         Load (): получает информацию о записи времени для указанной записи из базы данных, используя свойство EntryLogID.

·         Save (все свойства записи времени): добавляет или обновляет информацию о записи времени.  Если свойство EntryLogID - 0, информация добавляется как новая запись времени.  В противном случае информация обновляется.  Свойства UserName и ProjectID должны быть установлены перед вызовом Save.

Пользовательские наборы

Так как уровень представления Time Tracker строго ориентирован на список, приложение использует собственные пользовательские наборы для передачи информации между уровнем бизнес-логики и уровнем представления.  В качестве альтернативы возможно использование DataSet, DataTable, DataView или любого другого объекта, реализующего интерфейсы IEnumerable и ICollection.  Использование пользовательских наборов вместо вышеуказанных альтернативных вариантов обеспечивает несколько преимуществ:

·         Пользовательский набор более облегчен, нежели, например, DataSet.

·         Пользовательский набор обеспечивает более четкое отделение от уровня данных и уровня представления.

·         Каждый набор является объектом, специфичным для того или иного класса.

Пользовательские наборы, используемые в приложении Time Tracker, являются производными ядра ArrayList.  ArrayList настроен так, что оно может управлять сортировкой его внутренних объектов и их полей.  Ниже приведен типовой пользовательский набор, используемый в приложении Time Tracker.

 

   public class TimeEntriesCollection : ArrayList

   {

      public enum TimeEntryFields

      {

         InitValue,

         Day,

         Category,

         Project,

         Hours,

         Description

      }

 

      public void Sort(TimeEntryFields sortField, bool isAscending)

      {

         switch (sortField)

         {

            case TimeEntryFields.Day:

               base.Sort(new DayComparer());

               break;

            case TimeEntryFields.Category:

               base.Sort(new CategoryComparer());

               break;

            case TimeEntryFields.Description:

               base.Sort(new DescriptionComparer());

               break;

            case TimeEntryFields.Hours:

               base.Sort(new HoursComparer());

               break;

            case TimeEntryFields.Project:

               base.Sort(new ProjectComparer());

               break;

         }

 

         if (!isAscending) base.Reverse();

      }

 

      #region ICompare Implementations

      private sealed class DayComparer : IComparer

      {

         public int Compare(object x, object y)

         {

            Components.TimeEntry first = (Components.TimeEntry) x;

            Components.TimeEntry second = (Components.TimeEntry) y;

            return first.EntryDate.CompareTo(second.EntryDate);

         }

      }

 

      private sealed class CategoryComparer : IComparer

      {

         public int Compare(object x, object y)

         {

            Components.TimeEntry first = (Components.TimeEntry) x;

            Components.TimeEntry second = (Components.TimeEntry) y;

            return first.CategoryName.CompareTo(second.CategoryName);

         }

      }

 

      private sealed class ProjectComparer : IComparer

      {

         public int Compare(object x, object y)

         {

            Components.TimeEntry first = (Components.TimeEntry) x;

            Components.TimeEntry second = (Components.TimeEntry) y;

            return first.ProjectName.CompareTo(second.ProjectName);

         }

      }

 

      private sealed class DescriptionComparer : IComparer

      {

         public int Compare(object x, object y)

         {

            Components.TimeEntry first = (Components.TimeEntry) x;

            Components.TimeEntry second = (Components.TimeEntry) y;

            return first.Description.CompareTo(second.Description);

         }

      }

 

      private sealed class HoursComparer : IComparer

      {

         public int Compare(object x, object y)

         {

            Components.TimeEntry first = (Components.TimeEntry) x;

            Components.TimeEntry second = (Components.TimeEntry) y;

            return first.Duration.CompareTo(second.Duration);

         }

      }

      #endregion

   }

Всякий раз, когда в приложении Time Tracker необходим сбор данных, применяется пользовательский набор.

Статические методы

Кроме того, вызовы метода для возвращения пользовательских наборов объявляются как статические.  Статические методы принадлежат непосредственно типу, а не определенному объекту. Следовательно, преимущество использования статических методов заключается в том, что для вызова метода не обязательно создавать экземпляр объекта.  Например, GetProjects - статический метод в классе Project.  Вызов метода для получения списка всех проектов состоит из одной строки кода.

Projects.DataSource = Project.GetProjects();

Получение информации о пользователе

Приложение Time Tracker интегрируется с существующей сетью компании путем получения информации по учетной записи пользователя либо из NT SAM, либо из Active Directory.  При первом посещении пользователем сайта Time Tracker информация о его роли извлекается из базы данных TimeTracker.  Класс DirectoryHelper используется для получения имени и фамилии пользователя из указанного источника учетной записи пользователя, сконфигурированного в файле web.config.  Если пользователь не найден, то в качестве имени применяется ID пользователя.

Класс DirectoryHelper можно легко расширить с целью получения дополнительной информации о пользователе из NT SAM или Active Directory.

//*********************************************************************

//

// Поиск корневого каталога

//

//*********************************************************************

public static bool FindUser(string identification, ref string FirstName, ref string LastName)

{

   bool result = false;

 

   // Определение метода получения информации о пользователе

   // WindowsSAM

   if (ConfigurationSettings.AppSettings[Web.Global.CfgKeyUserAcctSource] == "WindowsSAM")

   {

      // Извлечение имени машины или домена и имени пользователя из

      // строки идентификации

      string [] samPath = identification.Split(new char[] {'\\'});

      _path = _windowsSAMPath + samPath[0];

 

      try

      {

         // Нахождение пользователя

         DirectoryEntry entryRoot = new DirectoryEntry(_path);

         DirectoryEntry userEntry = entryRoot.Children.Find(samPath[1], "user");

         LastName = userEntry.Properties["FullName"].Value.ToString();

      }

      catch

      {

         result = false;

      }

      result = true;

   }

 

   // Активный каталог

   else

   {

      _path = _activeDirectoryPath;

 

      // Установка фильтра

      identification = identification.Substring(identification.LastIndexOf(@"\") + 1,

      identification.Length - identification.LastIndexOf(@"\")-1);

      string userNameFilter = string.Format(_filter, identification);

 

      // Установка Directory Searcher в LDAPPath

      DirectorySearcher searcher = new DirectorySearcher(_path);

      if (searcher == null)

      {

         return false;

      }

                  

      // Добавление свойств, подлежащих извлечению

      searcher.PropertiesToLoad.Add("givenName");

      searcher.PropertiesToLoad.Add("sn");

                          

      // Установка фильтра для поиска

      searcher.Filter = userNameFilter;

                  

      try

      {

         // Выполнение поиска

         SearchResult search = searcher.FindOne();

                         

         if (search != null)

         {

            FirstName = SearchResultProperty(search, "givenName");

            LastName = SearchResultProperty(search, "sn");

            result = true;

         }

         else

            result = false;

      }

  

      catch

      {

         result = false;

      }

   }

 

   return result;

}

 

Уровень представления

Уровень представления отвечает за пользовательский интерфейс и поддерживает связь непосредственно с уровнем бизнес-логики.  Отделение уровня представления от остальной части приложения делает возможной разработку различных пользовательских интерфейсов (т.е., Web Forms, Windows Forms, Mobile Devices), которые все используют одну и ту же бизнес-логику и код доступа к базе данных.

Пользовательские элементы управления

Основные вкладки расположены в верхней части каждого экрана, а вкладки в разделе Administration (Администрирование) реализованы как пользовательские элементы управления для того, чтобы можно было применить многократное использование кода.  Авторизация осуществляется пользовательским элементом управления, поскольку он принимает решение об отображении вкладок Reports (Отчеты) и Administration на основании роли пользователя.  Роль пользователя извлекается из зашифрованного cookie, хранящего информацию о пользователе (см. раздел "Безопасность" ниже).

 

 

 

 

 

 

 

 

 

 

 

 

 

Пользовательские элементы управления выделены желтым цветом.

 
Страница записи времени

 

 

 

 

 

 

 

 

 

 

 

 

 

На странице записи времени пользователь может добавлять, изменять и удалять записи времени. 

 
DataGrid с пользовательским контекстным редактированием

Одной из важных характеристик элемента управления DataGrid является способность выполнять контекстное редактирование. Оно выполняется путем определения столбца как EditTemplate и заполнением его другим элементом управления сервера ASP.NET, таким, как TextBox или DropDownList.  Пример приведен в таблице времени, показанной ниже.

 

 

 

 

 

 

 

Приложение Time Tracker расширяется за счет встроенных функций контекстного редактирования DataGrid таким образом, что изменение в DropDownList проекта повлечет за собой изменение списка категорий в соответствующем DropDownList категории.

Создание отчета

Отчет по проекту

Когда менеджерам проекта необходимо узнать, как их группы продвигаются в различных проектах, они могут использовать страницу отчетов (Reports) для запуска формирования отчета по проекту.  Этот отчет создан на основании проектов, отобранных на экране запуска.  Данные для этого отчета сгруппированы по резюме проекта, резюме категории и резюме ресурса.  Каждое имя консультанта в резюме ресурса - это гиперссылка на отчет по ресурсам для данного консультанта.

Web-элемент управления DataList используется для отображения резюме по проектам.  В этом отчете используются три элемента управления DataList: ProjectList (внешняя рамка), CategoryList (средняя рамка), and EntryList (внутренняя рамка).  DataList вложены друг в друга: один DataList помещается в элемент шаблона родительского DataList, как показано ниже.

 

<asp:datalist id="ProjectList" RepeatColumns="1" runat="server">

   <headerstyle cssclass="header-gray" />

   <headertemplate>

      Отчет по проекту

   </headertemplate>

   <itemtemplate>

      <asp:datalist id="CategoryList" RepeatColumns="1" runat="server">

         <itemtemplate>

            ...

 

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

<asp:datalist id="CategoryList" DataSource='<%# ListCategory((int) DataBinder.Eval(Container.DataItem, "ProjectID")) %>' runat="server">

ListCategory – это вспомогательная функция для получения резюме всех категорий определенного проекта.  Обратите внимание, что ProjectID передается из ProjectList в CategoryList.

Источник данных EntryList также реализуется по этой методике.

<asp:datalist id="EntryList" DataSource='<%# ListTimeEntries((int) DataBinder.Eval(Container.DataItem, "CategoryID")) %>' runat="server">

Отчет по ресурсам

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

 

 

 

 

 

 

 

 

 

Здесь применяется та же методика, что и при создании отчета по проекту, с небольшой разницей в структуре.  Отчет по ресурсам включает в себя DataList (UserList - внешняя рамка) с вложенным DataGrid (TimeEntryGrid – внутренняя рамка). В данной реализации используется DataGrid, поскольку сортировка подробностей записи является частью требований, предъявляемых к отчету. Код для сортировки очень похож на код, реализованный для страницы записи времени.

Связь UserList c TimeEntryGrid очень похожа на синтаксис, используемый в отчете по проекту.

<asp:datagrid id="TimeEntryGrid" DataSource='<%# ListTimeEntry((int)DataBinder.Eval(Container.DataItem, "UserID"), _startDate, _endDate) %>' runat="server" AutoGenerateColumns="False" AllowSorting="True" OnSortCommand="TimeEntryGrid_Sort">

ListTimeEntry – это вспомогательная функция получения всех записей времени для определенного пользователя в пределах указанного диапазона дат.  Параметр UserID передается из родительских DataList, UserList, а диапазон дат передается из программы запуска отчета.

Создание диаграммы GDI+

На странице записи времени динамически сгенерирована гистограмма, основанная на данных записи времени текущего пользователя.  Эта гистограмма наглядно представляет время, отработанное пользователем за определенную неделю.

Страница диаграммы

Чтобы динамически изобразить граф в течение времени выполнения, для возврата изображения необходима отдельная страница - TimeEntryBarChart.aspx.  Изображение возвращается в ответном потоке как бинарные данные, назначенные элементу управления - изображению.  Отдельная страница требуется потому, что в ответном потоке нельзя смешивать контент Text/HTML с бинарным контентом.  Затем страница записи времени обращается к этой странице диаграммы как к источнику изображения.

Строка запроса используется для передачи данных для оси X и оси Y.  Формат данных каждой оси – строка значений, в которой каждое значение отделено знаком "|".  Обратите внимание, что значения, переданные из строки запроса, - типа string; класс диаграммы отвечает за преобразование значений в нужный тип данных.  В данном конкретном случае на оси X представлены названия дней недели (понедельник, вторник и т.д.), а на оси Y – общее количество часов за каждый день.  Пример строки запроса и кода получения из нее данных приведен ниже.

http://localhost/TTWeb/TimeEntryBarChart.aspx?xValues=Mon|Tue|Wed|Thu|Fri|Sat|Sun&yValues=2|4.5|2|3|0|0|0

 

string xValues, yValues;

xValues = Request.QueryString["xValues"];

yValues = Request.QueryString["yValues"];

 

bar.CollectDataPoints(xValues.Split("|".ToCharArray()),

                  yValues.Split("|".ToCharArray()));

Для обеспечения наилучшего качества изображения диаграмма на странице представлена в формате PNG (помните, что формат PNG не поддерживается браузерами Netscape 4.x).  Поскольку изображение выводится в формате PNG, растровый объект нельзя записывать непосредственно в ответном выходном потоке, так как OutputStream не поддерживает функцию случайного поиска, требуемую форматом PNG.  Во избежание этой проблемы для записи растрового изображения в Response.OutputStream используется MemoryStream.

 

Bitmap bmp;

MemoryStream memStream = new MemoryStream();

BarGraph bar = new BarGraph();

 

bmp.Save(memStream, ImageFormat.Png);

memStream.WriteTo(Response.OutputStream);

Классы диаграммы

Для реализации функции изображения диаграмм используются четыре класса: ChartItem, ChartItemsCollection, Chart и BarGraph.  Первые три являются основополагающими классами для создания диаграмм разных типов.  Идея заключается в том, что разработчики могут многократно использовать эту реализацию для создания собственного пользовательского класса диаграммы; класс BarGraph получен с использованием этой же методики.

ChartItem (Элемент диаграммы)

Этот класс представляет единственную точку ввода данных и содержит достаточно информации для изображения элемента диаграммы.  Для реализации записи времени каждый ChartItem точно отображается на каждом столбике диаграммы.

ChartItemsCollection (Набор элементов диаграммы)

В .NET содержится абстрактный класс CollectionBase, позволяющий разработчикам легко создавать наборы для своих пользовательских классов.  ChartItemCollection реализует эту функциональную возможность для представления набора точек ввода данных для изображения диаграммы.

Chart (Диаграмма)

Этот класс реализован как абстрактный по следующим причинам:

·         для определения стандарта функциональных возможностей и интерфейсов для каждого производного из него класса; в этом случае, все производные классы должны замещать метод Draw(), иметь в наличии набор заранее заданных цветов и формировать набор точек ввода данных;

·         для установления ограничения на количество точек данных, по которым можно строить получаемый график; ограничение количества значений для графика желательно, поскольку слишком большой объем данных на графике снижает его полезность.

BarGraph (Гистограмма)

Будучи полученным из класса Chart, BarGraph имеет сложную реализацию, поскольку он должен динамически преобразовывать полученный набор данных в осмысленную информационную диаграмму в реальном времени.  Однако основной целью такого построения является простота его использования разработчиками, которым в процессе разработки необходимо строить гистограммы.

Например, для отображения диаграммы на странице записи времени в настраиваемом пользователем виде необходимо задать только два свойства BarGraph.  При создании класса этим свойствам назначены значения по умолчанию, поэтому во многих случаях разработчикам вообще не приходится настраивать свойства; достаточно напрямую вызвать метод CollectDataPoints() для передачи точек ввода данных, после чего вызвать метод Draw() для создания растрового изображения.

Сложные методы и математические расчеты для изображения гистограммы с использованием GDI+ не рассматриваются в данной документации.  Однако при реализации гистограммы полезно запомнить некоторые моменты:

·         При проектировании рекомендуется построить график на бумаге перед реализацией этой функции.

·         Вычислите заранее все значения и размеры для каждой части диаграммы.

·         Удостоверьтесь, что масштабы графика соответствуют количеству точек данных.

Мобильные устройства

Мобильные устройства, такие как PocketPC и сотовые телефоны, поддерживаются приложением Time Tracker в ограниченной форме.  Пользователи имеют возможность просмотра, добавления и обновления записей времени с помощью имеющихся у них мобильных устройств.  Для реализации поддержки мобильных устройств используется инструментарий Microsoft Mobile Information Toolkit.

 

 

 

 

 

 

 

 

 

 

 

 

Обычные страницы ASP.NET Web Forms могут содержать только одну серверную форму (например, <form runat=”Server”>) на странице. Однако из-за малых размеров экрана мобильных устройств мобильные страницы Web Forms позволяют определять несколько форм на одной странице. Это дает несколько преимуществ:

·         Можно управлять всеми элементами Web-сайта, избегая большого количества маленьких страниц.

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

·         Можно воспользоваться преимуществами средств уровня страницы, предоставляемых мобильными Web-формами, такими как автоматическое поддержание состояния страницы (известное как состояние отображения) и настройка на устройства, способные принимать множество экранов за один ответ.

 

 

 

 

 

 

 

 

Глобализация

Глобализацией называется процесс проектирования и разработки приложения, поддерживающего локализованные пользовательские интерфейсы и региональные данные для пользователей, принадлежащих к разным культурам. В .NET Framework класс CultureInfo представляет информацию о той или иной культурной среде. Сюда входят данные о системе письменности, используемых календарях, принятых форматах исчисления дат и времени, о числовой и денежной системах, а также правила сортировки.

Локализация – это процесс преобразования ресурсов приложения в локализованные версии для каждой культуры, которая будет поддерживаться этим приложением.

Приложение Time Tracker только глобализирует, но не локализирует ресурсы приложения.

Текущее значение культуры меняется в зависимости от установок браузера пользователя каждый раз при запросе страницы из приложения.

      // Инициализация значений культурных особенностей для каждого

      // запроса по языку пользователя из настроек браузера.

      protected void Application_BeginRequest(Object sender, EventArgs e)

      {

         if (Request.UserLanguages != null)

            Thread.CurrentThread.CurrentCulture =

              CultureInfo.CreateSpecificCulture(Request.UserLanguages[0]);

         else

            // Установка английского языка по умолчанию, если

            // пользовательские языки отсутствуют

            Thread.CurrentThread.CurrentCulture =

               new CultureInfo("en-us");

 

         Thread.CurrentThread.CurrentUICulture =

         Thread.CurrentThread.CurrentCulture;

      }

Безопасность

При проектировании безопасности используется как аутентификация, так и авторизация. Аутентификация – это процесс, при котором приложение проверяет идентичность пользователя и его удостоверения. При авторизации фактически проверяются права аутентифицированного пользователя на доступ к запрошенному ресурсу.

Приложение TimeTracker поддерживает аутентификацию на основе Windows. Режим аутентификации определяется в web.config, а свойство User.Identity.Name поддерживает имя пользователя. Аутентификация Windows использует домен/активный каталог с процедурой запроса/подтверждения по протоколу NTLM.

Авторизация для TimeTracker осуществляется при помощи средств безопасности на уровне ролей для определения наличия у пользователя доступа к тому или иному ресурсу. Пользователи сгруппированы по различным ролям (администраторы, профессиональные пользователи, разработчики и т.д.), и отображение их ролей сохранено в базе данных. Роль текущего пользователя проверяется на навигационных вкладках, где определяется то, какие вкладки будут отображены для этого пользователя.  Проверка осуществляется при событии загрузки страницы для каждой страницы и подтверждает наличие у пользователя роли, необходимой для доступа к странице. Эти проверки препятствуют доступу пользователя к закрытым для него функциональным возможностям.

Аналогичным образом роль пользователя в приложении Time Tracker определяет задачи пользователя, которые он может или не может выполнять.  Например, консультант может только добавить записи времени в назначенные для него проекты, а менеджеры проектов могут только вносить изменения в проекты, которыми они руководят.

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

 

Задача

Консультант

Менеджер проекта

Администратор

Создание записи времени

Назначенные проекты

Назначенные и собственные проекты

Разрешено

Изменение подробностей записи времени

Назначенные проекты

Назначенные и собственные проекты

Разрешено

Удаление записи времени

Назначенные проекты

Назначенные и собственные проекты

Разрешено

Просмотр записи времени

Назначенные проекты

Назначенные и собственные проекты

Разрешено

Создание проекта

 

Разрешено

Разрешено

Изменение подробностей проекта

 

Собственные проекты

Разрешено

Удаление проекта

 

 

Разрешено

Просмотр проекта

 

Собственные проекты

Разрешено

Просмотр отчета по проекту

 

Собственные проекты

Разрешено

Просмотр отчета по ресурсам

 

Собственные проекты

Разрешено

Создание пользователя

 

 

Разрешено

Изменение подробностей учетной записи пользователя

 

 

Разрешено

Просмотр пользователей

 

 

Разрешено

 

 

 

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

TTSecurity.GetUserRole()

 

Развертывание

При использовании приложением Time Tracker аутентификации Windows, пользовательская информация, например, роль пользователя, сохраняется в зашифрованном cookie (с использованием функциональных возможностей, предоставленных классом аутентификации на основе Forms) при первой аутентификации пользователя.  Если приложение Time Tracker развертывается в "Web-ферме", то ключ, используемый для шифрования, должен быть одинаковым на каждом Web-сервере в Web-ферме, кроме случаев, когда активизирована функция сохранения с распределением нагрузки. 

При рассмотрении сценария Web-фермы пользователи могут регистрироваться через один сервер (это означает, что для этого сервера создано cookie), но затем запрашивать страницу, требующую аутентификации с другого сервера фермы (не имеющего cookie).  Это может привести к необходимости регистрации всякий раз при обращении к другому Web-серверу. По умолчанию ключ расшифровки cookie аутентификации установлен на автоматическое генерирование, означающее, что ключ расшифровки является случайным ключом, зависимым от этого сервера. Это означает, что такие серверы не смогут использовать cookie друг друга. Для правильной конфигурации фермы ключу machineKey в файле web.config каждого Web-сервера должен быть присвоено одинаковое значение.

Кроме этого, в приложении Time Tracker для определенных страниц используется состояние сеанса (т.е. страниц подробностей проекта).  Это означает, что если функция сохранения с распределением нагрузки не активизирована, то информация сеанса должна сохраняться на сервере состояния или SQL Server.  Это также можно задать в файле web.config.

 

О нас | Карта сайта | Наши контакты | ©2007 Красноярский Государственный Педагогический Университет им. В.П.Астафьева
Перепечатка с указанием ссылки.