Get Website Permission with Powershell - powershell

I am trying to figure out how to get the well known Website Permission Lists with Powershell. I tried several methods. The best solution seems to me to try something like $spWeb.RoleAssignments but this delivers me not only the users and groups with ist permissions on the spweb. I also get the roleassignments from the unique lists and libraries on the website.
Do you have suggestions how can I filter to check if a user has, for example, read permission on the spweb (without regarding the lists and subwebs)?
My target is to check the spweb and ist subwebs and unique lists and libraries step by step for a user(group) like "NT AUTHORITY\Authenticated Users". Then I want to remove the roleassignment and add a new roleassignment with a group of my colleagues, so that not everybody can see the content. The uniqe permission structure should remain.

You could check if a user has specific permission level using SPWeb.DoesUserHavePermissions method:
public bool DoesUserHavePermissions(
string login,
SPBasePermissions permissionMask
)
SPWeb.DoesUserHavePermissions method (String, SPBasePermissions)
using (SPSite site = new SPSite("http://sp/"))
{
using (SPWeb web = site.OpenWeb())
{
// Make sure the current user can enumerate permissions.
if (web.DoesUserHavePermissions(SPBasePermissions.EnumeratePermissions))
{
// Specify the permission to check.
SPBasePermissions permissionToCheck = SPBasePermissions.ViewListItems;
Console.WriteLine("The following users have {0} permission:", permissionToCheck);
// Check the permissions of users who are explicitly assigned permissions.
SPUserCollection users = web.Users;
foreach (SPUser user in users)
{
string login = user.LoginName;
if (web.DoesUserHavePermissions(login, permissionToCheck))
{
Console.WriteLine(login);
}
}
}
}
}
Console.ReadLine();

Related

Get user's AD role without using Remote Server Administration Tools

I'm trying to write a powershell command that checks to see if a user is part of an AD Group, however, I don't want to use the RSAT modules, as this may end up being a logon script (and we don't want users having those modules installed). This did lead me to this question, Search AD with PowerShell without using AD module (RSAT), however, I can't figure out how to filter the results check it the value is in there.
For example, the below does return a list of users, in LDAP form, for the group IT, but how do I then check a specific user (with their Username, not display name) is in there?
([System.DirectoryServices.DirectorySearcher]"(&(objectCategory=group)(name=IT))").FindOne().Properties["Member"]
FindOne() despite what it says as well, returns multiple rows; in fact FindAll() and FindOne() both return the same results.
Should I be using a different command to search AD? Specifically I want to either check an AD group contains a user (the current user), or the inverse, check a user (the current user) is a member of a particular AD group.
You can do it that way if you really need to (and I can help you do it that way if you really need) but if you are going to be running this script under the credentials of the user you are interested in, then you can get all the groups from the user's login token. That already contains a recursive list of all security groups that the user is in. (It won't include groups where the 'Group type' is "Distribution")
The login token contains a list of SIDs, so the absolute fastest way is to compare using the SID of the group you are interested in, since it won't have to make any network request at all. That's especially convenient for laptop users who may not be online when they login - your script would still work.
$currentIdentity = [Security.Principal.WindowsIdentity]::GetCurrent()
if ($currentIdentity.Groups.Where({$_.Value -eq "S-1-1-0"}, "First")) { #Is in "Everyone"?
"Yes"
} else {
"No"
}
To find the SID of a group, use this:
(Get-ADGroup "GroupName").SID.Value
Then copy/paste that value into the script.
If you would prefer to use the name of the group in the script, then you can convert it to a WindowsPrincipal and use IsInRole. However, this will need to make a network request to find the group by its name.
$currentIdentity = [Security.Principal.WindowsIdentity]::GetCurrent()
$currentPrincipal = New-Object System.Security.Principal.WindowsPrincipal($currentIdentity)
if ($currentPrincipal.IsInRole("Everyone")) {
"Yes"
} else {
"No"
}

Backend access rights for news records

