Read a value from an array - perl

I have an array defined as below.
I am able to fetch the value for email and uid as mentioned below. How do I get the user display name userdn?
my ($mesg) = $ldap->search(
scope => 'one',
base => $userdn,
filter => $filter,
attrs => [ 'email', 'pwdChangedTime', 'uid' ],
);
This is how I read the email ID and uid, but I'm unable to read the user display name.
foreach my $entry ( $mesg->all_entries ) {
$email = ${ $entry->get( 'email' ) }[0];
$uid = ${ $entry->get( 'uid' ) }[0];
$uName = ${ $entry->get( 'userdn' ) };
}

This is not really about an array, but rather about how to use Net::LDAP. There are no arrays in your example code.
You want to get the userdn property for the items returned from your LDAP query. In order to do that, you need to tell search to fetch those.
A list of attributes to be returned for each entry that matches the search filter.
This means, you need to include userdn in the call to search.
my ($mesg) = $ldap->search(
scope => 'one',
base => $userdn,
filter => $filter,
attrs => [ 'email', 'pwdChangedTime', 'uid', 'userdn' ],
);
Now you can get the userdn.
$uName = $entry->get('userdn')->[0];
I've used the arrow dereference syntax instead of ${ ... }[0] here because I find that easier to read. However, as ysth points out below in the comments, get is deprecated and not documented in the current version of Net::LDAP. It was deprecated in release 0.21 in September 2000, which is currently seventeen years ago.
Instead, you should probably use get_value, which returns the first value of that attribute.
$uName = $entry->get_value('userdn');

Related

Iterating over an array reference

