Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Make an ajax call to the active directory and pull thumbnail photos using post

I want to retrieve informations from the active directory (such as thumbnail photos) using post.

<?php
/**
 * Get a list of users from Active Directory.
 */
$ldap_password = $_POST['password'];
$ldap_username = $_POST['username'];
$server = 'ldap://xxxxxxxxxxxxxxxxxxxxxx';
$domain = 'xxxxxxxxxxxxxxxxx';
$port       = 389;
$ldap_connection = ldap_connect($server, $port);

if (FALSE === $ldap_connection){
    // Uh-oh, something is wrong...
}

// We have to set this option for the version of Active Directory we are using.
ldap_set_option($ldap_connection, LDAP_OPT_PROTOCOL_VERSION, 3) or die('Unable to set LDAP protocol version');
ldap_set_option($ldap_connection, LDAP_OPT_REFERRALS, 0); // We need this for doing an LDAP search.

if (TRUE === ldap_bind($ldap_connection, $ldap_username.$domain, $ldap_password)){
    $ldap_base_dn = "OU=Employees,OU=Accounts,OU=xxxxx,DC=xxxxxx,DC=xxxxxxx,DC=com";
    $search_filter = '(&(objectCategory=person)(samaccountname=*))';
    $attributes = array();
    $attributes[] = 'givenname';
    $attributes[] = 'mail';
    $attributes[] = 'samaccountname';
    $attributes[] = 'sn';
    $result = ldap_search($ldap_connection, $ldap_base_dn, $search_filter, $attributes);
    $maxPageSize = 1000;
    if (FALSE !== $result){
        $entries = ldap_get_entries($ldap_connection, $result);
        for ($x=0; $x<$entries['count']; $x++){
            if (!empty($entries[$x]['givenname'][0]) &&
                 !empty($entries[$x]['mail'][0]) &&
                 !empty($entries[$x]['samaccountname'][0]) &&
                 !empty($entries[$x]['sn'][0]) &&
                 'Shop' !== $entries[$x]['sn'][0] &&
                 'Account' !== $entries[$x]['sn'][0]){
                $ad_users[strtoupper(trim($entries[$x]['samaccountname'][0]))] = array('email' => strtolower(trim($entries[$x]['mail'][0])),'first_name' => trim($entries[$x]['givenname'][0]),'last_name' => trim($entries[$x]['sn'][0]));
            }
        }
    }
    ldap_unbind($ldap_connection); // Clean up after ourselves.
}

$message .= "Retrieved ". count($ad_users) ." Active Directory users\n";
?>

I tried using http://localhost:8666/web1/activedirectory.php to see if it returns anything but it returns the following error as result is >1000.

Warning: ldap_search(): Partial search results returned: Sizelimit exceeded in C:\xampp\htdocs\web1\activedirectory.php on line 28

Notice: Undefined variable: message in C:\xampp\htdocs\web1\activedirectory.php on line 46

below is the jquery where I want to link the .php file to the above file :

$('.leaderboard li').on('click', function () {
    $.ajax({
        url: "../popupData/activedirectory.php", // php file with link to the active directory.
        type: "POST",
        data: {id:$(this).find('.parent-div').data('id')},
        success: function(data){
            console.log(data);
            data = JSON.parse(data);
            $('#popup').fadeIn();
            //call for the thumbnail photo
            // etc ..
        },
        error: function(){
            alert('failed, possible script does not exist');
        }
    });
});
like image 290
jane Avatar asked Jan 24 '17 13:01

jane


People also ask

What is the Ajax thumbnail script and how does it work?

The Script facilitates the process of uploading an image via Ajax and using PHP to create a thumbnail, return the image source and display to the user as a thumbnail of the image uploaded. All without the page reloading. To help you understand how it works I’ve commented on a few of the key parts below.

How do I send data to a server using Ajax?

The POST method transports data in the request body. Data can be transported in JSON and XML formats. You can use the XMLHttpRequest object (XHR) to communicate with a web server using the AJAX technique. This is the classic way to do AJAX, but it's not the best way now that the Fetch API is supported in modern browsers.

What are get and post methods in Ajax?

jQuery - AJAX get() and post() Methods. The jQuery get() and post() methods are used to request data from the server with an HTTP GET or POST request. HTTP Request: GET vs. POST. Two commonly used methods for a request-response between a client and server are: GET and POST.

What is a Ajax POST request?

AJAX is a modern web technology used for updating page contents asynchronously. This means that a user can still interact with a page while the app uses JavaScript to fetch information from the server and update the page. In this article, we looked at three ways to make AJAX post requests in a web application.


2 Answers

First of all, the error you get has nothing to do with POST, AJAX, or PHP. It is caused by the LDAP query being too generic:

