public void MSOXCPERM_S03_TC01_SetUnexpectedPermissionFlags()
        {
            this.OxcpermAdapter.InitializePermissionList();

            uint getPermissionResponseValue          = 0;
            List <PermissionTypeEnum> permissionList = new List <PermissionTypeEnum>();
            RequestBufferFlags        bufferFlag     = new RequestBufferFlags();
            FolderTypeEnum            folderType     = FolderTypeEnum.CommonFolderType;

            // Set the right flags that are not specified in the Open Specification.
            permissionList.Add(PermissionTypeEnum.Reserved20Permission);
            uint responseValueSetPermission = OxcpermAdapter.AddPermission(folderType, this.User1, bufferFlag, permissionList);

            permissionList.Clear();
            getPermissionResponseValue = OxcpermAdapter.GetPermission(folderType, this.User1, bufferFlag, out permissionList);

            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCPERM_R1093: Verify the unexpected permission flags specified in [MS-OXCPERM] section 2.2.7 can't be set. The test case expects that if set the unexpected permission flags, return value is not success or return value is success but actually the flags are not set.");

            // Verify MS-OXCPERM requirement: MS-OXCPERM_R1093
            // If the server fails to set the unexpected flags or the permissions set for the user is empty, it indicates that the server doesn't set the permission flags that are not specified in the Open Specification.
            bool isR1093Verified = responseValueSetPermission != TestSuiteBase.UINT32SUCCESS || (getPermissionResponseValue == TestSuiteBase.UINT32SUCCESS && permissionList.Count == 0);

            Site.CaptureRequirementIfIsTrue(
                isR1093Verified,
                1093,
                @"[In PidTagMemberRights Property] The client and server MUST NOT set any other flags [except ReadAny, Create, EditOwned, DeleteOwned, EditAny, DeleteAny, CreateSubFolder, FolderOwner, FolderContact, FolderVisible, FreeBusySimple, FreeBusyDetailed].");
        }
        public void MSOXCPERM_S03_TC02_RetrieveFolderPermissionNotImplementedError()
        {
            this.OxcpermAdapter.InitializePermissionList();

            FolderTypeEnum folderType     = FolderTypeEnum.CommonFolderType;
            const uint     NotImplemented = 0x80040102;

            uint responseValue = OxcpermAdapter.ReadSecurityDescriptorProperty(folderType);

            // Verify MS-OXCPERM requirement: MS-OXCPERM_R183
            Site.CaptureRequirementIfAreEqual <uint>(
                NotImplemented,
                responseValue,
                183,
                @"[In Processing a Request for PidTagSecurityDescriptorAsXml Property] When the server receives a RopOpenStream ROP request ([MS-OXCROPS] section 2.2.9.1) on the PidTagSecurityDescriptorAsXml property ([MS-XWDVSEC] section 2.2.2) of the folder, the server MUST return an error code of ecNotImplemented rather than satisfying the RopOpenStream ROP request.");

            // Verify MS-OXCPERM requirement: MS-OXCPERM_R152
            Site.CaptureRequirementIfAreEqual <uint>(
                NotImplemented,
                responseValue,
                152,
                @"[In Retrieving Folder Permissions] The server MUST return an error code of ecNotImplemented instead of satisfying the RopOpenStream ROP request.");

            this.NeedDoCleanup = false;
        }
        public void MSOXCPERM_S03_TC03_VerifyRopQueryRowsErrorCodeAccessDenied()
        {
            this.OxcpermAdapter.InitializePermissionList();

            Site.Assume.IsTrue(Common.IsRequirementEnabled(115, this.Site), "This case runs only when the implementation supports the FolderOwner permission.");
            const uint                AccessDenied   = 0x80070005;
            FolderTypeEnum            folderType     = FolderTypeEnum.CommonFolderType;
            List <PermissionTypeEnum> permissionList = new List <PermissionTypeEnum>();
            RequestBufferFlags        bufferFlag     = new RequestBufferFlags();

            // Add the user entry in the permissions list to modify the permissions later.
            permissionList.Add(PermissionTypeEnum.FolderOwner);
            permissionList.Add(PermissionTypeEnum.FolderVisible);
            uint responseValue = OxcpermAdapter.AddPermission(folderType, this.User1, bufferFlag, permissionList);

            Site.Assert.AreEqual <uint>(TestSuiteBase.UINT32SUCCESS, responseValue, "0 indicates the server response successfully.");

            OxcpermAdapter.Logon(this.User1);
            permissionList.Clear();

            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCPERM_R2007: Verify the AccessDenied (0x80070005) when calling RopQueryRows to retrieve the permission list if the permission is insufficient.");

            // Verify MS-OXCPERM requirement: MS-OXCPERM_R2007
            responseValue = OxcpermAdapter.CheckRopQueryRowsErrorCodeAccessDenied(folderType, this.User1, permissionList);
            Site.CaptureRequirementIfAreEqual <uint>(
                AccessDenied,
                responseValue,
                2007,
                "[In Processing a RopGetPermissionsTable ROP Request] If the user does not have permission to view the permissions list of the folder, the server returns 0x80070005 (AccessDenied) in the ReturnValue field of the RopQueryRows ROP response buffer.");
        }
        public void MSOXCPERM_S01_TC01_GetFolderPermissionsList()
        {
            this.OxcpermAdapter.InitializePermissionList();

            // Set the calendar folder type
            FolderTypeEnum folderType    = FolderTypeEnum.CalendarFolderType;
            uint           responseValue = 0;

            // Set IncludeFreeBusy flag
            RequestBufferFlags bufferflags = new RequestBufferFlags
            {
                IsIncludeFreeBusyFlagSet = true
            };
            List <PermissionTypeEnum> permissionList = new List <PermissionTypeEnum>
            {
                PermissionTypeEnum.FreeBusyDetailed,
                PermissionTypeEnum.FreeBusySimple
            };

            // Add the FreeBusyDetailed and FreeBusySimple to the calendar folder.
            responseValue = OxcpermAdapter.AddPermission(folderType, this.User1, bufferflags, permissionList);
            Site.Assert.AreEqual <uint>(TestSuiteBase.UINT32SUCCESS, responseValue, "0 indicates the server adds permission successfully.");

            // Get the permissions list on the folder
            permissionList.Clear();
            responseValue = OxcpermAdapter.GetPermission(folderType, this.User1, bufferflags, out permissionList);

            // Add the debug information
            this.Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCPERM_R2014");

            // Verify MS-OXCPERM requirement: MS-OXCPERM_R2014
            this.Site.CaptureRequirementIfAreEqual <uint>(
                TestSuiteBase.UINT32SUCCESS,
                responseValue,
                2014,
                @"[In Processing a RopGetPermissionsTable ROP Request] If the user has permission to view the permissions list of the folder, the server returns the permissions list in a RopQueryRows ROP response buffer ([MS-OXCROPS] section 2.2.5.4). ");

            // Verify MS-OXCPERM requirement: MS-OXCPERM_R19
            bool   isR19Verified      = permissionList.Contains(PermissionTypeEnum.FreeBusyDetailed) && permissionList.Contains(PermissionTypeEnum.FreeBusySimple);
            string returnedPermission = this.ConvertFreeBusyStatusToString(permissionList);

            Site.Log.Add(LogEntryKind.Debug, "Verify MS-OXCPERM_R19: If the IncludeFreeBusy is set, the server should return {FreeBusyDetailed, FreeBusySimple}, actually " + returnedPermission);
            Site.CaptureRequirementIfIsTrue(
                isR19Verified,
                19,
                @"[In RopGetPermissionsTable ROP Request Buffer] If this flag [IncludeFreeBusy] is set, the server MUST include the values of the FreeBusySimple and FreeBusyDetailed flags of the PidTagMemberRights property in the returned permissions list.");

            // Remove the user from the permissions list that added in this case
            responseValue = OxcpermAdapter.RemovePermission(folderType, this.User1, bufferflags);
            Site.Assert.AreEqual <uint>(TestSuiteBase.UINT32SUCCESS, responseValue, "0 indicates the server removes permission successfully.");
        }
