So i have some hardcoded persmissions. Class "A" user can create roles and define access level for each module. When users tries to access a resource system checks if users should be able to read resource and if 'edit' controlls should be displayed.
I'm making a Laravel app, so I'm going to use this also in custom Route::filter.
What I was thinking of is adding $table->integer('resource_title') column to roles table, where:
0 - no access to resource
1 - user level access (read and/or basic functionality)
2 - manage level access (define/edit/delete classifiactors and/or entities)
What would pros do? This? Some extra pivot or $table->boolean('resource_title_access_level')?
For mor flexability you can define access not only for resource but on certain actions on it.
As many roles as u wish.
For example if we have forum:
post
post_edit_own
post_edit
post_delete_own
post_delete
thread_create
thread_edit_own
thread_edit
thread_delete
category_create
category_edit
category_merge
category_delete
You even can store all of user's permissions in ONE field of its table.
users.permissions BIGINT
For doing this you should store this perms in some config like "bitfields" (bad english)
$bf = [
post_create => 1,
post_edit_own => 2,
post_edit => 4,
post_delete_own => 8,
post_delete => 16,
thread_create => 32,
thread_edit_own => 64,
thread_edit => 128,
thread_delete => 256,
category_create => 512,
category_edit => 1024,
category_merge => 2048,
category_delete => 4096,
]
After that you can calculate any needed set of permissions in this manner:
function getPermsSet(array $permsToAdd = ['post_create', 'thread_create']) {
$permSet = 0;
foreach ($permsToAdd as $premission) {
$permSet += $bf[$premission];
}
return $permSet;
}
for example if you want to change user permissions.
"UPDATE users SET permissions = " . getPermSet([some permissions...]). " WHERE id = ?"
Check user accessabity is too easy:
function hasPermission($permission) {
return $this->permissions & $bf[$permission];
}
And use it like this:
if ($user->hasPermission('post_edit') OR
$user->hasPermission('post_edit_own') AND $post->author->id == $user->id
) {
//do things related to post-edition
}
To get users with some permission you can use this
"SELECT * FROM users WHERE permissions & {$bf['category_delete']}" //somth near "Admin"
For example you can give users some specific permissions with their progress (like here on StackOverflow).
And so on. Very flexible.
Sorry for english, "pseudo-code" and almost no relation to Laravel, just variant how to organise permissions-system.
If you are interested i'll give some advices about this in exactly Laravel, little later.
Related
Using Ruby I'm making a call like:
client = SoftLayer::Client.new(:username => user, :api_key => api_key, :timeout => 999999)
client['Account'].object_mask("mask[id, hostname, fullyQualifiedDomainName, provisionDate, datacenter[name], billingItem[recurringFee, associatedChildren[recurringFee], orderItem[description, order[userRecord[username], id]]], tagReferences[tagId, tag[name]], primaryIpAddress, primaryBackendIpAddress]").getHardware
But only some machines return a provisionDate and only some return orderItem information. How can I consistently get this information for each machine? What would cause one machine to return this data and another machine to not?
Example output:
{"fullyQualifiedDomainName"=>"<removed_by_me>",
"hostname"=>"<removed_by_me>",
"id"=>167719,
"provisionDate"=>"",
"primaryBackendIpAddress"=>"<removed_by_me>",
"primaryIpAddress"=>"<removed_by_me>",
"billingItem"=>
{"recurringFee"=>"506.78",
"associatedChildren"=>
[<removed_by_me>]},
"datacenter"=>{"name"=>"dal09"},
"tagReferences"=>
[{"tagId"=>139415, "tag"=>{"name"=>"<removed_by_me>"}},
{"tagId"=>139417, "tag"=>{"name"=>"<removed_by_me>"}},
{"tagId"=>140549, "tag"=>{"name"=>"<removed_by_me>"}}]}
To be clear, most machines return this data so I'm trying to understand why some do not.
Please see the following provisioning steps, below is a little flow to consider:
1. Order a Server
Result:
* An orderId is assigned to the server
* The createDate has a new value
* activeTransaction value is = Null
* provisionDate value is = Null
2. The order is approved
Result:
* activeTransaction value is <> Null
* provisionDate value = Null
3. Server is already provisioned
Result:
* activeTransaction value is = Null
* provisionDate value has a New value
* billingItem property has a new value
To see if your machines have still ”activeTransaction”, please execute:
https://[username]:[apikey]#api.softlayer.com/rest/v3/SoftLayer_Hardware_Server/[server_id]/getActiveTransaction
Method: GET
Now, after reviewing your example response, this server had some problems when completing the provisioning; for that reason this step was completed manually but the provisionDate was not set for any reason(please open a ticket if you want that the provisionDate can be set) . This is a special case. I can see that another server has a similar behavior. But the other servers that don’t have provisionDate, have still ”activeTransaction<>null” (it means that these server are not provisioned yet).
EDIT:
Other property can help you to know that your machine has been already provisioned although other kind of transaction is being executed, is “hardwareStatus”, it should have “ACTIVE” value.
https://[username]:[apikey]#api.softlayer.com/rest/v3/SoftLayer_Account/getHardware?objectMask=mask[id, hostname, fullyQualifiedDomainName, provisionDate,hardwareStatus]
Method: GET
The response should be something like this:
{
"fullyQualifiedDomainName": "myhostname.softlayer.com"
"hostname": " myhostname"
"id": 1234567
"provisionDate": "2015-06-29T00:21:39-05:00"
"hardwareStatus": {
"id": 5
"status": "ACTIVE"
}
In my content type I have a field (field_fbunique) whose default value is 0; programatically, I change its value to 1 with below code and clear cache.
The value is changed to 1, but when admin users edit the node, the field value is displayed as 0, even though the value in the database is 1 (as expected).
However, to display it as 1, I need to clear cache manually. I have Memcached enabled.
$node = node_load($nid);
$node->field_fbunique['und'][0]['value'] = 1;
field_attach_presave('node', $node);
field_attach_update('node', $node);
$nodeurl = url('node/'. $nid);
cache_clear_all($nodeurl, 'cache_page');
entity_get_controller('node')->resetCache(array($nid));
drupal_flush_all_caches();
With help of this code to exclude form_cache from memcache_bins it started working for me:
$conf['memcache_bins'] = array( 'cache' => 'default', 'cache_form' => 'none', );
here is a part of my perl cgi script (which is working..):
use Net::LDAP;
use Net::LDAP::Entry;
...
$edn = "DC=xyz,DC=com";
$quser ="(&(objectClass=user)(cn=$username))";
$ad = Net::LDAP->new("ip_address...");
$ldap_msg=$ad->bind("$username\#xyz.com", password=>$password);
my $result = $ad->search( base=>$edn,
scope=>"sub",
filter=>$quser);
my $entry;
my $myname;
my $emailad;
my #entries = $result->entries;
foreach $entry (#entries) {
$myname = $entry->get_value("givenName");
$emailad = $entry->get_value("mail");
}
So basically, there is no admin/manager account for AD, users credentials are used for binding. I need to implement the same thing in grails..
+Is there a way to configure the plugin to search several ADs, I know I can add more ldap IPs in context.server but for each server I need a different search base...
++ I dont wanna use my DB, just AD. User logins through ldap > I get his email, and use the email for another ldap query but that will probably be another topic :)
Anyway the code so far is:
grails.plugin.springsecurity.ldap.context.managerDn = ''
grails.plugin.springsecurity.ldap.context.managerPassword = ''
grails.plugin.springsecurity.ldap.context.server = 'ldap://address:389'
grails.plugin.springsecurity.ldap.authorities.ignorePartialResultException = true
grails.plugin.springsecurity.ldap.search.base = 'DC=xyz,DC=com'
grails.plugin.springsecurity.ldap.authenticator.useBind=true
grails.plugin.springsecurity.ldap.authorities.retrieveDatabaseRoles = false
grails.plugin.springsecurity.ldap.search.filter="sAMAccountName={0}"
grails.plugin.springsecurity.ldap.search.searchSubtree = true
grails.plugin.springsecurity.ldap.auth.hideUserNotFoundExceptions = false
grails.plugin.springsecurity.ldap.search.attributesToReturn =
['mail', 'givenName']
grails.plugin.springsecurity.providerNames=
['ldapAuthProvider',anonymousAuthenticationProvider']
grails.plugin.springsecurity.ldap.useRememberMe = false
grails.plugin.springsecurity.ldap.authorities.retrieveGroupRoles = false
grails.plugin.springsecurity.ldap.authorities.groupSearchBase ='DC=xyz,DC=com'
grails.plugin.springsecurity.ldap.authorities.groupSearchFilter = 'member={0}'
And the error code is: [LDAP: error code 1 - 000004DC: LdapErr: DSID-0C0906E8, comment: In order to perform this operation a successful bind must be completed on the connection., data 0, v1db1
And it's the same code for any user/pass I try :/
Heeeeelp! :)
The most important thing with grails and AD is to use ActiveDirectoryLdapAuthenticationProvider rather than LdapAuthenticationProvider as it will save a world of pain. To do this, just make the following changes:
In resources.groovy:
// Domain 1
ldapAuthProvider1(ActiveDirectoryLdapAuthenticationProvider,
"mydomain.com",
"ldap://mydomain.com/"
)
// Domain 2
ldapAuthProvider2(ActiveDirectoryLdapAuthenticationProvider,
"mydomain2.com",
"ldap://mydomain2.com/"
)
In Config.groovy:
grails.plugin.springsecurity.providerNames = ['ldapAuthProvider1', 'ldapAuthProvider2']
This is all the code you need. You can pretty much remove all other grails.plugin.springsecurity.ldap.* settings in Config.groovy as they don't apply to this AD setup.
Documentation:
http://docs.spring.io/spring-security/site/docs/3.1.x/reference/springsecurity-single.html#ldap-active-directory
i am attempting to create a test user, and then write on that user's
wall. here is my code followed by the error i get (i'm using ruby and the gem fb_graph):
app = FbGraph::Application.new(config[:client_id], :secret =>
config[:client_secret])
user1 = app.test_user!(:installed => true, :permissions
=> :publish_stream)
user2 = app.test_user!(:installed => true, :permissions
=> :publish_stream)
me = FbGraph::User.me(ACCESS_TOKEN)
me.feed!(:message => "Testing")
FbGraph::Unauthorized: FbGraph::Unauthorized from /Library/Ruby/Gems/
1.8/gems/fb_graph-1.9.4/lib/fb_graph/node.rb:126:in
'handle_httpclient_error'
from /Library/Ruby/Gems/1.8/gems/fb_graph-1.9.4/lib/fb_graph/node.rb:
115:in 'handle_response'
from /Library/Ruby/Gems/1.8/gems/fb_graph-1.9.4/lib/fb_graph/node.rb:
48:in 'post'
from /Library/Ruby/Gems/1.8/gems/fb_graph-1.9.4/lib/fb_graph/
connections/feed.rb:15:in `feed!'
from (irb):90
publish_stream should give me the proper permissions to write to the
wall, but as you can see, it doesn't.
any suggestions?
thanks for any help.
Are you sure your access token is valid? Facebook needs a valid access token or it will not allow you to use the user's permissions, even if he granted them to you on facebook.
This question already has an answer here:
Duplicate DB sessions created upon Zend_Auth login
(1 answer)
Closed 2 years ago.
I'm trying to store sessions in a database using Zend Sessions however for some reason my sessions die out. Im not sure if there's some code being executed which does this or whether its something else.
I've noticed that the session ID seems to be regenerated after a breif time after having logged in.
This is even despite having added the following line in my htaccess file:
php_value session.auto_start 0
The end result is that I'm logged out every minute I'm logged in.
Heres my code in my bootstrap file
$config = array(
'name' => 'session',
'primary' => 'id',
'modifiedColumn' => 'modified',
'dataColumn' => 'data',
'lifetimeColumn' => 'lifetime'
);
$saveHandler = new Zend_Session_SaveHandler_DbTable($config);
Zend_Session::rememberMe($seconds = (60 * 60 * 24 * 30));
$saveHandler->setLifetime($seconds)->setOverrideLifetime(true);
Zend_Session::setSaveHandler($saveHandler);
//start your session!
Zend_Session::start();
I'm not using any other session related function except perhaps for Zend_Auth when logging in.
Infact rememberme calls the regenerateID function of the Session class - the end result is that I'm constantly logged out every few minutes now.
I think that you might be having this problem because you're calling rememberMe BEFORE starting the session.
You have to start the session first otherwise rememberMe won't do anything since it needs a session to set the rememberMe time on.
rememberMe calls the regenerateId function and the regeneration of the Id is what really needs the session to exist.
Place the rememberMe call after the session start then see how that works for you.
If that isn't it then I don't know what it could be since my code looks similar to yours.
Have you tried something like this?
protected function _initSession() {
$config = array(
'name' => 'session',
'primary' => 'id',
'modifiedColumn' => 'modified',
'dataColumn' => 'data',
'lifetimeColumn' => 'lifetime',
'lifetime' => 60*60*24*30,
);
Zend_Session::setSaveHandler(new F_Session_SaveHandler_DbTable($config));
}
This way the lifetime isn't set after initialising the database sessions, but is directly included in the initialisation options - it works for me, I see no reason why this should fail in your case :).
I think you need to look once into following values after bootstrap code
session.gc_maxlifetime
session.cookie_lifetime
If You configure session resources in *.ini config file, check resources.session.cookie_domain parameter.
I spend 3 hours when I remembered about it.