SQLUNINTERRUPTED

I am just a medium, SQL Server the Goal

Monthly Archives: April 2012

How To Determine User permissions on a Report Item

Recently while delivering a SQL Server Reporting Services workshop, a customer presented to me a very interesting question.

In their environment, they have multiple roles defined in SSRS, and when I say multiple, I am talking about more than 300 roles defined in SQL Reporting Services (customer has a work force of over 200K). My initial reaction was one of awe, as this is probably the first time I have seen anyone using this many roles and have that many users defined in SQL Reporting Services.

Their requirements were two fold

  1. Given a Report Item name and the User name, they need to find the permissions this user has on a report item.
  2. If the user is part of multiple roles, they also need to figure the permissions associated with each role.

The first part of the problem is real simple. In the Report Server Database we have 4 tables, writing a query one which provides the role membership of a user on the report items.

  • dbo.Roles
  • dbo.Catalog
  • dbo.Policies
  • dbo.PolicyUserRole
   1: Select C.Name,R.RoleName, U.UserName from 

   2: dbo.Catalog C 

   3: inner join dbo.PolicyUserRole PR on C.PolicyID = PR.PolicyID

   4: inner join dbo.Roles R on R.RoleID = PR.RoleID

   5: inner join dbo.Users U on PR.UserID = U.UserID 

   6: where U.UserName = '<reportusername>' and C.Name = ‘<report Item Name>’ 

The above query returns the effective permissions on the report Item for a given user.

The second part of the problem is a bit complex. In the Report Server Database, we do not store the explicit permissions for the Roles. What we instead do, is store it as a Bit Mask in the dbo.Roles table.

The TaskMask column in the dbo.Roles tables maps to the effective permissions for each role. There is no simple way to find what these bit mask values represent, so I created two static tables in the Report Server database or any other database (preferable) and then use these two tables in the function I created.

The Two Tables I created were

   1: create table SystemRoleTemp (ID int IDENTITY(1,1), permission varchar(200))

   2:         insert into SystemRoleTemp(permission) values 

   3:          ('Manage Roles')

   4:         ,('Manage Report Server Security')

   5:         ,('View Report Server Properties')

   6:         ,('Manage Report Server Properties')

   7:         ,('View Shared Schedules')

   8:         ,('Manage Shared Schedules')

   9:         ,('Generate Events')

  10:         ,('Manage Jobs')

  11:         ,('Execute Report Definitions')

   1: create table UsersRolesTemp (ID int IDENTITY(1,1), permission varchar(200))

   2:         insert into UsersRolesTemp(permission) values 

   3:         ('Set Security for Individual Items')

   4:         ,('Create Linked Reports')

   5:         ,('View Reports')

   6:         ,('Manage Reports')

   7:         ,('View Resources')

   8:         ,('Manage Resources')

   9:         ,('View Folders')

  10:         ,('Manage folders')

  11:         ,('Manage Report history')

  12:         ,('Manage Individual Subscriptions')

  13:         ,('Manage All Subscription')

  14:         ,('View Data Sources')

  15:         ,('Manage Data Sources')

  16:         ,('View Models')

  17:         ,('Manage Models')

  18:         ,('Consume Reports')

These two tables map the permissions for the System Roles and Item Specific roles.

Next I created a UDF to return the permissions associated with each role.