# data $bug
{ 
'keyword_objects' => [
bless( { 'id' => 15, 'name' => 'CRASH'}, 'SomeModule::SomeFilename' ),
bless( { 'id' => 6, 'name' => 'CUSTOMER' }, 'SomeModule::SomeFilename' ) ],
'category' => 'error'
}
foreach my $keyword ($bug->{keyword_objects}) {
print Dumper($keyword);
}
It prints the whole of keyword_objects instead of the individual items in it. Now it should be obvious to you that I know so little about Perl, I'd like to also ask what is the right way to reference name in each keyword.
To iterate over the elements in your array ref, you need to dereference it. foreach needs a list.
foreach my $keyword ( #{ $bug->{keyword_objects} } ) {
Your objects are hash references, so you could reach into their internals like this:
$keyword->{name}
However, messing with internals is not a good idea. Instead, you should write accessors and call them as a method.
$keyword->name

Does tweet_mode=extended work with the Twitter statuses/user_timeline API?

There is no mention of tweet_mode at https://developer.twitter.com/en/docs/tweets/timelines/api-reference/get-statuses-user_timeline.html
I am wondering if perhaps I am using the wrong API to be able to take advantage of tweet_mode?
In my application, I supplied the tweet_mode=extended argument and it had no effect. My code...
// Load the Tweets.
$args = array(
'screen_name' => $username,
'exclude_replies' => 'true',
'include_rts' => 'true',
'tweet_mode' => 'extended',
'count' => $numitems,
);
$connection = new TwitterOAuth(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET);
$tweets = $connection->get('statuses/user_timeline', $args);
if (!empty($tweets)) {
foreach ($tweets as $tweet) {
$text = $tweet->full_text;
// etcetera
Yes, you can use tweet_mode with the statuses/user_timeline API. Retweets are a special case, though. Check the retweeted_status object, as described at https://dev.to/kehers/formatting-tweets-a-look-at-extended-tweets-retweets-and-quotes-n5j
In short, if a tweet is a retweet, the extended tweet must be accessed at $tweet->retweeted_status->full_text. Thus, it's necessary in your code to check if each tweet object has a retweeted_status property.

Perl: How to get the value of an attribute of an object

In the below example, how would i print out the thread id?
$r_event = {
'type' => 'READ_' . $task . '_STARTED',
'timestamp' => $timestamp,
'threadid' => $threadId,
'fdn' => $fdn
};
You have a hash reference there (and those are often used as objects and that's what JSON calls an "object"). You can use the -> to dereference it and put the key you want in curlies:
print $r_event->{'threaded'};
This is just like a normal hash. Note the % and the parens instead of curlies:
%r_event = (
'type' => 'READ_' . $task . '_STARTED',
'timestamp' => $timestamp,
'threadid' => $threadId,
'fdn' => $fdn
);
In that case it's just $r_event{'threaded'} with no arrow since there's no reference.
My book Intermediate Perl covers this and you'll also find it in perlref.

Group membership of a specific user in Perl using Net::LDAPS

I've been searching various sites for some help on this, but not getting very far. My goal is to check group membership once a login is successful. The login part works fine, but I want to get a list of groups of the logged in user to compare it to a particular one. If they are not a member of that group, they are logged out, the session is deleted and they are returned to the login page, otherwise they can continue.
Here is the code:
my $base = "ou=Groups,ou=Services,dc=example,cd=com";
my $mesg = $ldap->search(
filter=>"(uid=$userid)",
base=>"$base",
scope=>'children',
);
my #entries = $mesg->entries;
print("mesg = <BR>");
print(Dumper($mesg));
And here is the output of $mesg:
$VAR1 = bless( {
'parent' => bless( {
'net_ldap_version' => 3,
'net_ldap_scheme' => 'ldaps',
'net_ldap_debug' => 0,
'net_ldap_socket' => bless( \*Symbol::GEN0, 'IO::Socket::SSL' ),
'net_ldap_host' => 'ldap.example.com',
'net_ldap_uri' => 'ldap.example.com',
'net_ldap_resp' => {},
'net_ldap_mesg' => {},
'net_ldap_async' => 0,
'net_ldap_port' => '636',
'net_ldap_refcnt' => 1
}, 'Net::LDAPS' ),
'errorMessage' => 'NDS error: no such entry (-601)',
'ctrl_hash' => undef,
'resultCode' => 32,
'callback' => undef,
'mesgid' => 2,
'matchedDN' => '',
'controls' => undef,
'raw' => undef
}, 'Net::LDAP::Search' );
I can see the NDS message that says there's no such entry, so I'm assuming my search query is where the error lies, but the mistake is escaping me. Any suggestions? I've also tried without the scope=>'children' line, without any change.
Thanks.
Update:
This is what I ended up doing, and was successful.. had to tweak one of the other person's answers a bit, but ended up getting what I was looking for.
my $mesg = $ldap->search(
filter=>"(&(objectClass=group)(memberUid=$userid)(member=$userdn))",
base=>"$base",
scope=>'subtree',
attrs=>[qw(memberUid)],
);
my $searchresults = $mesg->as_struct;
my %searchhash = %$searchresults; # dereference the hash
my #members = # { $searchhash{$base}{memberuid} }; # pick out just the memberuid array from the hash
Then I basically iterated over the users in that group (#members) and if the logged in user was in there,
they were authenticated, if not, their session info got deleted and the script exited.
Not exactly the same answer as was given below, but we don't have uniquemember in our tree. Either way, hope this helps someone.
When you log the user in I presume you are performing a successful bind with their distinguished name.
I would search for the user in the group instead of searching for all of the users groups and looking for the specific group. I am also presuming that you are using the groupOfUniqueNames group objectclass to group your users. I would do something like this...
# assuming you already have this value in a variable from the authN step
my $user_dn = "cn=dave,ou=people,dc=example,dc=com"
my $base = "cn=GroupToCheck,ou=Groups,ou=Services,dc=example,cd=com";
my $mesg = $ldap->search(
filter=>"(uniquemember=$user_dn)",
base=>"$base",
scope=>'base'
);
If you get a result then the user is in the group. If you don't get any results then the user is not in the group.
If you really do want to get all of the groups though then this will return the group name from all of the group(s) for which the user is a member.
# assuming you already have this value in a variable from the authN step
my $user_dn = "cn=dave,ou=people,dc=example,dc=com"
my $base = "ou=Groups,ou=Services,dc=example,cd=com";
my $mesg = $ldap->search(
filter=>"(uniquemember=$user_dn)",
base=>"$base",
scope=>'sub',
attrs => ['cn']
);

Can someone provide a php sample using nusoap/sugarcrm api to create an acct/lead in sugarcrn?

Can someone provide a sample code chunk of php using the sugarcrm API/nusoap for adding creating an acct. and then linking a lead to the acct?
I've got a sample function that adds a lead, and I can see how to create an acct, but I can't see how to tie a lead to the acct, to simulate the subpanel process in the sugarcrm acct/subpanel process.
thanks
// Create a new Lead, return the SOAP result
function createLead($data)
{
// Parse the data and store it into a name/value list
// which will then pe passed on to Sugar via SOAP
$name_value_list = array();
foreach($data as $key => $value)
array_push($name_value_list, array('name' => $key, 'value' => $value));
// Fire the set_entry call to the Leads module
$result = $this->soap->call('set_entry', array(
'session' => $this->session,
'module_name' => 'Leads',
'name_value_list' => $name_value_list
));
return $result;
}
$result = $sugar->createLead(array(
'lead_source' => 'Web Site',
'lead_source_description' => 'Inquiry form on the website',
'lead_status' => 'New',
'first_name' => $_POST['first_name'],
'last_name' => $_POST['last_name'],
'email1' => $_POST['email'],
'description' => $_POST['message']
));
You need to find the ID for the account and assign that ID to whatever the account_id field name is in the Lead Module. I have run into a couple things like this before and I have found it easier to go straight to the Sugar database. So, write a statement that will return the account is, for example: SELECT id WHERE something_in_the_account_table = something else;
Then you can assign that id in your $result array. I hope it helps. I didn't have any code or documentation in front of me or I would have helped more.