Auth API

Submit modules/packages for inclusion with Source.Python.
Omega_K2
Senior Member
Posts: 227
Joined: Sat Jul 07, 2012 3:05 am
Location: Europe
Contact:

Auth API

Postby Omega_K2 » Thu Jul 19, 2012 3:25 am

I think an API should be planned carefully since once it's done, we probably have a bunch of addons using it; I think it is quite fundamental to have a shared/common API that scripters/coders can use without worrying about how the authorization is done exactly.

So basically, I think the 3-way system is a good start. We have a general API (the auth API), that both auth providers and auth consumer use. So for each part, the goals are probably sightly different:

Auth Provider API:

Goals/ideas:

  1. support for multiple auth providers at once
  2. support complex auth providers as well as simple ones (group/flag/permission based auth should be supported)
  3. support for different auth methods (steamid, name, ip, passwords etc.)

Implementation

1. Multiple auth support:

Probably a listener-style way of adding auth could work well. So, when the Cusomer API function X is called, it is validated against all authproviders - I suppose it makes sense that the user is "authenticated" if one of the providers return True for the checked permission.

2. Supporting complex auth methods:

One approach to solve this problem is to provide general functions - as the actual permissions/flags/groups are going to differ on each authprovider, the providers could just check for each permission internally; so if we have a simple auth provider that only checks for ID, it will return True in any case, however, with a more complex provider it checks against any flag.

Something else to think about is whether it makes sense to provide default-API flags; Sourcemod for example has a pretty complex system regarding the flags and so on - if some scripters intend it to be more specifically for sm, they'll use that group and other scripts may have similar groups but with a different name (so they won't get recognized). A solution could be to provide a bunch of predefined flags /groups/permissions that custom providers can just override if they have a similar function; however, this may lead that the API becomes quite large (and possibly 'bloated') and that it has some 'features' that are barly used by any auth provider.

3. Support for multiple auth methods:

I think a decent approch here is too loop though all registered auth methods for each auth provider until one returns True. If they are not implemented, they just return False with no extra work.
For custom auth methods that are not used in the default, there could be a method to add them to the internal list.
On the Consumer API side everything should require as little work as possible - possibly all that is done is giving a userid (and then these checks will be automatically done - including the retrieval)

Auth Consumer API:

Goals/ideas:

  1. simple to use (single function)
  2. access to complex auth mechanisms

1. simpilcity

Access could be done though a user specific class that just uses the userid parameter for the constructor and specific methods for checking access. For example, it could be something like Auth(userid).IsAuthed()

2. access to complex methods

Using the approch above it could be rather simple; for example it could be something like Auth(userid).InGroup('admin') and Auth(userid).HasPessmission('be_awesome')



Looking forward to comments & ideas. I would be up for writing this API :)