The UDF check for the corresponding bits of the BitMask and appends the permissions in a string, the function then returns the string to the caller.

   1: Alter function dbo.EffectivePermissionsRoles (@TaskMask nvarchar(20), @RoleFlag tinyint)

   2: Returns varchar(500)

   3: As

   4: Begin

   5:     Declare @effectivepermissions varchar(600) ='Role Permissions ==> '

   6:     declare @taskmaskindex int

   7:     set @taskmaskindex = LEN(@TaskMask)

   8:     declare @count int = 1

   9:     declare @temp varchar(50)

  10:     

  11:     ---- For System Roles

  12:         

  13:         If (@RoleFlag = 1)

  14:         begin

  15:             While @count < @taskmaskindex

  16:                 begin

  17:                     if(SUBSTRING(@TaskMask, @count, 1) ='1')

  18:                     begin

  19:                         Select @temp = permission + ','  from dbo.SystemRoleTemp where ID = @count

  20:                     end

  21:                     Set @effectivepermissions = @effectivepermissions + ISNULL(@temp,'')

  22:                     Set @temp = ''

  23:                     Set @count = @count+1

  24:                 end

  25:         end

  26:         

  27:         --- For Item Specific Roles

  28:         If (@RoleFlag = 0)

  29:         begin

  30:                 While @count < @taskmaskindex

  31:                 begin

  32:                     if(SUBSTRING(@TaskMask, @count, 1) = '1')

  33:                     begin

  34:                         Select @temp = permission  + ',' from UsersRolesTemp where ID = @count

  35:                     end

  36:                     Set @effectivepermissions = @effectivepermissions + ISNULL(@temp,'')

  37:                     Set @temp = ''

  38:                     Set @count = @count+1

  39:                 end

  40:         end

  41:     return @effectivepermissions      

  42: end

  43: GO

Finally, we can put all of it together in a Stored Procedure or in a SQL Query as follows, to return the effective permissions for the users on a particular report Item.

   1: Select C.Name,R.RoleName, U.UserName, dbo.EffectivePermissionsRoles(R.TaskMask, R.RoleFlags)  As RolePermissions 

   2: from 

   3: dbo.Catalog C 

   4: inner join dbo.PolicyUserRole PR on C.PolicyID = PR.PolicyID

   5: inner join dbo.Roles R on R.RoleID = PR.RoleID

   6: inner join dbo.Users U on PR.UserID = U.UserID 

   7: where U.UserName = '<User Name>'  and C.Name = '<ReportItemName>'

Advertisement

Working with Data Alerts in SQL Reporting Services 2012 – Part1

With SQL Server 2012 Reporting Services, we introduced a new feature called Data Alerts. Data Alert is a data driven alerting mechanism, where in you can get automated responses if the data associated with a particular report changes. These alerts are send by email, with the user having control on the frequency of these emails and the rules (conditions) on which these alerts are fired.

Requirements

Data Alerts work only with reports which are deployed in a SharePoint library. This means if your Reporting Services is configured for Native Mode, you cannot configure Data Alerts.  SSRS 2012, unlike earlier versions of SSRS does not allow changing an existing Native Mode installation to SharePoint Integrated mode using the Reporting Services configuration manager. You need to install a new instance of reporting services in SharePoint mode to use it.

How Data Alerts work

Data Alerts work flow can be divided into two sections, configuration and processing of alerts. During the configuration phase, the user needs to be first run the report. Data Alerts can only be configured if the Report has data. Data Alerts can be configured for any report (containing any item type) as long as it has some data. In order to configure Data Alerts, the report data source must use Stored Credentials or no credentials (would use the SSRS execution account).

Power View reports cannot be configured for Data Alerts.

image

Once the Data Alert has been configured, it is put in the Alerting database. This database is automatically created when we install SSRS in SharePoint integrated mode. By default the name of the database is ReportingServices<GUID>_Alerting. This also creates a SQL Agent job, to automatically processes the data alert based on the schedule defined, while creating the alert.

When the SQL Agent Job starts at its schedule, it starts the processing of the data Alert. During processing, the Report is run and the data feed for the report is refreshed. Then the rules defined for the alert are applied to the data feed. It a data value matches the rules applied in the alert, it is included in the results for the Alert. An email messages is composed with all the data value which match the rules and sent to the recipients (specified during alert creation).

The email messages being sent, typically contains the following

  1. From email address, is the email address configured in your SSRS Email Settings.
  2. To addresses are the emails provided during Alert creation.
  3. The Email body consists of the following, but is not limited to
    • Data Values in the result set.
    • A link to the report on which the alert is built.
    • The name of the person who configured the alert.
    • The parameters and values used in the report during the time of alert creation.

image

In another post, I will talk about installing data alerts and using the data alert designer.