SSAS roles - OR rather than AND - active-directory

we are using SSAS 2008. We have a data related permissions issue. We are successfully able to apply SSAS roles to an incoming user's (Active Directory [AD]) context. i.e. the results returned are based on the user's SSAS role and limit the data returned from a dimension based on the role.
As far as I am aware, you can apply multiple roles to a user so that dimensions take the relevant role and limits it's results - however this condition is applied as an intersection (i.e. an AND) - is it able to be applied as a union (i.e. an OR)
There are a couple of things to note.
- we are accessing our cube via Excel, so relying on the above intelligence within some MDX is not necessarily achievable because the user can query on any dimension (some may be limited by role while others not)
- we have toyed with the idea of having two cubes coupled with two different userIds (in different AD groups) per user; the user would extract data from Excel depending on the data they would like to see (and hence the cube they would be querying); this is messy because we would like the users results all wrapped up in one resultset rather than two separate ones
Has anyone experienced and/or a resolution to the above - is it possible - is there an alternative ?

You can add the Roles property to a SSAS connection string that hold a comma-delimited list of database roles to be evaluated. Only the roles applied in that list will then be applied by the server.
Data Source=localhost;Initial Catalog=MySSASDb;Roles=RoleA,RoleB

If you need a OR condition on 2 dimensions, you can add another dimension with 2 levels being the same level of the 2 initial dimension:
For instance, you want to limit the role to [Country].[France] or [Currency].[USD], then you can add a [CountryThenCurrency] dimension and allow the 2 following paths: [CountryThenCurrency].[France].[*] and [CountryThenCurrency].[*].[USD]
In other words: add dimensions in order to be able all your OR conditions in a single dimension.

I have been searching for a solution for this problem and found a great article of Chris Webb.
http://cwebbbi.wordpress.com/2011/12/22/replacing-cell-security-with-dimension-security/
The idea is to create a junk dimension named DIM_Security and put all distinct combination of both dimensions in there. Now via an MDX expression you get the UNION of all Members having either dimension1 = 'allowedvalue' or dimension2 = 'allowedvalue', thus you have OR permissions.
Moreover Webb explains how to do this with dynamic security.
Not copying all the MDX as the original post is several pages long with many screenhots and linked many times all over the web.

Related

Creating an Efficient (Dynamic) Data Source to Support Custom Application Grid Views

In the application I am working on, we have data grids that have the capability to display custom views of the data. As a point of reference, we modeled this feature using the concept of views as they exist in SharePoint.
The custom views should have the following capabilities:
Be able to define which subset of columns (of those that are
available) should be displayed in the view.
Be able to define one or
more filters for retrieving data. These filters are not constrained
to use only the columns that are in the result set but must use one
of the available columns. Standard logical conditions and operators
apply to these filters. For example, ColumnA Equals Value1 or
ColumnB >= Value2.
Be able to define a set of columns that the data will be sorted by. This set of columns can be one or more columns
from the set of columns that will be returned in the result set.
Be
able to define a set of columns that the data will be grouped by.
This set of columns can be one or more columns from the set of
columns that will be returned in the result set.
I have application code that will dynamically generate the necessary SQL to retrieve the appropriate set of data. However, it appears to perform poorly. When I run across a poorly performing query, my first thought is to determine where indexes might help. The problem here is that I won't necessarily know which indexes need to be created as the underlying query could retrieve data in many different ways.
Essentially, the SQL that is currently being used does the following:
Creates a temporary table variable to hold the filtered data. This table contains a column for each column that should be returned in the result set.
Inserts data that matches the filter into the table variable.
Queries the table variable to determine the total number of rows of data.
If requested, determines the grouping values of the data in the table variable using the specified grouping columns.
Returns the requested page of the requested page size of data from the table variable, sorted by any specified sort columns.
My question is what are some ways that I may improve this process? For example, one idea I had was to have my table variable only contain the columns of data that are used to group and sort and then join in the source table at the end to get the rest of the displayed data. I am not sure if this would make any difference which is the reason for this post.
I need to support versions 2014, 2016 and 2017 of SQL Server in addition to SQL Azure. Essentially, I will not be able to use a specific feature of an edition of SQL Server unless that feature is available in all of the aforementioned platforms.
(This is not really an "answer" - I just can't add comments yet because my reputation score isn't high enough yet.)
I think your general approach is fine - essentially you are making a GUI generator for SQL. However a few things:
This type of feature is best suited for a warehouse or read only replica database. Do not build this on a live production transactional database. There are permutations that you haven't thought of that your users will find that will kill your database (it's also true from a warehouse standpoint, but they usually don't have response time expectations as a transactional database)
The method you described for doing paging is not efficient from a database standpoint. You are essentially querying, filtering, grouping, and sorting the same exact dataset multiple times just to cherry pick a few rows each time. If you have the data cached, that might be ok, but you shouldn't make that assumption. If you have the know how, figure out how to snapshot the entire final data set with an extra column to keep the data physically sorted in the order the user requested. That way you can quickly query the results for your paging.
If you have a Repository/DAL layer, design your solution so that in the future certain combinations of tables/columns can utilize hardcoded queries/stored procedures. There will inevitably be certain queries that pop up that cause you performance issues and you may have to build a custom solution for specific queries in order to get the desired performance that can't be obtained by your dynamic sql