Esempio n. 5
0
        public XResponse Execute(MoveFolderRequest request, IXExecutionContext context)
        {
            XDbCommand          cmd;
            DomainObjectDataSet dataSet = new DomainObjectDataSet(context.Connection.MetadataManager.XModel);

            foreach (Guid oid in request.ObjectsID)
            {
                DomainObjectData xobj = dataSet.CreateStubLoaded("Folder", oid, -1);
                if (request.NewParent != Guid.Empty)
                {
                    // задана родительская папка
                    xobj.SetUpdatedPropValue("Parent", request.NewParent);
                    // родительская папка задана, однако, она может принадлежать другому клиенту и/или типу проектных затрат
                    cmd = context.Connection.CreateCommand(@"
						SELECT 
							CASE WHEN f1.Customer <> f2.Customer THEN f1.Customer ELSE cast(NULL as uniqueidentifier) END AS Customer, 
							CASE WHEN f1.ActivityType <> f2.ActivityType THEN f1.ActivityType ELSE cast(NULL as uniqueidentifier) END AS ActivityType
						FROM Folder f1, Folder f2
						WHERE f1.ObjectID = @NewParentID AND f2.ObjectID = @ObjectID 
							AND (f1.Customer <> f2.Customer OR f1.ActivityType <> f2.ActivityType)
						"                        );
                    cmd.Parameters.Add("NewParentID", DbType.Guid, ParameterDirection.Input, false, request.NewParent);
                    cmd.Parameters.Add("ObjectID", DbType.Guid, ParameterDirection.Input, false, oid);
                    using (IDataReader reader = cmd.ExecuteReader())
                    {
                        int nIndex;
                        if (reader.Read())
                        {
                            nIndex = reader.GetOrdinal("Customer");
                            if (!reader.IsDBNull(nIndex))
                            {
                                xobj.SetUpdatedPropValue("Customer", reader.GetGuid(nIndex));
                            }
                            nIndex = reader.GetOrdinal("ActivityType");
                            if (!reader.IsDBNull(nIndex))
                            {
                                xobj.SetUpdatedPropValue("ActivityType", reader.GetGuid(nIndex));
                            }
                        }
                    }
                    // Далее мы проверяем следующее:
                    //	каталог может быть подчинен папке любого типа, однако проект только проекту,
                    //	а пресейл и тендер вообще никому
                    cmd.CommandText = @"
						SELECT f1.Type AS FolderType, f2.Type AS ParentFolderType, 
							f1.LIndex, f1.RIndex,
							f2.LIndex AS ParentLIndex, f2.RIndex AS ParentRIndex
						FROM Folder f1, Folder f2
						WHERE f1.ObjectID = @ObjectID AND f2.ObjectID = @NewParentID
						"                        ;
                    // Примечание: используем созданную ранее команду с параметрами NewParentID и ObjectID
                    using (IDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.Read())
                        {
                            FolderTypeEnum folderType       = (FolderTypeEnum)reader.GetInt16(reader.GetOrdinal("FolderType"));
                            FolderTypeEnum parentFolderType = (FolderTypeEnum)reader.GetInt16(reader.GetOrdinal("ParentFolderType"));
                            // Если у папки не изменилась ссылка на организацию клиента, то проверим, что ее не переносят в одну из дочерних папок
                            if (!xobj.HasUpdatedProp("Customer"))
                            {
                                // Примечание: LIndex/RIndex будут пересчитываться в триггере
                                int nLIndex       = reader.GetInt32(reader.GetOrdinal("LIndex"));
                                int nRIndex       = reader.GetInt32(reader.GetOrdinal("RIndex"));
                                int nParentLIndex = reader.GetInt32(reader.GetOrdinal("ParentLIndex"));
                                int nParentRIndex = reader.GetInt32(reader.GetOrdinal("ParentRIndex"));
                                // Проверим, что новый родитель не является дочерним (рекурсивно) узлом переносимой папки
                                if (nParentLIndex >= nLIndex && nParentRIndex <= nRIndex)
                                {
                                    throw new XBusinessLogicException(FolderTypeEnumItem.GetItem(folderType).Description + " не может быть перенесен в подчиненный " + FolderTypeEnumItem.GetItem(parentFolderType).Description.ToLower());
                                }
                            }
                            if (folderType == FolderTypeEnum.Project)
                            {
                                if (parentFolderType != FolderTypeEnum.Project)
                                {
                                    throw new XBusinessLogicException("Проект не может быть перенесен в " + FolderTypeEnumItem.GetItem(parentFolderType).Description.ToLower());
                                }
                            }
                            else if (folderType == FolderTypeEnum.Tender || folderType == FolderTypeEnum.Presale)
                            {
                                throw new XBusinessLogicException("Тендер (тендерная активность) и пресейл (пресейл-активноть) не могут быть перенесены в папку");
                            }
                        }
                    }
                }
                else
                {
                    // перенос в корень
                    xobj.SetUpdatedPropValue("Parent", DBNull.Value);
                    // однако при этом мог измениться клиент или тип проектных затрат
                    if (request.NewActivityType != Guid.Empty)
                    {
                        // если изменился тип проектных затрат, то ссылка на клиента также должна быть задана (даже если он не изменился)
                        if (request.NewCustomer == Guid.Empty)
                        {
                            throw new ArgumentException("Если задана ссылка на тип проектных затрат, то должна быть задана ссылка на организацию-клиента");
                        }

                        // также нужно проверить, что выбранный типа проектных затрат поддерживает тип переносимой папки
                        cmd = context.Connection.CreateCommand(@"
							SELECT 1 FROM ActivityType 
							WHERE ObjectID = @ActivityTypeID AND FolderType & (SELECT [Type] FROM Folder WHERE ObjectID = @ObjectID) > 0
							"                            );
                        cmd.Parameters.Add("ActivityTypeID", DbType.Guid, ParameterDirection.Input, false, request.NewActivityType);
                        cmd.Parameters.Add("ObjectID", DbType.Guid, ParameterDirection.Input, false, oid);
                        if (cmd.ExecuteScalar() == null)
                        {
                            throw new XBusinessLogicException("Перенос папки невозможен. Выбранный тип проектных затрат не может содержать папку переносимого типа.");
                        }

                        xobj.SetUpdatedPropValue("ActivityType", request.NewActivityType);
                        xobj.SetUpdatedPropValue("Customer", request.NewCustomer);
                    }
                    else if (request.NewCustomer != Guid.Empty)
                    {
                        // Если выбрали организацию без изменения типа проектных затрат, то подразумевается, что он (ActivityTyoe) остается прежним,
                        // однако такое возможно только при переносе либо между организациями-клиентами, либо между организациями-владельцами.
                        cmd = context.Connection.CreateCommand(@"
							SELECT 1 FROM Organization c1, Organization c2 
							WHERE c1.ObjectID = (SELECT Customer FROM Folder WHERE ObjectID = @ObjectID)
								AND c2.ObjectID = @NewCustomerID AND c1.Home <> c2.Home
							"                            );
                        cmd.Parameters.Add("NewCustomerID", DbType.Guid, ParameterDirection.Input, false, request.NewCustomer);
                        cmd.Parameters.Add("ObjectID", DbType.Guid, ParameterDirection.Input, false, oid);
                        if (cmd.ExecuteScalar() != null)
                        {
                            throw new XBusinessLogicException("Перенос папки невозможен. Для переноса папок между разными типами проектных затрат следует выбрать узел, соответствующий требуемому типу проектных затрат.");
                        }

                        xobj.SetUpdatedPropValue("Customer", request.NewCustomer);
                    }
                    else
                    {
                        // Parent = Null, Customer = Null, ActivityType = Null - такого быть не может
                        throw new ArgumentException("При незаданной ссылке на родительскую папку должны быть заданы ссылки на Клиента и/или Тип проектных затрат");
                    }
                }

                XSecurityManager.Instance.DemandSaveObjectPrivilege(xobj);
            }
            XStorageGateway.Save(context, dataSet, Guid.NewGuid());

            // если все сохранилось хорошо, то отработали триггеры, изменяющие LIndex/RIndex, и возможно Customer.
            // Если у переносимой папки изменилась ссылка на тип проектных затрат ,
            // то необходимо изменить эту ссылку всем подчиненным папкам (если они есть)
            StringBuilder cmdBuilder = new StringBuilder();

            cmdBuilder.AppendFormat(
                @"UPDATE f
SET f.ActivityType = p.ActivityType
FROM Folder f
	JOIN Folder p ON f.LIndex > p.LIndex AND f.RIndex < p.RIndex AND f.Customer = p.Customer
WHERE p.ObjectID IN ("
                );
            cmd = context.Connection.CreateCommand();
            string sParamName;
            int    nParamIndex = 0;

            foreach (Guid oid in request.ObjectsID)
            {
                ++nParamIndex;
                sParamName = "ObjectID" + nParamIndex;
                cmd.Parameters.Add(sParamName, XPropType.vt_uuid, ParameterDirection.Input, false, oid);
                cmdBuilder.Append(context.Connection.GetParameterName(sParamName));
                cmdBuilder.Append(",");
            }
            // Отрежим последнюю запятую
            cmdBuilder.Length--;
            cmdBuilder.Append(")");
            cmd.CommandText = cmdBuilder.ToString();
            cmd.ExecuteNonQuery();

            // Если у переносимой папки были заданы направления, которые не соответствуют направлениям новой
            // родительской папки, то удалим эти направления
            if (request.NewParent != Guid.Empty)
            {
                cmdBuilder = new StringBuilder();


                cmd         = context.Connection.CreateCommand();
                nParamIndex = 0;
                foreach (Guid oid in request.ObjectsID)
                {
                    ++nParamIndex;
                    sParamName = "FolderID" + nParamIndex;
                    cmd.Parameters.Add(sParamName, XPropType.vt_uuid, ParameterDirection.Input, false, oid);
                    cmdBuilder.Append(context.Connection.GetParameterName(sParamName));
                    cmdBuilder.Append(",");
                }
                // Отрежим последнюю запятую
                cmdBuilder.Length--;
                cmd.CommandText = @"IF (EXISTS(
	                    SELECT top 1 fd.Direction
	                    FROM dbo.FolderDirection fd
	                    WHERE (fd.Direction not in 
	                        (
		                    SELECT Direction
		                    FROM dbo.FolderDirection
		                    WHERE  Folder = @ParentID) 
	                        AND fd.Folder IN ("     + cmdBuilder.ToString() + @"))  OR
                        EXISTS(
                            SELECT COUNT(*) 
                            FROM dbo.FolderDirection
                            WHERE Folder IN (" + cmdBuilder.ToString() + @")
                            HAVING COUNT(*)>1))) AND EXISTS( SELECT TOP 1 * FROM dbo.Folder WHERE ObjectID = @ParentID )
                                               
                        BEGIN
	                        DELETE fd
	                        FROM
	                        FolderDirection fd
	                        WHERE fd.Folder IN ("     + cmdBuilder.ToString() +
                                  @")
                        END"
                ;
                cmd.Parameters.Add("ParentID", DbType.Guid, ParameterDirection.Input, false, request.NewParent);
                cmd.ExecuteNonQuery();
            }

            return(new XResponse());
        }
        /// <summary>
        /// Check the error code AccessDenied when calling RopQueryRows ROP.
        /// </summary>
        /// <param name="folderType">Folder type</param>
        /// <param name="permissionUserName">The permission user name</param>
        /// <param name="permissionList">The permission list of the folder specified by folderType</param>
        /// <returns>The return value from the server. 0x00000000 indicates success, others indicate error occurs.</returns>
        public uint CheckRopQueryRowsErrorCodeAccessDenied(FolderTypeEnum folderType, string permissionUserName, List<PermissionTypeEnum> permissionList)
        {
            // Get the folder handle
            uint folderHandle = this.GetFolderObjectHandle(folderType);

            RequestBufferFlags requestBufferFlags = new RequestBufferFlags();
            uint status = this.RetrievePermissionsList(folderType, folderHandle, requestBufferFlags);
            Site.Assert.AreEqual<uint>(UINT32SUCCESS, status, "0 indicates querying permission data operates successfully.");

            List<PermissionUserInfo> permissionUserList = new List<PermissionUserInfo>();
            this.ParseUserListFromRawData(out permissionUserList, ref this.rawData);

            bool memberIdIsExisted = false;
            ulong pidTagMemberId = this.GetPidTagMemberId(permissionUserList, permissionUserName, out memberIdIsExisted);

            uint nrights = this.ParsePermissionFromPermissionTypeListToByteFormat(permissionList);
            PermissionData[] permissionsDataArray = this.SetPermissionDataArrayForModify(pidTagMemberId, nrights);

            // Check the user doesn't contain FolderVisible
            Site.Assume.IsFalse(permissionList.Contains(PermissionTypeEnum.FolderVisible), "False indicate the user: {0} doesn't contain FolderVisible.", permissionUserName);

            // Modify the permissions
            this.DoRopCall(this.CreateModifyPermissionsRequestBuffer(permissionsDataArray, requestBufferFlags), folderHandle, ref this.response, ref this.rawData);
            RopModifyPermissionsResponse modifyPermissionsResponse = (RopModifyPermissionsResponse)this.response;
            Site.Assert.AreEqual<uint>(UINT32SUCCESS, modifyPermissionsResponse.ReturnValue, "0 indicates the RopModifyPermissions operates successfully.");

            status = this.RetrievePermissionsList(folderType, folderHandle, requestBufferFlags);
            return status;
        }
        /// <summary>
        ///  Remove a permission for a user from the permission list on the folder
        /// </summary>
        /// <param name="folderType">Folder type</param>
        /// <param name="permissionUserName">The user is removed from the permissions list. The user name is the alias of the user without domain</param>
        /// <param name="requestBufferFlags">Request buffer flags</param>
        /// <returns>The return value from the server. 0x00000000 indicates success, others indicates error occurs.</returns>
        public uint RemovePermission(FolderTypeEnum folderType, string permissionUserName, RequestBufferFlags requestBufferFlags)
        {
            if (permissionUserName == null)
            {
                throw new ArgumentNullException("permissionUserName");
            }

            uint folderHandle = this.GetFolderObjectHandle(folderType);

            List<PermissionUserInfo> permissionUserList;
            uint responseValue = UINT32FAILED;
            this.QueryPermission(folderType, out folderHandle, out permissionUserList);

            bool memberIdIsExisted = false;
            ulong pidTagMemberId = this.GetPidTagMemberId(permissionUserList, permissionUserName, out memberIdIsExisted);
            if (memberIdIsExisted)
            {
                PermissionData[] permissionsDataArray = this.SetPermissionDataArrayForRemove(pidTagMemberId);
                this.DoRopCall(this.CreateModifyPermissionsRequestBuffer(permissionsDataArray, requestBufferFlags), folderHandle, ref this.response, ref this.rawData);

                RopModifyPermissionsResponse modifyPermissionsResponse = (RopModifyPermissionsResponse)this.response;
                this.VerifyModifyPermissionsResponse();
                responseValue = modifyPermissionsResponse.ReturnValue;

                this.VerifyReturnValueForModifyPermission();

                if (responseValue == UINT32SUCCESS)
                {
                    this.VerifyReturnValueSuccessForModifyPermission(responseValue);
                }
            }
            else
            {
                return UINT32SUCCESS;
            }

            // RopRelease folder message 
            this.ReleaseObject(folderHandle);

            return responseValue;
        }
        /// <summary>
        /// Modify the permission list for a user on the folder
        /// </summary>
        /// <param name="folderType">Folder type</param>
        /// <param name="permissionUserName">The user whose permission is modified. The user name is the alias of the user without domain</param>
        /// <param name="requestBufferFlags">Request buffer flags</param>
        /// <param name="permissionList">The permission list of the folder specified by folderType</param>       
        /// <returns>The return value from the server. 0x00000000 indicates success, others indicates error occurs.</returns>
        public uint ModifyPermission(FolderTypeEnum folderType, string permissionUserName, RequestBufferFlags requestBufferFlags, List<PermissionTypeEnum> permissionList)
        {
            if (permissionUserName == null)
            {
                throw new ArgumentNullException("permissionUserName");
            }

            uint folderHandle = this.GetFolderObjectHandle(folderType);

            List<PermissionUserInfo> permissionUserList;
            uint responseValue = UINT32FAILED;
            this.QueryPermission(folderType, out folderHandle, out permissionUserList);

            bool memberIdIsExisted = false;
            ulong pidTagMemberId = this.GetPidTagMemberId(permissionUserList, permissionUserName, out memberIdIsExisted);
            if (memberIdIsExisted)
            {
                uint nrights = this.ParsePermissionFromPermissionTypeListToByteFormat(permissionList);
                PermissionData[] permissionsDataArray = this.SetPermissionDataArrayForModify(pidTagMemberId, nrights);

                this.DoRopCall(this.CreateModifyPermissionsRequestBuffer(permissionsDataArray, requestBufferFlags), folderHandle, ref this.response, ref this.rawData);

                RopModifyPermissionsResponse modifyPermissionsResponse = (RopModifyPermissionsResponse)this.response;
                this.VerifyModifyPermissionsResponse();
                responseValue = modifyPermissionsResponse.ReturnValue;

                this.VerifyReturnValueForModifyPermission();

                if (responseValue == UINT32SUCCESS)
                {
                    this.VerifyReturnValueSuccessForModifyPermission(responseValue);
                }
            }
            else
            {
                Site.Assert.Fail("No pidTagMemberId for the user: {0}", permissionUserName);
            }

            // RopRelease folder handle 
            this.ReleaseObject(folderHandle);

            return responseValue;
        }
        /// <summary>
        /// Add a permission for a user to the permission list of the folder
        /// </summary>
        /// <param name="folderType">Folder type</param>
        /// <param name="permissionUserName">The user whose permission is added. The user name is the alias of the user without domain</param>
        /// <param name="requestBufferFlags">Request buffer flags</param>
        /// <param name="permissionList">The permission list of the folder specified by folderType</param>      
        /// <returns>The return value from the server. 0x00000000 indicates success, others indicates error occurs.</returns>
        public uint AddPermission(FolderTypeEnum folderType, string permissionUserName, RequestBufferFlags requestBufferFlags, List<PermissionTypeEnum> permissionList)
        {
            if (permissionUserName == null)
            {
                throw new ArgumentNullException("permissionUserName");
            }

            uint folderHandle = this.GetFolderObjectHandle(folderType);
            uint pidTagMemberRights = this.ParsePermissionFromPermissionTypeListToByteFormat(permissionList);

            PermissionData[] permissionsDataArray = this.SetPermissionDataArrayForAdd(permissionUserName, pidTagMemberRights);

            this.responseSOHs = this.DoRopCall(
                this.CreateModifyPermissionsRequestBuffer(permissionsDataArray, requestBufferFlags),
                folderHandle,
                ref this.response,
                ref this.rawData);
            RopModifyPermissionsResponse modifyPermissionsResponse = (RopModifyPermissionsResponse)this.response;
            this.VerifyModifyPermissionsResponse();
            uint responseValue = modifyPermissionsResponse.ReturnValue;

            this.VerifyReturnValueForModifyPermission();

            if (responseValue == UINT32SUCCESS)
            {
                this.VerifyReturnValueSuccessForModifyPermission(responseValue);
            }

            // RopRelease folder handle 
            this.ReleaseObject(folderHandle);

            return responseValue;
        }
        /// <summary>
        /// Get the permission list for a user on the folder
        /// </summary>
        /// <param name="folderType">Folder type</param>
        /// <param name="permissionUserName">The user whose permission is returned. The user name is the alias of the user without domain</param>
        /// <param name="requestBufferFlags">The TableFlags or the ModifyFlags</param>
        /// <param name="permissionList">The permission list of the folder specified by folderType</param>
        /// <returns>The return value from the server. 0x00000000 indicates success, others indicates error occurs.</returns> 
        public uint GetPermission(FolderTypeEnum folderType, string permissionUserName, RequestBufferFlags requestBufferFlags, out List<PermissionTypeEnum> permissionList)
        {
            if (permissionUserName == null)
            {
                throw new ArgumentNullException("permissionUserName");
            }

            permissionList = new List<PermissionTypeEnum>();
            this.rawData = null;

            uint folderHandle = this.GetFolderObjectHandle(folderType);
            uint status = this.RetrievePermissionsList(folderType, folderHandle, requestBufferFlags);
            Site.Assert.AreEqual<uint>(UINT32SUCCESS, status, "0 indicates querying permission data operates successfully.");

            this.VerifyReturnValueForGetPermission();

            bool succeedToParse = this.ParseUserListFromRawData(out this.currentPermissionsList, ref this.rawData);
            if (succeedToParse)
            {
                this.VerifyMessageSyntax();
                this.VerifyPropertiesOfDataStructure(succeedToParse, this.currentPermissionsList);
                this.VerifyProperties(succeedToParse, this.currentPermissionsList);
            }

            uint responseValue = this.ParsePermissionByUserNameFromUserInfoList(permissionUserName, out permissionList, ref this.currentPermissionsList);

            return responseValue;
        }
        /// <summary>
        /// Read the folder's PidTagSecurityDescriptorAsXml property. For more details see section 3.1.4.1 Retrieving Folder Permissions of [MS-OXCPERM]
        /// </summary>
        /// <param name="folderType">The folder type specifies the PidTagSecurityDescriptorAsXml property of the folder is read.</param>
        /// <returns>The return value from the server. 0x00000000 indicates success, others indicates error occurs.</returns>
        public uint ReadSecurityDescriptorProperty(FolderTypeEnum folderType)
        {
            uint folderHandle = this.GetFolderObjectHandle(folderType);
            this.DoRopCall(this.CreateOpenStreamRequestBuffer(), (uint)folderHandle, ref this.response, ref this.rawData);
            RopOpenStreamResponse openStreamResponse = (RopOpenStreamResponse)this.response;

            // Release the stream object
            this.ReleaseObject(folderHandle);

            return openStreamResponse.ReturnValue;
        }
        /// <summary>
        /// Get Folder Object Handle
        /// </summary>
        /// <param name="folder">The folder type</param>
        /// <returns>Return the folder object handle</returns>
        private uint GetFolderObjectHandle(FolderTypeEnum folder)
        {
            ulong folderId = 0;
            if (folder == FolderTypeEnum.CalendarFolderType)
            {
                folderId = this.GetCalendarFolderId();
            }
            else if (folder == FolderTypeEnum.CommonFolderType)
            {
                folderId = this.ropLogonResponse.FolderIds[4];
            }

            RopOpenFolderResponse openFolderResponse;
            this.responseSOHs = this.DoRopCall(this.CreateOpenFolderRequestBuffer(folderId), this.inobjHandle, ref this.response, ref this.rawData);
            openFolderResponse = (RopOpenFolderResponse)this.response;
            Site.Assert.AreEqual<uint>(UINT32SUCCESS, openFolderResponse.ReturnValue, "0 indicates the RopOpenFolder operates successfully.");

            uint folderHandle = this.responseSOHs[0][openFolderResponse.OutputHandleIndex];

            return folderHandle;
        }
        /// <summary>
        /// Get the permission data.
        /// </summary>
        /// <param name="folderType">Folder type</param>
        /// <param name="folderHandle">The handle of the folder</param>
        /// <param name="permissionUserList">Permission user list</param>
        private void QueryPermission(FolderTypeEnum folderType, out uint folderHandle, out List<PermissionUserInfo> permissionUserList)
        {
            permissionUserList = new List<PermissionUserInfo>();

            folderHandle = this.GetFolderObjectHandle(folderType);

            this.responseSOHs = this.DoRopCall(this.CreateGetPermissionsTableRequestBuffer(folderType), (uint)folderHandle, ref this.response, ref this.rawData);
            RopGetPermissionsTableResponse getPermissionsTableResponse = (RopGetPermissionsTableResponse)this.response;
            Site.Assert.AreEqual<uint>(UINT32SUCCESS, getPermissionsTableResponse.ReturnValue, "0 indicates the RopGetPermissionsTable operates successfully.");

            uint tableHandle = this.responseSOHs[0][getPermissionsTableResponse.OutputHandleIndex];
            PropertyTag[] propertyTags = this.CreateHierarchyTablePropertyTagsForPermissionUser();
            this.DoRopCall(this.CreateSetColumnsRequestBuffer(propertyTags), tableHandle, ref this.response, ref this.rawData);
            RopSetColumnsResponse setColumnsResponse = (RopSetColumnsResponse)this.response;
            Site.Assert.AreEqual<uint>(UINT32SUCCESS, setColumnsResponse.ReturnValue, "0 indicates the RopSetColumns operates successfully.");

            this.DoRopCall(this.CreateQueryRowsRequestBuffer(), tableHandle, ref this.response, ref this.rawData);
            RopQueryRowsResponse queryRowsResponse = (RopQueryRowsResponse)this.response;
            Site.Assert.AreEqual<uint>(UINT32SUCCESS, queryRowsResponse.ReturnValue, "0 indicates the RopQueryRows operates successfully.");

            if (!this.ParseUserListFromRawData(out permissionUserList, ref this.rawData))
            {
                throw new ArgumentException("Failed to parse the row data from permissions list");
            }

            // RopRelease table message 
            this.ReleaseObject(tableHandle);
        }
        /// <summary>
        /// Create request to get permissions table
        /// </summary>
        /// <param name="folderType">Folder type</param>
        /// <returns>A request is used to get permissions table</returns>
        private RopGetPermissionsTableRequest CreateGetPermissionsTableRequestBuffer(FolderTypeEnum folderType)
        {
            RopGetPermissionsTableRequest getPermissionsTableRequest = new RopGetPermissionsTableRequest
            {
                RopId = 0x3E,
                LogonId = 0x0,
                InputHandleIndex = 0x0,
                OutputHandleIndex = 0x01
            };

            if (folderType == FolderTypeEnum.CalendarFolderType)
            {
                getPermissionsTableRequest.TableFlags = 0x02; // IncludeFreeBusy
            }

            return getPermissionsTableRequest;
        }
        /// <summary>
        /// Retrieve the permission list for a user of the folder
        /// </summary>
        /// <param name="folderType">Folder type</param>
        /// <param name="folderHandle">Folder handle of the folder specified by argument folderType.</param>
        /// <param name="requestBufferFlags">The TableFlags or the ModifyFlags</param>
        /// <returns>Specify whether the folder handle is valid. 0 indicates valid, others indicate error occurs.</returns>
        private uint RetrievePermissionsList(FolderTypeEnum folderType, uint folderHandle, RequestBufferFlags requestBufferFlags)
        {
            this.responseSOHs = this.DoRopCall(this.CreateGetPermissionsTableRequestBuffer(requestBufferFlags), (uint)folderHandle, ref this.response, ref this.rawData);
            RopGetPermissionsTableResponse getPermissionsTableResponse = (RopGetPermissionsTableResponse)this.response;
            Site.Assert.AreEqual<uint>(UINT32SUCCESS, getPermissionsTableResponse.ReturnValue, "0 indicates the RopGetPermissionsTable operates successfully.");

            this.VerifyGetPermissionHandle(getPermissionsTableResponse.ReturnValue);
            this.VerifyReturnValueSuccessForGetPermission(getPermissionsTableResponse.ReturnValue);

            uint tableHandle = this.responseSOHs[0][getPermissionsTableResponse.OutputHandleIndex];

            PropertyTag[] propertyTags = this.CreateHierarchyTablePropertyTagsForPermissionUser();
            this.DoRopCall(this.CreateSetColumnsRequestBuffer(propertyTags), tableHandle, ref this.response, ref this.rawData);
            RopSetColumnsResponse ropSetColumnsResponse = (RopSetColumnsResponse)this.response;
            Site.Assert.AreEqual<uint>(UINT32SUCCESS, ropSetColumnsResponse.ReturnValue, "0 indicates the RopSetColumns operates successfully.");

            this.DoRopCall(this.CreateQueryRowsRequestBuffer(), tableHandle, ref this.response, ref this.rawData);
            RopQueryRowsResponse queryRowsResponse = (RopQueryRowsResponse)this.response;

            return queryRowsResponse.ReturnValue;
        }
Esempio n. 16
0
        protected override void buildReport(Croc.XmlFramework.ReportService.Layouts.ReportLayoutData data)
        {
            Guid        folderID = (Guid)data.Params.GetParam("ID").Value;
            IDictionary f        = null;



            using (IDataReader r = data.DataProvider.GetDataReader("dsMain", data.CustomData))
            {
                if (r.Read())
                {
                    f = _GetDataFromDataRow(r);
                }
            }

            if (null == f)
            {
                // Проект не найден
                writeEmptyBody(data.RepGen, "Проект не найден");
                return;
            }
            data.RepGen.WriteLayoutMaster();
            data.RepGen.StartPageSequence();
            data.RepGen.StartPageBody();

            data.RepGen.Header("<fo:basic-link color=\"#ffffff\" external-destination=\"x-tree.aspx?METANAME=Main&amp;LocateFolderByID=" + folderID.ToString() + "\" target=\"_blank\" show-destination=\"new\">" + xmlEncode(f["Name"]) + "</fo:basic-link>");
            data.RepGen.TStart(false, "CELL_CLASS", false);
            data.RepGen.TAddColumn(null, align.ALIGN_LEFT, valign.VALIGN_TOP, "30%");
            data.RepGen.TAddColumn(null, align.ALIGN_LEFT, valign.VALIGN_TOP, "70%");

            // основные свойства проекта
            data.RepGen.TRStart();
            data.RepGen.TRAddCell("Клиент", null, 1, 1, "BOLD");
            data.RepGen.TRAddCell(xmlEncode(f["CustomerName"]), null);
            data.RepGen.TREnd();
            data.RepGen.TRStart();
            data.RepGen.TRAddCell("Название", null, 1, 1, "BOLD");
            data.RepGen.TRAddCell(_GetFolderAnchor(f["Name"], (Guid)f["ObjectID"], false), null);
            data.RepGen.TREnd();
            if (null != f["Description"])
            {
                data.RepGen.TRStart();
                data.RepGen.TRAddCell("Описание", null, 1, 1, "BOLD");
                data.RepGen.TRAddCell(_LongText(f["Description"]), null);
                data.RepGen.TREnd();
            }
            if (null != f["FirstDate"])
            {
                data.RepGen.TRStart();
                data.RepGen.TRAddCell("Дата начала", null, 1, 1, "BOLD");
                data.RepGen.TRAddCell(xmlEncode(((DateTime)f["FirstDate"]).ToLongDateString()) + " (" + getUserMailAnchor(f["FirstName"] + ", " + f["FirstDep"], f["FirstMail"], (Guid)f["FirstID"], folderID) + ")", null);
                data.RepGen.TREnd();
            }
            if (null != f["LastDate"])
            {
                data.RepGen.TRStart();
                data.RepGen.TRAddCell("Дата последней активности", null, 1, 1, "BOLD");
                data.RepGen.TRAddCell(xmlEncode(((DateTime)f["LastDate"]).ToLongDateString()) + " (" + getUserMailAnchor(f["LastName"] + ", " + f["LastDep"], f["LastMail"], (Guid)f["LastID"], folderID) + ")", null);
                data.RepGen.TREnd();
            }

            FolderStates folderState = (FolderStates)f["State"];

            data.RepGen.TRStart();
            data.RepGen.TRAddCell("Состояние", null, 1, 1, "BOLD");
            data.RepGen.TRAddCell(xmlEncode(FolderStatesItem.GetItem(folderState).Description), null);
            data.RepGen.TREnd();

            FolderTypeEnum folderType = (FolderTypeEnum)f["Type"];

            data.RepGen.TRStart();
            data.RepGen.TRAddCell("Тип", null, 1, 1, "BOLD");
            data.RepGen.TRAddCell(xmlEncode(FolderTypeEnumItem.GetItem(folderType).Description), null);
            data.RepGen.TREnd();

            data.RepGen.TRStart();
            data.RepGen.TRAddCell("Тип проектной активности", null, 1, 1, "BOLD");
            data.RepGen.TRAddCell(xmlEncode(f["ActivityTypeName"]), null);
            data.RepGen.TREnd();

            // Код проекта:
            //	- только для активности;
            //	- м.б. не задан: в этом случае показываем что данных нет
            if (folderType != FolderTypeEnum.Directory)
            {
                data.RepGen.TRStart();
                data.RepGen.TRAddCell("Код", null, 1, 1, "BOLD");
                if (null != f["ExternalID"])
                {
                    data.RepGen.TRAddCell(xmlEncode(f["ExternalID"]), null);
                }
                else
                {
                    data.RepGen.TRAddCell(xmlEncode("(не задан)"), null);
                }
                data.RepGen.TREnd();
            }

            if (null != f["DefaultIncidentTypeName"])
            {
                data.RepGen.TRStart();
                data.RepGen.TRAddCell("Тип инцидента по умолчанию", null, 1, 1, "BOLD");
                data.RepGen.TRAddCell(xmlEncode(f["DefaultIncidentTypeName"]), null);
                data.RepGen.TREnd();
            }
            if ("0" != f["IsLocked"].ToString())
            {
                data.RepGen.TRStart();
                data.RepGen.TRAddCell("", null, 1, 1, "BOLD");
                data.RepGen.TRAddCell("Списания на папку заблокированы", null, 1, 1, "BOLD-RED");
                data.RepGen.TREnd();
            }
            int nTotalSpent = (int)f["SummarySpent"];

            if (0 != nTotalSpent)
            {
                data.RepGen.TRStart();
                data.RepGen.TRAddCell("Суммарные трудозатраты", null, 1, 1, "BOLD");
                data.RepGen.TRAddCell(
                    string.Format("<fo:basic-link external-destination=\"x-get-report.aspx?name=r-ProjectIncidentsAndExpenses.xml&amp;Folder={1}\">{0}</fo:basic-link>", xmlEncode(_FormatTimeStringAtServer(nTotalSpent, int.MaxValue)), folderID)
                    , null);
                data.RepGen.TREnd();
            }

            // Направления
            StringBuilder directions = new StringBuilder();

            using (IDataReader r = data.DataProvider.GetDataReader("dsDirections", data.CustomData))
            {
                while (r.Read())
                {
                    directions.AppendFormat("<fo:block>{0}</fo:block>", xmlEncode(r.GetString(0)));
                }
            }
            if (directions.Length != 0)
            {
                // Шапка
                data.RepGen.TRStart();
                data.RepGen.TRAddCell("Направления", null, 1, 1, "BOLD");
                data.RepGen.TRAddCell(directions.ToString(), null);
                data.RepGen.TREnd();
            }

            data.RepGen.TEnd();

            // проектная команда
            insertAdditionalProjectReports(data, folderID);

            // история
            insertFolderHistory(data, folderID);

            // инциденты
            insertWorkStaff(data, folderID);

            data.RepGen.EndPageBody();
            data.RepGen.EndPageSequence();
        }