ldap_search(): Partial search results returned: Size limit exceeded

Each jQuery call can only return one image, so you need to retrieve the thumbnails one by one, and each call needs to search and return only one record (i.e. a READ, not a SEARCH).

This means that you need to send along your user ID in the PHP call so that the script may know which thumbnail to return... and this you do.

But the PHP is not using that information. You search for all the names, which means that it couldn't work anyway, but it doesn't even start because the LDAP search croaks.

$search_filter = '(&(objectCategory=person)(samaccountname=*))';

In the line above, you need to add some filter. For example, is the ID name you get in the leaderboard the SAM account name? If so, you can do something like

$kid = 'NonExistingAccount';
if (preg_match('#SAM_NAME_MATCHING_REGEX#', $_POST['id'])) {
    $kid = $_POST['id'];
}
$search_filter = "(&(objectCategory=person)(samaccountname={$kid}))";

and be sure to retrieve only one record. At that point you can go about extracting the image (which if memory serves is in bitmap format), and convert it to a form suitable for jQuery:

$bitmap = $entries[0]['picture'];
// Some error checking would probably be good
$gd     = imageCreateFromString($bitmap);
// Here you'll probably want to resize your image. Create
// another GD object with ImageCreateTrueColor and use imageCopyResampled
// with the appropriate size.

// Then, inform jQuery that a PNG is coming along
header('Content-Type: image/png');
// and send the PNG
imagePNG($gd);
// and nothing else (shouldn't matter, but you never know, and anyway...).
exit();

Example

You have a HTML section containing several elements (say, your employees).

VERY IMPORTANT: this section will have been generated by PHP using a LDAP search, so that you have the information required. You may need to paginate the LDAP search to avoid too many results being returned (and an error), as before.

But once you do this, you will have the distinguished name of each user.

<ul class="leaderboard">
   ...
   <li data-dn="CN=Jeff Smith,OU=Sales,DC=Fabrikam,DC=COM">
       <img class="placeholder" />
           <span class="cn">Jeff Smith</span>
           <span class="ou">Sales</span>
   </li>
   ...
</ul>

In the above, you read 'Jeff Smith' and so on from the LDAP search. But you cannot easily place an image there from PHP, HTML does not permit it (okay, it does, as this answer to a similar question as yours shows, but say you prefer not to), so you put there a placeholder instead with the appropriate size using CSS.

You can also put an animated GIF that says "loading..." in the image.

To make things more efficient you save in the data-dn attribute the DN of each result.

Either on clicking or onload(), or if you have an AJAX paging on page change, you retrieve all the images. This is very similar to the code you already have.

$('.leaderboard li').on('click', function () {
    // Get the image. This returns nothing if it has already been loaded.
    var img = $(this).find('img.placeholder');
    if (img.length === 0) { return; }
    var dn = $(this).attr('data-dn');

    // Load image from its DN.
    // See https://stackoverflow.com/questions/4285042/asychronously-load-images-with-jquery
    img.src = 'load-image.php?dn=' + dn;
});

The load-image.php script will receive $_GET['dn'] and will require to perform a LDAP read using the supplied DN, and retrieve the appropriate image attribute.

Then you just output it with header() and the image*() function you prefer (e.g. imageJPEG() or imagePNG() ).

You could do this in AJAX and send images encoded as base64 (code in the link above), but it's more complicated, and the time you save sending only one call instead of twenty for twenty images is promptly lost, with interest, when you need to send along the JPEGs encoded as base64 instead of binary, with a 5-10% increase in size if your web server gz-encodes the base64 (or a 33% increase in size when it doesn't).

like image 68
LSerni Avatar answered Oct 24 '22 18:10

LSerni


FIRST QUESTION:

You have to append an img element insteadt of setting the text like this:

$('#imagesofBadges').append('<img src="'  + data[0].BadgeImage + '"/>');

SECOND QUESTION:

When appending the images add a class attribute so you can fetch them with jQuery using that classname like this:

var $img = $('<img src="'  + data[0].BadgeImage + '"/>'); // create the image
$img.addClass('badge-image'); // add the class .badge-image to it
$('#imagesofBadges').append($img); // append it

Now you can fetch those images using a selector like this:

$('#imagesofBadges .badge-image'); // will fetch all the elements that have the class .badge-image that are inside #imagesofBadges.

EDIT:

if you want to remove all the images inside #imagesofBadges before appending the new one use this:

// fetch all the images inside #imagesofBadges and remove them
$('#imagesofBadges img').remove();
// append the new image
$('#imagesofBadges').append('<img src="'  + data[0].BadgeImage + '"/>');
like image 25
ibrahim mahrir Avatar answered Oct 24 '22 18:10

ibrahim mahrir