I'm trying to find out the unboundid AttributeSyntax type for a specific attribute name and it's simply not working.
Here's the example test code that I'm using to achieve this:
#Test
public void testLDAPSchema() {
try {
LDAPConnection connection = new LDAPConnection();
connection.connect("hessmain", 389);
connection.bind("CN=Administrator,CN=Users,DC=FISHBOWL,DC=NET", "password");
Schema s = connection.getSchema();
System.out.println(s.toString());
AttributeTypeDefinition atd = s.getAttributeType("directReports");
Set<AttributeTypeDefinition> oat = s.getOperationalAttributeTypes();
Set<AttributeSyntaxDefinition> l = s.getAttributeSyntaxes();
AttributeSyntaxDefinition asd1 = s.getAttributeSyntax(atd.getOID());
AttributeSyntaxDefinition asd2 = s.getAttributeSyntax(atd.getSyntaxOID());
AttributeSyntaxDefinition asd3 = s.getAttributeSyntax(atd.getBaseSyntaxOID());
connection.close();
} catch (Exception e) {
Assert.fail(e.getMessage());
}
}
From the above code, all the sets are empty. This also means that no matter which OID I pass to the schema getAttributeSyntax method that I will simply get a null return.
Is there any reason why I can't get the attribute syntaxes from an Active Directory server schema?
Thanks
I don't think that this is specific to the UnboundID LDAP SDK for Java. I'm not sure that Active Directory exposes this information over LDAP. When I perform a general LDAP search to retrieve schema information, I can see the attributeTypes and objectClasses attributes, but ldapSyntaxes isn't returned (and in fact ldapSyntaxes doesn't appear in the list of attribute types).
Similarly, none of the attribute type definitions includes a USAGE element, which is what is used to indicate that the attribute type is operational (e.g., "USAGE directoryOperation").
It may well be that Active Directory simply doesn't report this information at all. It could be that it provides some other non-standard way to get this information (e.g., a control or extended operation, or some other entry that can be retrieved), but if there is then I don't know about it.
Related
I am trying to check if a change tables exists in Salesforce by calling
var name = "acme_npsp__Allocation_c__c";
try
{
salesforceObject = _service.describeSObject(name);
return sObject;
}
catch (Exception ex)
{
error = ex.Message;
}
but it gives an error:
INVALID_TYPE: salesforceObject type 'acme_npsp__Allocation_c__c' is not
supported. If you are attempting to use a custom object, be sure to append the
'__c' after the entity name. Please reference your WSDL or the describe call for
the appropriate names.
(107 - FIELD_INTEGRITY_EXCEPTION) Cannot create a new component with the namespace: acme_npsp. Only components in the same namespace as the organization can be created through the API.
But if i replace the __ in the middle with a single _ it seems to work , but that isnt my object in salesforce so i cant reference it in other code.
Salesforce doesnt allow to create such an object with '__' in the middle, but it was created using the package Nonprofit Success Pack (NPSP) which can be downloaded from the store.
How can i create the object with the '__' in the middle , ie after the npsp ?
Salesforce does not allow __ in API names, because double underscores serve a special meaning: they delimit the components of the API name. An API name, for a schema element like this, consists of up to 3 parts:
namespace__component_name__c
namespace is the first component, and is the (optional) namespace, which indicates that the component is part of a package. NPSP's namespace is npsp. You cannot create components in a namespace you do not own.
The name element is present on all components. For Account and other standard objects, it's the entire API name.
__c is the suffix, which indicates what kind of entity you have. __c is a custom object; __b a BigObject; __e a custom Platform Event; __mdt a custom Metadata Type. Lack of a suffix indicates a standard component.
Your question does not make much sense as written. You appear to be trying to work with the object npsp__Allocation__c. It's not clear why you are trying to prepend some other value to the namespace and suffix.
Accessing the describe does not create an object, so the behavior of your code is exactly as designed.
I'm trying to remove a member from a large ldap Active Directory (AD) group. The below code will remove the member if the group is small. However it won't work if it's larger since AD splits the members into multiple range related attributes.
group.removeMember(person.getFullDn());
ldapTemplate.update(group);
I've tried to access those attributes directly using something like the below. IncrementalAttributesMapper allows me to get the list of range related member attributes ie member;Range=0-1499 and I attempt to delete the person from each, but no good. I don't get an error, but the person isn't removed from the group either
DirContextOperations ctx = ldapTemplate.lookupContext(group.getDn());
IncrementalAttributesMapper<?> attributesMapper = new DefaultIncrementalAttributesMapper("member");
while (attributesMapper.hasMore()) {
String[] attributes = attributesMapper.getAttributesForLookup();
for (String attribute: attributes ) {
ldapTemplate.lookup(group.getDn(), attributesMapper.getAttributesForLookup(), attributesMapper);
ctx.removeAttributeValue(attribute, person.getDn() );
ldapTemplate.modifyAttributes(ctx);
}
}
Hopefully someone has had more success with this. Thanks in advance!
I've got the solution as posted
I was getting a malformed attribute error until I just realised that the BasicAttribute is expecting String parameters. I was incorrectly passing in a Name object to it.
ldapTemplate.modifyAttributes(group.getDn(), new ModificationItem[] {
new ModificationItem(
DirContext.REMOVE_ATTRIBUTE,
new BasicAttribute("member", person.getFullDn().toString() ))
});
I have a Permissions class for which I need to create a static method to get the corresponding element based on the POST method in my views.py. The choices are done via checkboxes, in which you can select either of those, a pair or all of them, based on your preferences. That creates a list of strings (u'OWNER'), which should be processed in the static method and return the corresponding Permissions.OWNER, Permissions.HR, Permissions.USER_ADMIN
My views.py's POST method looks like this:
permissions = self.request.get_all('permissions')
user.new_permission = Permissions.get_permission(permissions)
Model looks like this:
class Permissions(object):
OWNER = 'OWNER'
HR = 'HR'
USER_ADMIN = 'USER_ADMIN'
descriptions = {
OWNER: """Company owner (full admin)""",
HR: """Human Resources administrator (access to special fields within job and submissions)""",
USER_ADMIN: """Add/Delete users, change user permissions""",
}
What I have so far on the static method:
#staticmethod
def get_permissions(permissions):
new_perms = []
for permission in permissions:
name = permission
if permission ==
new_perms.append(permission)
return new_perms
I really do not know how can I compare a string to the value in the model... Nor I am sure if I have titled the question correctly.
Thank you in advance,
Borislav
There are a whole bunch of things wrong with your code, and it seems to be overcomplicated.
I suggest you do some python tutorials. I m not sure how the class definition was ever going to work. Any way here is one way you could do it.
class Permissions(object):
_perms = {
'OWNER': """Company owner (full admin)""",
'HR': """Human Resources administrator (access to special fields within job and submissions)""",
'USER_ADMIN': """Add/Delete users, change user permissions""",
}
#classmethod
def get_permissions(cls,permissions):
new_perms = []
for choice in permissions:
if choice in cls._perms:
new_perms.append(choice)
return new_perms
#classmethod
def get_description(cls,permission)
return cls._perm.get(permission)
Actually on re-reading your question I am not sure what you are really trying to do. You mention a model, but the permissions class you provide doesn't reflect that, and I assume you need to query for the object. In fact if you where using a model to define permissions you would have a Permission object for each possible Permission - maybe.
alternate strategy, but there are many and without looking in more detail at how you really plan to use permissions. (I use repose.who/what for a fairly well developed permission model). At its most basic you can use getattr with your existing class. However I not keen on it, as there are no checks in place.
class Permissions(object):
OWNER = 'OWNER'
HR = 'HR'
USER_ADMIN = 'USER_ADMIN'
#classmethod
def get_permission(cls,permission):
if hasattr(cls,permission):
return getattr(cls,permission)
else:
raise KeyError("No permission %s" % permission) # Some better exception should be used.
I have the following objects: L1User, L2User, L3User (all inherits from User) and Document.
Every user can create the document but depending on the user type, the document will have a different status. So in case it's L1User, the document will be created with L1 status and so on:
Solution 1
Please note that after document is created, it will be saved in the database, so it should be natural to have a method create_document(User user) in Document object. In the method body I could check which type is the user and set manually appropriate status. Such approach seems rather not OOP to me.
Solution 2
Ok, so the next approach would be to have all users implement a common method (say create_document(Document doc)) which will set a status associated with the user and save the document in the database. My doubt here is that the document should be saved in it's own class, not the user.
Solution 3
So the final approach would similar to the above, except that the user will return modified document object to it's create_document(User user) method and save will be performed there. The definition of the method would be like this:
create_document(User user)
{
this = user.create_document(this);
this->save();
}
It also doesn't seems right to me...
Can anyone suggest a better approach?
I think that both Solutions 2 and 3 are ok from the OO point of view, since you are properly delegating the status assignment to the user object (contrary to solution 1, whare you are basically doing a switch based on the user type). Whether to choose 2 or 3 is more a matter of personal tastes.
However, I have a doubt: why do you pass a document to a create_document() method? I would go for a message name that best describes what it does. For example, in solution 3 (the one I like the most) I would go for:
Document>>create_document(User user)
{
this = user.create_document();
this->save();
}
and then
L1User>>create_document()
{
return new Document('L1');
}
or
Document>>create_document(User user)
{
this = new Document()
this = user.set_document_type(this);
this->save();
}
and then
L1User>>set_document_type(document)
{
document.setType('L1');
}
Edit: I kept thinking about this and there is actually a fourth solution. However the following approach works only if the status of a document doesn't change through its lifetime and you can map the DB field with a getter instead of a property. Since the document already knows the user and the status depends on the user, you can just delegate:
Document>>getStatus()
{
return this.user.getDocumentStatus();
}
HTH
I've got an asp application running but i want to search the Active Directory.
i am using vb (visual web developer 2008)
how do i search the active directory for a given user?
ie: user enters login name in text box, clicks submit. active directory is searched on-click for this user. when found user information is displayed .
Thanks
What version of the .NET framework can you use? Searching and looking up stuff in AD has become extremely easy in .NET 3.5 - see this great MSDN article by Ethan Wilanski and Joe Kaplan on using the security principals API for that.
If you're not on .NET 3.5 yet, you'll have to use the DirectorySearcher class and set up the search filters as you need. Getting the LDAP filter right is probably the biggest obstacle.
Robbie Allen also has two great intro article on System.DirectoryServices programming:
- Part 1
- Part 2
There are some really good resources at http://www.directoryprogramming.net (Joe Kaplan's site - he's a Microsoft Active Directory MVP), and Richard Mueller has some great reference excel sheets on what properties are available for each of the ADSI providers, and what they mean, and how their LDAP name is - see http://www.rlmueller.net.
Marc
EDIT: Ok- here's the .NET 2.0 / 3.0 approach:
// set the search root - the AD container to search from
DirectoryEntry searchRoot = new DirectoryEntry("LDAP://dc=yourdomain,dc=com");
// create directory searcher
DirectorySearcher ds = new DirectorySearcher(searchRoot);
ds.SearchScope = SearchScope.Subtree;
// set the properties to load in the search results
// the fewer you load, the better your performance
ds.PropertiesToLoad.Add("cn");
ds.PropertiesToLoad.Add("sn");
ds.PropertiesToLoad.Add("givenName");
ds.PropertiesToLoad.Add("mail");
// set the filter - here I'm using objectCategory since this attribute is
// single-valued and indexed --> much better than objectClass in performance
// the "anr" is the "ambiguous name resolution" property which basically
// searches for all normally interesting name properties
ds.Filter = "(&(objectCategory=person)(anr=user-name-here))";
// get the result collection
SearchResultCollection src = ds.FindAll();
// iterate over the results
foreach (SearchResult sr in src)
{
// do whatever you need to do with the search result
// I'm extracting the properties I specified in the PropertiesToLoad
// mind you - a property might not be set in AD and thus would
// be NULL here (e.g. not included in the Properties collection)
// also, all result properties are really multi-valued, so you need
// to do this trickery to get the first of the values returned
string surname = string.Empty;
if (sr.Properties.Contains("sn"))
{
surname = sr.Properties["sn"][0].ToString();
}
string givenName = string.Empty;
if (sr.Properties.Contains("givenName"))
{
givenName = sr.Properties["givenName"][0].ToString();
}
string email = string.Empty;
if (sr.Properties.Contains("mail"))
{
email = sr.Properties["mail"][0].ToString();
}
Console.WriteLine("Name: {0} {1} / Mail: {2}", givenName, surname, email);
}
Hope this helps!
Marc