NAME
    SysTools::REST - common permissions-checking routines for system tools

SYNOPSIS
      use SysTools::REST;

      # basic CGI usage:
      my $sys = SysTools::REST->new( resid => 'myprogid' );
      my $user = $sys->UserID();
      my $perms = $sys->CheckAccess();
      if ($sys->Permit('someperm') eq 'someval') {
         # ...
      }
      print $sys->HTMLHeader('My Tool');
      # yadda yadda yadda
      print $sys->HTMLFooter();
      $sys->LogEntry('ran my program');

DESCRIPTION
    This module provides a common programming interface to the permissions
    database used for systools.oit.ncsu.edu. The object contains information
    about the current Resource (or program) and the current User who is
    running the program. Calls can be made to retrieve information about the
    Resource or the User; to determine the permissions that the User has on
    the current Resource; or to list Resources available to the User.

    Additionals functions are provided to access shared tool filespaces, to
    generate common HTML formatting, and to log activity message.

    This rewrite makes calls to the REST API on systools.api.ncsu.edu and no
    longer requires direct database access. It also updates the user
    handling to finally remove WRAP references and add OIDC claims.

AUTHOR
            Charles Brabec
            brabec@ncsu.edu

COPYRIGHT
    Copyright (c) 2026 NC State University. All rights reserved. This
    program is free software; you can redistribute it and/or modify it under
    the same terms as Perl itself.

    The full text of the license can be found in the LICENSE file included
    with this module.

SEE ALSO
    perl(1).

PUBLIC METHODS
    Each public function/method is described here. These are how you should
    interact with this module.

  new
     Usage    : my $sys = SysTools::REST->new();
     Purpose  : Create a new SysTools::REST object.
     Returns  : An object in the form of a blessed hash ref.
     Argument : hash or hashref of values to set:
                   resid  => id of this resource
                   userid => id of the user
                   basicauth => MIME-encoded "username:password" for BasicAuth from off campus
                   timeout => REST timeout, default is 10 (seconds)
                   logdir  => override the default LogDir
     Comments : Looks for userid in Shibboleth/OIDC if one is not provided.

  ResID
     Usage    : my $resid = $sys->ResID($newresid);
     Purpose  : Sets or reads the Resource ID assigned to the current object.
     Returns  : The resource ID string
     Argument : The new resource ID to set

  UserID
     Usage    : my $userid = $sys->UserID($newuserid);
     Purpose  : Sets or reads the User ID assigned to the current object.
     Returns  : The user ID string
     Argument : The new user ID to set

  GetUserID
     Usage    : my $userid = $sys->GetUserID();
     Purpose  : Looks for a valid userid from the Shibboleth or OIDC environment variables
     Returns  : The user ID string if a user is found.
     Argument : None.
     Comments : Will not overwrite the existing userid, if no Shibboleth id 
                is found.  Shibboleth user must be in the ncsu.edu scope.
                Will also OIDC (Entra) claims.

  ResourceInfo
     Usage    : my $hashref = $sys->ResourceInfo();
     Purpose  : Reads the resource information from the database
     Returns  : A hash ref of the database entry, or undef on failure
     Argument : None.
     Comments : ResID must be set.
                Useful fields are: name, summary, srcpath, url

  UserInfo
     Usage    : my $hashref = $sys->UserInfo();
     Purpose  : Reads the user information from the database
     Returns  : A hash ref of the database entry, or undef on failure
     Argument : None.
     Comments : UserID must be set.
                Useful fields are: name, dept, notes

  UserGroups
     Usage    : my @grouplist = $sys->UserGroups();
     Purpose  : Reads the user's group membership information from the database
     Returns  : An array of group id's, or undef on failure
     Argument : None.
     Comments : UserID must be set.

  PermTypes
     Usage    : my $hashref = $sys->PermTypes();
     Purpose  : Reads type information about the permssions available for
                current resource
     Returns  : A hash ref of the types keyed by name, or undef on failure
     Argument : None.
     Comments : ResID must be set.

  Permissions
     Usage    : my $hashref = $sys->Permissions();
     Purpose  : Reads the permissions assigned to the current user on the 
                current resource
     Returns  : A hash ref of the permissions, or undef on failure
     Argument : None.
     Comments : ResID must be set, UserID can be blank, for EVERYONE matching.
                Permissions that can have multiple values are returned
                as an array ref to the list.

  Permit
     Usage    : my $value = $sys->Permit($name, $value);
     Purpose  : Check a given permission for the current user and resource
     Returns  : The value or array contents of the given permission.
                If a value is specified, returns 1 or undef.
     Argument : $name is the name of the permission to check, default 'member'
                $value, if provided, will test for a match to that value
     Comments : ResID must be set as required by Permissions.

  ResourceList
     Usage    : my $arrayref = $sys->ResourceList();
     Purpose  : Lists all the resources that permit the current User
     Returns  : A array ref of the resources, or undef on failure
     Argument : None.
     Comments : Each array item is a hashref of {resid, name, summary, url, catid}
                Resources that belong to multiple categories will have 
                one entry for each catid. The list is returned sorted by name.

  FavoritesList
     Usage    : my $arrayref = $sys->FavoritesList();
     Purpose  : Lists all the favorites that the current User has set up
     Returns  : A array ref of the resources, or undef on failure
     Argument : None.
     Comments : Each array item is a hashref of {resid, name, summary, url, catid}
                All favorites have the same catid "favorites", but it is returned
                none-the-less.  The list is returned sorted by preferred ordering.
                It also filters out tools the user doesn't really have access to.

  Categories
  DocumentLink
     Usage    : my $url = $sys->DocumentLink();
     Purpose  : Generates the URL to retrieve documentation for the current
                resource, if there are attached doucments.
     Returns  : A URL string if there are documents, undef otherwise.
     Argument : None.

  LogEntry
     Usage    : $sys->LogEntry($message);
     Purpose  : Write a message to the logfile for this resource
     Returns  : Nothing.
     Argument : $message = entry to write

  OUCHash
     Usage    : my $hash = $sys->OUCHash( $onlylen );
     Purpose  : Returns a hash containing all of the current OUC codes
     Returns  : A hash reference, keyed on OUC code, values are descriptions.
     Argument : $onlylen, limits the results to codes of given length
     Comment  : This function was not ported to the API and thus does not work here.

