The Community Forums

Interact with an entire community of cPanel & WHM users!
  1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Custom API Calls - How to create?

Discussion in 'cPanel Developers' started by bdigitalstudios, Jun 7, 2011.

  1. bdigitalstudios

    Joined:
    Mar 29, 2010
    Messages:
    9
    Likes Received:
    0
    Trophy Points:
    1
    Hi,

    Before someone says it, I have searched for this on the forum, Google etc... I could only come up with the following: WritingCpanelModules < SoftwareDevelopmentKit < TWiki

    But I personally don't think it is very well explained... Plus, I think it's talking about calling API functions, not creating them for access over HTTP.

    I am fluent in PHP, but never written a line of Perl... I don't plan learning the entire language for something simple like I need to do, so if someone could point me in the correct direction or write an example for me, I would be very grateful! :)

    Basically all I need to do is execute a line of code... the code will be modifying accounts files directly. The API will be called as root. It will be passes a username & the rest is static, that's all.

    Does that make sense? I hope so, I'm stuck for searching, I can't find anything like this, althought I'm sure there must be.

    Thank you in advance,

    Josh
     
  2. cPanelDavidN

    cPanelDavidN Integration Developer
    Staff Member

    Joined:
    Dec 17, 2009
    Messages:
    571
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    Houston, TX
    cPanel Access Level:
    Root Administrator
    Hi Josh,

    That documentation is the correct starting point for creating custom API calls. Currently, on APIs design for cPanel (not WHM) can be created. Fortunately, all cPanel APIs (eg, API1 & API2) can be call, not only locally for use in the cPanel UI, but remotely ala the XML/JSON-API.

    However, cPanel APIs are typically designed to be run as the cPanel user, not root. If I understand properly, you want root to do stuff related to the user, as opposed to a user doing particular actions as a privilege user (ie, root). There's a distinction. If you want the latter, then there's a way you can perform privilege escalation that's documented here.

    I'm happy to explain (hopefully in a meaningful way) how to create custom cPanel modules, but I'm wonder if it's really the solution that's best for you? If you have root access, and you're performing file manipulations, won't it make sense to create a shell script? And there are pure PHP SSH/SCP clients out there, so you can copy/trigger the remote script even within a web application.

    Let me know you're thoughts, and we can press onwards accordingly.

    Regards,
    -DavidN
     
  3. bdigitalstudios

    Joined:
    Mar 29, 2010
    Messages:
    9
    Likes Received:
    0
    Trophy Points:
    1
    Hi David,

    Thank you for your detailed reply. Basically, I will be calling this function (or existing function, but I can't see one to do this) to change the permissions on an account. Simply to comply with suPHP etc, incase a clients break them & starts to receive 500 Int Server Errors.

    I would like to call the JSON API & authenticate as root, which I will be supplying with a hash. I then need to change the permissions on the account with the specified username...

    I hope that makes sense...

    Thanks again.
     
  4. cPanelDavidN

    cPanelDavidN Integration Developer
    Staff Member

    Joined:
    Dec 17, 2009
    Messages:
    571
    Likes Received:
    1
    Trophy Points:
    18
    Location:
    Houston, TX
    cPanel Access Level:
    Root Administrator
    Josh,

    There really isn't an API for what you want. You have three choices:

    1) make your own API2 custom module that we validate the requested action then escalates to root to perform the action.
    2) you could utilize a combination of API2 Fileman::listfiles, Fileman::fileop to recursively fetch the filenames and then perform a chmod on them (I assume that is the only "permissions" that your talking about; if you need to chown, this method won't work because Fileman::fileop don't have that option)
    3) do the operation via SSH.

    I kinda think that a options 3 will be the simplest and most straight forward to maintain.

    Regards,
    -DavidN

    If, by chance, you decide to do method 2, here's a sample in PHP (using the PHP XML-API client class) of how to recursively fetch the file list...just something I whipped up to see how feasible it was
    PHP:
    require "xmlapi.php";

    //////////////////////////////////////////////////////////////////
    // Extend PHP Class ///////////////////////////////////////////

    class CustomXmlapi extends xmlapi
    {
        private 
    $cpuser;
        
        public function 
    __construct($host null$user null$pass null
        {
            
    parent::__construct($host,$user,$pass);
            
    $this->set_output('json');
            return 
    $this;
        }
        
        public function 
    set_cpuser($user)
        {
            
    $this->cpuser $user;
            return 
    $this;
        }
        
        public function 
    get_dir_list($listdir)
        {
            
    $args = array(
                
    'dir'          => $listdir,
                
    'checkleaf'    => 1,
                
    'showdotfiles' => 0,
                
    'types'        => 'dir|file',
            );
            
            
    $list $this->api2_query($this->cpuser'Fileman''listfiles'$args);
            
    $list $this->_getValidResult($list);
            
    $files = array();
            
    $rdirs = array();
            foreach(
    $list as $item) {
                if ( 
    $item['type'] == 'file'){
                    
    #just a normal file
                    
    array_push($files$item['fullpath']);
                } elseif ( 
    $item['type'] == 'dir' && $item['isleaf'] == 1) {
                    
    #a directory that contains files;
                    
    array_push($rdirs$item['fullpath']);
                }
            }
            foreach( 
    $rdirs as $dir) {
                
    $tmp_files $this->get_dir_list($dir);
                foreach( 
    $tmp_files as $more ){
                    
    array_push($files$more);
                }
            }
            return 
    $files;
        }
        
        private function 
    _getValidResult$json_str 
        {
            
    $arr json_decode($json_str,1);
            if ( 
    $arr === null || !is_array($arr)) {
                return 
    null;
            } elseif ( !
    array_key_exists("cpanelresult"$arr)
              || !
    is_array($arr['cpanelresult']) 
              || !
    array_key_exists("data"$arr['cpanelresult']) 
              || !
    is_array($arr['cpanelresult']['data'])) {
                return 
    null;
            }
            
            return 
    $arr['cpanelresult']['data'];
        }
    }

    //////////////////////////////////////////////////////////////////
    // Main script //////////////////////////////////////////////////

    $ip 'my.server.net';
    $loginUser 'root';
    $accessHash get_file_contents('/stored/root/.accesshash');
    $user 'mycpanel';  //user with permission issues

    $xmlapi = new CustomXmlapi($ip);
    $xmlapi->set_user($loginUser);
    $xmlapi->set_hash($accessHash);
    $xmlapi->set_port(2087);

    $xmlapi->set_cpuser($user);

    //$xmlapi->set_debug(1);

    $list $xmlapi->get_dir_list('public_html');
    //var_dump($list);

    // Now that we have list we can use Fileman::fileop to perform a chmod on the files.

     
  5. bdigitalstudios

    Joined:
    Mar 29, 2010
    Messages:
    9
    Likes Received:
    0
    Trophy Points:
    1
    Sweet, thanks David.

    I will try it out & build it into my app & get back to you to let you know it worked (Fingers corssed! :) )

    Have a great day.
     
  6. bdigitalstudios

    Joined:
    Mar 29, 2010
    Messages:
    9
    Likes Received:
    0
    Trophy Points:
    1
    Worked like a charm, thank you David! I simply sepperated the output into files & folders, then called to mod the permissions on each type in two calls. Total thing only uses 3 calls to the API! (More depending on the depth of the dir)

    Thanks again! :)
     
    #6 bdigitalstudios, Jun 13, 2011
    Last edited: Jun 13, 2011
Loading...

Share This Page