Forking an existing gitlab project under my user namespace with the same group name as the original repo - gitlab

How could I fork an existing gitlab project which exists at: https://gitlab.com/organisation/custom-group/custom-project under my own user namespace: https://gitlab.com/my-user/custom-group/custom-projet ?
Because here https://gitlab.com/groups/new#create-group-pane it's not possible to create a group in my own namespace, e.g. it will necessarily be created at https://gitlab.com/custom-group whereas I want it under https://gitlab.com/my-user/custom-group
On the other hand, if I click on the fork button in the original organization repository, there is no option to create a sub-group in my own namespace at this stage:
https://gitlab.com/organisation/custom-group/custom-project/-/forks/new
so this will create https://gitlab.com/my-user/custom-project instead of https://gitlab.com/my-user/custom-group/custom-project
I certainly missed something really obvious but it has been 2h that I'm losing myself in the documentation without finding anything relevant to solve this "problem".

I hate to say, what you're looking for is just not possible.
As you noticed, it's not possible to create groups "inside" of your username path. This is because your user's namespace and a group namespace work differently.
The namespaces documentation explicitly states this:
You cannot create subgroups in a personal namespace.
The only way to get the path you're looking for would be to change your username and create a group with your "old" username, because namespace paths are unique across both personal and group namespaces. Meaning, you cannot create a group with my-user path to get gitlab.com/my-user since it's taken by your user.
So if you're willing to give up my-user as your username, then you would:
Change your username to something else.
Create a group with the path my-user.
Create a subgroup in my-user group to get my-user/custom-group.

Related

Get all groups where a user is member of in LDAP

I'm using ApacheDS as directory server which is used in applications like Gogs (Git server like GitLab). My idea is to create groups like gogs-users and restrict the login to those group, so that only users who are member of that group are able to login. I have created a groupOfNames for this and a testuser, which is added to the gogs group.
The type of gogs-users is groupOfNames and it has an attribute member which contains the DN of my user (uid=testuser,ou=Users,DC=example,DC=com). So I'm able to see, who is a member of this group.
But I would like to see all groups where a user is a member of. When I open the testuser, I see no attribute that could tell me, that he's a member of gogs-users. I remember that the proprietary Active Directory had an attribute called memberOf whch was queryable in a filter like (&(objectClass=inetOrgPerson)(memberOf=CN=gogs-user,DC=example,DC=com)). That would be exactly what I need.
How can I get this in a free LDAP implementation? I see no way except defining a custom attribute - Which I had to maintenant per hand. That's not good, I would like to have an automated solution, that keep care of those attribute.
Things I already tried
https://stackoverflow.com/a/34502363/3276634 No changes
https://morenews.blogspot.de/2010/12/adding-active-directory-properties-to.html No changes, too
Note: I did a complete reset after each scheme import, to make sure, that my tests are not influenced by previous changes.
Here are Queries that will go either way but ONLY work for Microsoft Active Directory:
Resolves all members (including nested) Security Groups (requires at least Windows 2003 SP2):
(memberOf:1.2.840.113556.1.4.1941:=CN=gogs-user,DC=example,DC=com)
And
All Groups a User is a member of including Nested Groups
(member:1.2.840.113556.1.4.1941:=CN=UserName,CN=Users,DC=YOURDOMAIN,DC=NET))

grant User permissions based on ldap groups

We are running GitLab EE Version 8.17.0-ee. To manage the amount of Users, we want to add and administrate them via ldap groups. We know that there are some ldap settings in the gitlab.rb file. We can definde a user base and also a admin group at
gitlab_rails['ldap_servers'] = ...
[...]
#     ## EE only
#     group_base: ''
#     admin_group: ''
#     sync_ssh_keys: false
#
But we miss the option to define user groups which we can use to automatically give permissions after those users are assignet to specific groups/projects.
Seen in this video there was a feature called Linked LDAP Groups. But in the newest version I cant find it. Is there any other way to configure GitLab to perform this?
I think I found an possible answer to my question. We forgot to set the group_base in the gitlab.yml file. link

How to restrict user to access only his group elements in Loopback?

I was trying to find it in docs or anywhere on the web but I did not find.
What I am asking about?
I am building website for multiple users. Frontend is not important, back backend API is being build in Loopback.
Every user will be assigned to some, let's name it GROUP.
Group content will be then exposed on subdomain but it is not important now.
Users will be kind of admins of their group.
I will have plenty of different models, but I will always have to protect user from accessing elements which not belongs to his group.
How should I do it? I think it will be some middleware but I do not know how to do it properly.
Of course, every user and every element have field "group_id".
I am also trying to find a good solution... I did find this npm package that looks worth a try: https://www.npmjs.com/package/loopback-component-access-groups
Here is a short description of what the package is used for:
"This loopback component enables you to add multi-tenant style access controls to a loopback application. It enables you to restrict access to model data based on a user's roles within a specific context."
I'm struggeling with the same problem, and I did not yet find a satisfatory response.
My workaround is explained in this question. I've got my user ID and with this, I retrieve the data I need to restrict the access. Then I alter the query in accordance with fetched data.