PUBLIC FUNCTIONS
  deob
     Usage    : my $credentials = deob( 'obfuscated data' );
     Purpose  : Provide an obfuscated method of embedding credentials in code.
     Returns  : The de-obfuscated credential string.
     Argument : A string of obfuscated, hex-encoded data.
     Comments : Code required to generate these strings is not included here.
                This function may be exported.

CGI METHODS
    These functions are to be used by CGI-based system tools.

  HTMLHeader
     Usage    : print $sys->HTMLHeader($title, [ NoBodyTable => 1], %params);
     Purpose  : Generate a standard HTML page header
     Returns  : The top of an HTML page, with CGI headers.
     Argument : $title = title of output page.
                NoBodyTable = optional flag to disable the standard body table
                %params = hash of options that will be passed directly
                to CGI::start_html

  HTMLFooter
     Usage    : print $sys->HTMLFooter( [ NoBodyTable => 1] );
     Purpose  : Generate a standard HTML page footer
     Returns  : The bottom of an HTML page
     Argument : optional flag to disable the default body table

  CheckAccess
     Usage    : my $hashref = $sys->CheckAccess();
     Purpose  : Check for basic access to the current resource,
                return an HTML page if access denied.
     Returns  : Hashref of the user's permissions.
     Argument : None.

REST METHODS
    These functions are used internally to talk to the REST API. They can
    also be called externally if needed.

  GetREST
     Usage    : my $results = $sys->GetREST($uri);
     Purpose  : Perform a REST GET request on the SysTools API
     Returns  : The data object returned from the API, in a perl variable.
     Argument : $uri is the API path and any query options

PRIVATE METHODS
    Each private function/method is described here. These methods and
    functions are considered private and are intended for internal use by
    this module. They are not considered part of the public interface and
    are described here for documentation purposes only.

  _OpenRESTClient
     Usage    : my $client = $sys->_OpenRESTClient;
     Purpose  : Opens a new object for API calls
     Returns  : A REST::Client object
     Argument : The object that will keep the handle.
     Comments : May overwrite an existing client without checking.

  _PostError
     Usage    : $sys->_PostError($type, $message);
     Purpose  : Gracefully handle errors, warnings, debug messages
     Returns  : Nothing.
     Argument : $type    = what type of error was found
                $message = plain text description of the error
     Comments : $type  = 0 - fatal error
                $type  = 1 - warning error
                $type >= 2 - debug messages