Is it possible to store all records of the news extension (ext:news) on the same storage page, but show only records, which are created by the loggedin backend user?
So the current backend user can just see and edit his own records? Admins should see all records of course.
No, this is not possible, since backend user permissions on record level are not implemented in TYPO3.
So you either have to separate the news records of the users in separate sysfolders or you could try to use hooks (e.g. $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['typo3/class.db_list_extra.inc']['getTable']) or XClass to customize TYPO3 backend to your needs. I do not recommend the latter, since the TYPO3 backend permission system is complex and you would need to make sure to restrict record access in several parts of TYPO3 (e.g. recordlist, element browser, related news field, ...)
There are two ways to archive that:
If the backend user is not too much. You can just create a page(type
is folder) named with the backend user name. And in the backend user
module you can set the permission(Not for the group user but for the
single backend user only).
if the backend user is too much. and You just wanna set permissions for the group and all backend users are sharing the same rules. You can refer to Hook:https://docs.typo3.org/p/georgringer/news/main/en-us/Tutorials/ExtendNews/Hooks/Index.html so that the basic logic is like this:
2.1 get current logged-in user group.
2.2 if the group is Reporter, we can use the hook for the listing page:
$constraints[] = $query->equals('cruser_id', $be_id);
Edit(3/3/2022):
Hi Chris, Yes you are right.
Today, I have got a chance to dig into the news extension. I think we can still make it by the hook
in your ext_localconf.php
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS'][\TYPO3\CMS\Recordlist\RecordList\DatabaseRecordList::class]['modifyQuery'][$_EXTKEY]
= \T3docs\SitePackage\Hooks\DatabaseRecordListHook::class;
(Please make sure the namespace is correct)
within the file : T3docs\SitePackage\Hooks\DatabaseRecordListHook.Create a function named modifyQuery:
public function modifyQuery($parameters,
$table,
$pageId,
$additionalConstraints,
$fields,
$queryBuilder)
{
if ($table === 'tx_news_domain_model_news') {
$tsconfig = $GLOBALS['BE_USER']->getTSConfig();
if (!empty($tsconfig['options.']['be_users'])) {
$be_users = $tsconfig['options.']['be_users'];
$queryBuilder->andWhere('cruser_id IN (' . $be_users . ')');
}
}
return $queryBuilder;
}
in the user Options tab set Tsconfg : options.be_users = 3,100
(3,100 is the be_user id. And the 2 two backend users's news will show up)
thus, it works for me.

Entity framework - Avoid circular Relationship in serialization

I have two tables : Users & Profiles. A user has one profile (1:1), a profile can be affected to many users, each profile has many modules, each module has many actions.
I'm sending this object from an asmx to a aspx page using a direct service call.
I got an error because of lazy loading ... so I disabled the lazy loading.
this.Configuration.LazyLoadingEnabled = false;
this works fine, I got my user, with the profile null.
To build the menu tree I have to retrieve the profile. I included It :
User user = new User();
using (cduContext db = new cduContext())
{
// get the user
string encryptedPassword = Encryption.Encrypt(password);
user = (from u in db.Users
where u.UserName.Equals(login) &&
u.Password.Equals(encryptedPassword)
select u).FirstOrDefault();
// Include the users profile
user = db.Users.Include("Profile").FirstOrDefault();
}
return user;
I got this error in the javascript call function :
A circular reference was detected while serializing an object of type 'CDU.Entities.Models.User'.
When I made a quick watch on the user object, in asmx ( before sending it ) , I found, that the profile has included the list of the users who had this pofile, each user has his profile loaded ... etc
Any idea please ?
Note, your code should look like this:
using (cduContext db = new cduContext())
{
// get the user
string encryptedPassword = Encryption.Encrypt(password);
var user = from u in db.Users
where u.UserName.Equals(login) &&
u.Password.Equals(encryptedPassword)
select u;
// Include the users profile
return user.Include("Profile").FirstOrDefault();
}
In your code, you were throwing away the first query by overwriting it with the second. And there was no valid reason to create a blank user.
To address your problem, you're going to have make a decision on what you don't want to serialize. In your case, you probably don't want to serialize Profile.Users
You don't mention what serializer you're using. I'm assuming you're using the DataContract serializer?
EDIT:
You would mark your Profile.Users object with the [IgnoreDataMember] Attribute.

facebook graph api check if user is a member of a group using PHP

i want to check if a user is a member of a group using facebook graph api...
i have this:
$group = file_get_contents("https://graph.facebook.com/177129325652421/members?access_token=XXXXXXXX");
$group = json_decode($group);
$checkuser = $group->data;
and check the user if is a member by using his facebook id and in_array()
if(in_array($_GET["fid"],$checkuser)){
echo "yes";
} else {
echo "no";
}
can someone help me to correct this please... my code is not working...
Reference: https://developers.facebook.com/docs/reference/api/
Use the API url:
https://graph.facebook.com/me/groups
To get a user's groups. In the above link, change the me/ to the user's FB ID. You must also pass in an Access Token.
The reply will be JSON encoded. Decode it using json_decode to a PHP Associative array. Iterate over it and check for the group you want.
The Graph API does not return all groups at once. You must either use the pagination links at the end of each response to fetch more, or use the limit parameter to request as many as you need.
The following code sample will post the IDs of the Groups you are a part of
<?php
$url = "https://graph.facebook.com/me/groups?access_token=AAAAAAITEghMBAMDc6iLFRSlVZCoWR0W3xVpEl1v7ZAxJRI3nh6X2GH0ZBDlrNMxupHXWfW5Tdy0jsrITfwnyfMhv2pNgXsVKkhHRoZC6dAZDZD";
$response = file_get_contents($url);
$obj = json_decode($response);
foreach($obj->data as $value) {
echo $value->id;
echo '<br>';
}
/* to check for existence of a particular group
foreach($obj->data as $value) {
if ($value->id == $yourID) {
//found
break;
}
//not found. fetch next page of groups
}
*/
PS - If running the above code gives you an error stating Could not find wrapper for "https", you need to uncomment/add the PHP extension extension=php_openssl.dll
Was looking into this and found this as first answer in google but the answer seems to be much of a hassle so I dug a bit deeper.
The fastest answer I've found which doesn't require iterating through all of the groups' members uses FQL.
SELECT gid, uid FROM group_member WHERE uid = (user id) AND gid = (group id)
This either returns an empty 'data' object, or a 'data' object with the UID and GID.
It also (from what I see so far) , doesn't require the user_groups permission.
https://developers.facebook.com/tools/explorer?fql=SELECT%20gid%2C%20uid%20FROM%20group_member%20WHERE%20uid%20%3D%20551549780%20AND%20gid%20%3D%20282374058542158
This FQL query returns for me:
{
"data": [
{
"gid": "282374058542158",
"uid": "551549780"
}
]
}
This doesn't seem to be possible after Graph API v2.4, because Facebook decided to disallow it:
https://developers.facebook.com/docs/apps/changelog#v2_4
"the user_groups permission has been deprecated. Developers may continue to use the user_managed_groups permission to access the groups a person is the administrator of. This information is still accessed via the /v2.4/{user_id}/groups edge which is still available in v2.4."
It also states "From October 6, 2015 onwards, in all previous API versions, these endpoints will return empty arrays." But it seems to me that it still works on v2.2 & v2.3.

Modifying permissions on files/items in version control using TFS API

Using the TFS API, I need to change permissions on a specified file/item in version control. I need to edit permissions for a particular user or for all users.
For instance, my app will prevent check-in of a specified file for all users. Then, it would allow check-in of that file for a particular user, perform check in of the file, then allow check-in again for all users.
How can I do this? Please provide example code.
With guidance from Vicky Song at Microsoft (http://social.msdn.microsoft.com/Forums/en-US/tfsversioncontrol/thread/289fb1f4-4052-41f1-b2bf-f97cd6d9e389/), here is what I ended up with:
public void SetCheckInLockForFile(string fileAndPath, string userGroup, bool checkInLock)
{
// sets of the CheckIn permission for the specified file
List<SecurityChange> changes = new List<SecurityChange>();
string[] perm = new string[] { PermissionChange.ItemPermissionCheckin };
if (checkInLock)
changes.Add(new PermissionChange(fileAndPath, userGroup, null, perm, null));
else
changes.Add(new PermissionChange(fileAndPath, userGroup, null, null, perm));
SecurityChange[] actualChanges = versionControlServer.SetPermissions(changes.ToArray());
}
When CheckInLock is true, a deny permission is added for check in. When CheckInLock is false, the check in permission is removed, allowing check in permission for the specified file to be inherited.