perforce server settings

Is it possible to set the Perforce server to by default don't let the users check out a directory, instead of letting everybody update their view-spec to exclude that directory?
Eg: if you would like to check out //code/heavy/stuff you must explicitly add that directory to your view-spec instead of adding a -//code/heavy/stuff yo your spec.
You can install a trigger on the server that generates the default clientspec for a user. With this flexible tool, you can achieve a number of designs. The idea is that when a user creates a new clientspec, the server would fill it in with something other than the default //depot/... mapping for each depot.
One simple idea would be to define the default clientspec to include -//code/heavy/stuff mapping automatically.
Another more advanced idea would be to check to see what groups the user is a member of, and then auto-generate a clientspec appropriate for that user based on his group membership.
If you just want to block people from getting it, then it might be possible with permission mapping.
But then they would never by able to access it, even if they change their client spec.
Maybe you need to (re-)structure your repository so that the heavy part isn't in most users' client specs.

Authorization System Design Question

I'm trying to come up with a good way to do authentication and authorization. Here is what I have. Comments are welcome and what I am hoping for.
I have php on a mac server.
I have Microsoft AD for user accounts.
I am using LDAP to query the AD when the user logs in to the Intranet.
My design question concerns what to do with that AD information. It was suggested by a co-worker to use a naming convention in the AD to avoid an intermediary database. For example, I have a webpage, personnel_payroll.php. I get the url and with the URL and the AD user query the AD for the group personnel_payroll. If the logged in user is in that group they are authorized to view the page. I would have to have a group for every page or at least user domain users for the generic authentication.
It gets more tricky with controls on a page. For example, say there is a button on a page or a grid, only managers can see this. I would need personnel_payroll_myButton as a group in my AD. If the user is in that group, they get the button. I could have many groups if a page had several different levels of authorizations.
Yes, my AD would be huge, but if I don't do this something else will, whether it is MySQL (or some other db), a text file, the httpd.conf, etc.
I would have a generic php funciton IsAuthorized for the various items that passes the url or control name and the authenticated user.
Is there something inherently wrong with using a naming convention for security like this and using the AD as that repository? I have to keep is somewhere. Why not AD?
Thank you for comments.
EDIT: Do you think this scheme would result in super slow pages because of the LDAP calls?
EDIT: I cannot be the first person to ever think of this. Any thoughts on this are appreciated.
EDIT: Thank you to everyone. I am sorry that I could not give you all more points for answering. I had to choose one.
I wonder if there might be a different way of expressing and storing the permissions that would work more cleanly and efficiently.
Most applications are divided into functional areas or roles, and permissions are assigned based on those [broad] areas, as opposed to per-page permissions. So for example, you might have permissions like:
UseApplication
CreateUser
ResetOtherUserPassword
ViewPayrollData
ModifyPayrollData
Or with roles, you could have:
ApplicationUser
ApplicationAdmin
PayrollAdmin
It is likely that the roles (and possibly the per-functionality permissions) may already map to data stored in Active Directory, such as existing AD Groups/Roles. And if it doesn't, it will still be a lot easier to maintain than per-page permissions. The permissions can be maintained as user groups (a user is either in a group, so has the permission, or isn't), or alternately as a custom attribute:
dn: cn=John Doe,dc=example,dc=com
objectClass: top
objectClass: person
objectClass: webAppUser
cn: John Doe
givenName: John
...
myApplicationPermission: UseApplication
myApplicationPermission: ViewPayrollData
This has the advantage that the schema changes are minimal. If you use groups, AD (and every other LDAP server on the planet) already has that functionality, and if you use a custom attribute like this, only a single attribute (and presumably an objectClass, webAppUser in the above example) would need to be added.
Next, you need to decide how to use the data. One possibility would be to check the user's permissions (find out what groups they are in, or what permissions they have been granted) when they log in and store them on the webserver-side in their session. This has the problem that permissions changes only take effect at user-login time and not immediately. If you don't expect permissions to change very often (or while a user is concurrently using the system) this is probably a reasonable way to go. There are variations of this, such as reloading the user's permissions after a certain amount of time has elapsed.
Another possibility, but with more serious (negative) performance implications is to check permissions as needed. In this case you end up hitting the AD server more frequently, causing increased load (both on the web server and AD server), increased network traffic, and higher latency/request times. But you can be sure that the permissions are always up-to-date.
If you still think that it would be useful to have individual pages and buttons names as part of the permissions check, you could have a global "map" of page/button => permission, and do all of your permissions lookups through that. Something (completely un-tested, and mostly pseudocode):
$permMap = array(
"personnel_payroll" => "ViewPayroll",
"personnel_payroll_myButton" => "EditPayroll",
...
);
function check_permission($elementName) {
$permissionName = $permMap[$elementName];
return isUserInLdapGroup($user,$permissionName);
}
The idea of using AD for permissions isn't flawed unless your AD can't scale. If using a local database would be faster/more reliable/flexible, then use that.
Using the naming convention for finding the correct security roles is pretty fragile, though. You will inevitably run into situations where your natural mapping doesn't correspond to the real mapping. Silly things like you want the URL to be "finbiz", but its already in AD as "business-finance" - do you duplicate the group and keep them synchronized, or do you do the remapping within your application...? Sometimes its as simple as "FinBiz" vs "finbiz".
IMO, its best to avoid that sort of problem to begin with, e.g, use group "185" instead of "finbiz" or "business-finance", or some other key that you have more control over.
Regardless of how your getting your permissions, if end up having to cache it, you'll have to deal with stale cache data.
If you have to use ldap, it would make more sense to create a permissions ou (or whatever the AD equivalent of "schema" is) so that you can map arbitrary entities to those permissions. Cache that data, and you should ok.
Edit:
Part of the question seems to be to avoid an intermediary database - why not make the intermediary the primary? Sync the local permissions database to AD regularly (via a hook or polling), and you can avoid two important issues 1) fragile naming convention, 2) external datasource going down.
You will have very slow pages this way (it sounds to me like you'll be re-querying AD LDAP every time a user navigates to figure out what he can do), unless you implement caching of some kind, but then you may run into volatile permission issues (revoked/added permissions on AD while you didn't know about it).
I'd keep permissions and such separate and not use AD as the repository to manage your application specific authorization. Instead use a separate storage provider which will be much easier to maintain and extend as necessary.
Is there something inherently wrong with using a naming convention for security like
this and using the AD as that repository? I have to keep is somewhere. Why not AD?
Logically, using groups for authorization in LDAP/AD is just what it was designed for. An LDAP query of a specific user should be reasonably fast.
In practice, AD can be very unpredictable about how long data changes take to replicate between servers. If someday your app ends up in a big forest with domain controllers distributed all over the continent, you will really regret putting fine-grained data into there. Seriously, it can take an hour for that stuff to replicate for some customers I've worked with. Mysterious situations arise where things magically start working after servers are rebooted and the like.
It's fine to use a directory for 'myapp-users', 'managers', 'payroll' type groups. Try to avoid repeated and wasteful LDAP lookups.
If you were on Windows, one possibility is to create a little file on the local disk for each authorized item. This gives you 'securable objects'. Your app can then impersonate the user and try to open the file. This leverages MS's big investment over the years on optimizing this stuff. Maybe you can do this on the Mac somehow.
Also, check out Apache's mod_auth_ldap. It is said to support "Complex authorization policies can be implemented by representing the policy with LDAP filters."
I don't know what your app does that it doesn't use some kind of database for stuff. Good for you for not taking the easy way out! Here's where a flat text file with JSON can go a long way.
It seems what you're describing is an Access Control List (ACL) to accompany authentication, since you're going beyond 'groups' to specific actions within that group. To create an ACL without a database separate from your authentication means, I'd suggest taking a look at the Zend Framework for PHP, specifically the ACL module.
In your AD settings, assign users to groups (you mention "managers", you'd likely have "users", "administrators", possibly some department-specific groups, and a generic "public" if a user is not part of a group). The Zend ACL module allows you to define "resources" (correlating to page names in your example), and 'actions' within those resources. These are then saved in the session as an object that can be referred to to determine if a user has access. For example:
<?php
$acl = new Zend_Acl();
$acl->addRole(new Zend_Acl_Role('public'));
$acl->addRole(new Zend_Acl_Role('users'));
$acl->addRole(new Zend_Acl_Role('manager'), 'users');
$acl->add(new Zend_Acl_Resource('about')); // Public 'about us' page
$acl->add(new Zend_Acl_Resource('personnel_payroll')); // Payroll page from original post
$acl->allow('users', null, 'view'); // 'users' can view all pages
$acl->allow('public', 'about', 'view'); // 'public' can only view about page
$acl->allow('managers', 'personnel_payroll', 'edit'); // 'managers' can edit the personnel_payroll page, and can view it since they inherit permissions of the 'users' group
// Query the ACL:
echo $acl->isAllowed('public', 'personnel_payroll', 'view') ? "allowed" : "denied"; // denied
echo $acl->isAllowed('users', 'personnel_payroll', 'view') ? "allowed" : "denied"; // allowed
echo $acl->isAllowed('users', 'personnel_payroll', 'edit') ? "allowed" : "denied"; // denied
echo $acl->isAllowed('managers', 'personnel_payroll', 'edit') ? "allowed" : "denied"; // allowed
?>
The benefit to separating the ACL from the AD would be that as the code changes (and what "actions" are possible within the various areas), granting access to them is in the same location, rather than having to administrate the AD server to make the change. And you're using an existing (stable) framework so you don't have to reinvent the wheel with your own isAuthorized function.

Resources