How do a handle a database with over 100 tables

I have a database with over a 100 tables, 30 of them are lookup tables with lookup Language tables. each table links back to one or three tables. but there are around 20 different web forms that needs to interlink for a registered user.
My question is, do i create one connection string with one Model, or do i break them up into individual models?
I've tried the breaking up into individual models based on the page that they are required for, but this just throws up validation and reference errors looking for the same field.
I don't have any errors to show at the moment, but i can provide if necessary.
Sounds like you need to create some views so that you can consolidate the queries coming from the database. Try to think of logical groupings of the tables (lookup and otherwise) that you have and create a view for each logical grouping. Then, have your application query against those views to retrieve data.
As for connection strings, I don't see why you would need more than one if all of the tables are in the same database.
If you have the possibility to create only one connection string, that is what you should do.
When you create a second connection string, it's because you have no choice. Having many different connections strings is just going to add to the confusion you migth already be in.
The number of tables you have in a data base is never going to influence how many connection string you should have. I would even say : having acces to all the information of your database through one single object is an advantage. Now, the way you are going to organise the impressive amount of informations is crucial, and there is a lot of way to accomplish that. You need to find out yours.

Mutually exclusive facts. Should I create a new dimention in this case?

There is a star schema that contains 3 dimensions (Distributor, Brand, SaleDate) and a fact table with two fact columns: SalesAmountB measured in boxes as the integer type and SalesAmountH measured in hectolitres as the numeric type. The end user wants to select which fact to show in a report. The report is going to be presented via SharePoint 2010 PPS.
So help me please determine which variant is suitable for me the most:
1) Add a new dimension like "Units" with two values Boxes, Hectolitres and use the in-built filter for this dim. (The fact data types are incompatible though)
2) Make two separate tables for the two facts and build two cubes. Then select either as the datasource.
3) Leave the model as it is and use the PPS API in SharePoint to select the fact to show.
So any ideas?
I think the best way to implement this is by using separate field for SalesAmountB and SalesAmountH in fact table. Then creating 2 separate measure in BIDS and controlling the visibility through MDX. By doing this, you can avoid complexity of duplicating whole data or even creating separate cubes.

How to store data related to members of groups in a forum, using Cassandra?

Hii there,
My question is related to Groups in a forum, very much similar to the LinkedIn Groups.
How would you store the list of all users in a group in a discussion forum?...and when the size of groups are quite large like in tens of thousands members in a group ?
Also how can you find the mutual connections of the user in that group ?
I suggest doing this as one row per group, with a column for each member of the group. This will work well for any number of users in the group.
Regarding finding "mutual connections", the simplest way to handle this is to scan through the second user's connections and compare the two.
Here's an alternate strategy: assume that we want to find all of the mutual connections for user 'A' in group 'G'. If the columns in the A's connection row use the connections' usernames (or user ids) as the the column names, you can do (in pycassa syntax):
group_members = GROUPS.get('G').keys()
group_members.remove('A')
user_connections = USERS.get('A').keys()
mutual_connections = USERS.multiget(group_members, columns=connections)
Basically, this will go to a row for each user in the group and pull out only the columns that correspond to the original user's connections. This will move the work from the client to Cassandra, but it's hard to tell how much extra work this would be for Cassandra without a performance test.

Is it possible to LDAP query users common to a set of groups

I need a list of all the users common to a known collection of groups, using a single LDAP query of our Active Directory. It would seem, from the our reading so far, that such is not possible, but I thought it best to ask the hive mind.
Try this:
(&(objectCategory=Person)
(&
(memberOf=CN=group1,dc=company,dc=local)
(memberOf=CN=group2,dc=company,dc=local)
(memberOf=CN=group3,dc=company,dc=local)
)
)
This is similar to my question, except there I wanted all users who were NOT members of groups. You'll need to delete all the whitespace for most query tools to work.
Yes it's possible with an attribute scoped query. It requires W2K3 AD or later but will give you the all of the users that have a particular attribue i.e. membership in a group or in your case multiple groups (intersection of groups). One of the best examples is from Joe Kaplan and Ryan Dunns book "The .NET Developers Guide to Directory Services Programming" for AD work it's hard to beat look at page 179 for a good walk through.
Caveat:At this point you are past trivial searches in AD and a number of things are becoming important like the search root, scope and the effect of searching through some potentially HUGE set of data for the items you want. Looking through 50 or 60K users to find the members of a group does have an effect on performance and be prepared to do paged results or similar in case the dataset is large. Kaplan/Ryan do an excellent job of down to earth work to get you where you need to be. That said, I have used them on two AD projects with great success. Being able retrieve the data from AD without recursive queries is VERY worth while and I found that it is fast as long as I control the size of my dataset.
It's not possible in a single query if your groups contain nested groups.
You would need to write some code that recursively resolves the group members and does the logical equivalent of an "inner join" on the results, producing a list of users that are common to all the original groups.

Resources