(Note: Also see http://www.sourcepython.com/forums/showthread.php?13-Admin-System )



Alpha/Prototype auth API + Simple Auth Provider + Test Script
auth/__init__.py
auth/consumer.py
auth/provider.py
Simple Auth Provider
Test Script

EDIT: Of course you have the permission to include any of this in SP under the GPL
User avatar
satoon101
Project Leader
Posts: 2290
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Thu Jul 19, 2012 3:57 am

I'm up for you writing this API as well. I definitely want "one" overall system that encompasses everything and is easy to use on both ends. Give it a go, and show us what you can come up with :) . I do not have time right now to read over all your points, so I'll save any specific reply for when I do (likely tomorrow night).

Satoon
User avatar
ashbash1987
Developer
Posts: 20
Joined: Tue Jul 10, 2012 12:01 pm
Location: Sheffield, UK
Contact:

Postby ashbash1987 » Thu Jul 19, 2012 7:47 am

I'll just leave this here from what I've used in the past with Drupal 7 (website CMS) which I seemed to like a bit. It's just an idea and worth throwing out there for brainstorming with.

Each and every user can belong to 1 or more groups, and each group has a set of flags enabled/disabled, which are then checked by a method user_access('permission_name', $uid), which returns TRUE if the user belongs to a group with the permission 'permission_name' set to TRUE. Modules in Drupal can provide their own permissions and IDs, so separate addons don't have to *rely* on specific flags on existing ahead of time (or in Sourcemod, where there seems to be a limited number of flags available???), unless they obviously require an existing module to work with.

(There are also additional Drupal modules that extend this functionality by allowing per-user permission flags, rather than per-group, and other such modules.)

The only problem with this idea in a Drupal world is that a site installation can have more than 50+ modules installed and running, meaning that the permission list can be extraneously long. Drupal tried to remedy this issue in part by allowing the modules defining permissions to also define if the permission should be automatically awarded to the default Administrator group (btw, there are 2 other default required groups: Guests and Authenticated Users, where Authenticated Users in this case means a logged-in user on the website). Whereas in a Source server world, there won't be nearly as many addons running on one server I would imagine, and so the permissions list shouldn't be nearly as exhaustive.
User avatar
BackRaw
Senior Member
Posts: 413
Joined: Sun Jul 15, 2012 1:46 am
Location: Germany

Postby BackRaw » Thu Jul 19, 2012 12:51 pm

I like those ideas very much. Go for it Satoon! :D
Omega_K2
Senior Member
Posts: 227
Joined: Sat Jul 07, 2012 3:05 am
Location: Europe
Contact:

Postby Omega_K2 » Fri Jul 20, 2012 11:36 pm

Alpha/Prototype auth API:

Auth API
Simple Auth Provider
Test Script

Note that it isn't complete and I see quite a lot of room for improvement (redundant methods, adding a cache, refreshing priviledges is not completly implemented etc - also read the comments in the file).

(Or in other words, this is just something to base discussions on and open for a lot of changes, before it is even submitted for inclusion :P)
User avatar
satoon101
Project Leader
Posts: 2290
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Sat Jul 21, 2012 12:14 am

As with the logging, I will take a look at this when I actually get the chance. I would love to hear other opinions, though, so everyone feel free to post your thoughts.

Thank you,
Satoon
User avatar
DanielB
Junior Member
Posts: 4
Joined: Sat Jul 07, 2012 2:33 am
Location: Australia
Contact:

Postby DanielB » Sat Jul 21, 2012 4:40 am

Here's a simple sqlite3 auth module I wrote a little while ago for ideas. Here's how it works:
  • There are users, groups and permissions.
  • Permission are created as needed and can be applied to either users or groups.
  • Users can join any number of groups
  • Permissions on groups are always positive (Group HAS permission) [this avoids a user being in different groups that allow and deny]
  • Permissions on users may be either allow or deny (As there can be no conflict here)
  • Explicit permissions are always followed above implicit permissions, and user permissions before group permissions (more specific first)
  • All permissions, users and groups have an implicit level
  • If a user has no user-specific permissions or group-specific , implicit permissions are used
  • If their level is greater or equal to the permissions implicit level, the permission is allowed
  • Implicit level of 0 on a permission means public (always allow)


I haven't thoroughly tested it, and its a very simple implementation, but its only here for ideas/discussion. (there's no real API here - you're basically talking right at the database)
My thoughts are that you should be giving capabilities, not restricting them. This means nobody "Accidentally" gets capabilities and its very easy to set up.

attachment includes auth.py and auth.sql
Attachments
auth.zip
(2.12 KiB) Downloaded 43 times
User avatar
satoon101
Project Leader
Posts: 2290
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Tue Aug 07, 2012 4:37 am

I still have not had the chance to look over any of this, yet, unfortunately. However, this is obviously something we wish to be included, so I am moving it to the Module/Package Submission forum.

The only comment I have to make, currently, is that, just like the logging system, the server owners will select which Auth service they wish to use from within their ../cfg/source-python/core_settings.ini file (filename subject to change). They will only be able to load 1 Auth service, to avoid confusion, and will not be able to load a different one instead without shutting the server down. They will, however, be able to use a console command (name to be determined) to "refresh" their Authorization. When this command is used, the current Auth service will be wiped, and completely re-loaded, getting all new data. I guess we "could" also have a convar that stores the Auth service, and when it is changed, do pretty much the same thing by wiping the old Auth data, and loading in the new one. I will have to think that over more.

Also, as I stated somewhere, all Auth services should be located within the Auth module itself:

Code: Select all

../_libs/auth/services/simple.py
../_libs/auth/services/sql.py
We will use the name of the Auth provider to know which one is being loaded. If an invalid value is given in the .ini file, we will probably load simple by default, even if there are no values given for it. If we incorporate the console variable, and an invalid value is given, we will simply "silently" set it back to the current value.

As always, feel free to post your questions/comments/concerns.

Thanks,
Satoon
Omega_K2
Senior Member
Posts: 227
Joined: Sat Jul 07, 2012 3:05 am
Location: Europe
Contact:

Postby Omega_K2 » Wed Aug 08, 2012 2:40 pm

I don't like restricting people to 1 auth system. Real life scenario where is not desireable is a joint community for example, where you use a global admin system, and some people yet want local exceptions on their servers (especially if only a few people get access to global system for security reasons).

Another reason could be auth from different sources. For example, some may use some basic auth right now, but also want their forum admins to have access (if they have a steamid there), so that's again two sources for auth.


Anyway, I suppose they could go there aswell, though I like them more as 'scripts', because custom auth providers may come with their own translation/config files/libaries. But it won't be much of a difference, could just create a module there instead
(../_libs/auth/services/myauthprovider/__init__.py + more stuff)
User avatar
satoon101
Project Leader
Posts: 2290
Joined: Sat Jul 07, 2012 1:59 am

Postby satoon101 » Wed Aug 08, 2012 3:31 pm

Ok, we will allow multiple providers. The setting will now allow for commas to separate all Auth providers that should be loaded (which could look something like the following):

Code: Select all

[AUTH_SETTINGS]
Auth_Service = "simple,sql,sourcemod"


Custom Auth providers won't exactly be limited in any way by having to use the _libs/auth/services for their service. Though, as long as we load the providers like the current plan, we could always move them out of the main _libs/auth module and into their own, like ../addons/source-python/auth_providers/simple/simple.py.

Also, I do plan on adding a server command (possibly sp_auth_reload), that if no arguments are passed will refresh the data for all loaded Auth providers. If one or more arguments are provided, each will be checked to see if it is a loaded Auth service, and if so will be refreshed.

Satoon
Omega_K2
Senior Member
Posts: 227
Joined: Sat Jul 07, 2012 3:05 am
Location: Europe
Contact:

Postby Omega_K2 » Fri Aug 17, 2012 1:13 am

I'm still in the process of testing/finishing this, but I thought I'll leave this here:

auth/__init__.py
auth/consumer.py
auth/provider.py

Main changes: Added a cache (not fully functional as of now) to cache access, split it up in consumer and provider APIs and added special DENY attributes to deny access to a flag/permission completely.

Return to “Module/Package Submissions”

Who is online

Users browsing this forum: No registered users and 1 guest