COM-FSM

DependencyErrors

Page last modified 14:15, 31 Oct 2010 by Admin
    Table of contents
    No headers

    Version as of 03:25, 22 Nov 2024

    to this version.

    Return to Version archive.

    View current version

    /***
        USAGE:
        
        DependencyErrors(components, license, permissions)
    
        PARAMETERS:
        
        components : list of maps, [{}, {}, {}, ...]
            Components to test. Each component defines
                name => component name or capability to test for
                sid => Service ID (sid) to check for in license. If present, does a service check.
                requires => Capability to check in the license. If present, does a capability check. 
                (optional) title => User-friendly component name
                (optional) link => Link for more information in case of error
        
        (optional) license : str (default: nil)
            Site license type to check for; one of 'commercial' or nil
    
        (optional) permission : str (default: nil)
            Permissions required for current user; one of 'admin' or nil
        
        VERSIONS:
        
        1.0     15-Jun-10    kalida     initial version
        1.1     15-Jul-10    kalida     added capability checks 
    
    ***/
    
    var components = $0 ?? $components ?? [];
    var license = $1 ?? $license ?? nil;
    var permission = $2 ?? $permission ?? nil;
    
    var licenseError = nil;
    var permissionError = nil;
    var componentErrors = nil;
    
    // general data lookups
    var licenseXML = wiki.api(site.api & 'license');
    
    // if no explicit expiration, use a far-future date
    var licenseExpires = xml.date(licenseXML, 'date.expiration') ?? date.addyears(date.now, 100);
    var prefix = 'mindtouch.templates.dependencyerrors.';
    var sidList = [];
    
    // gather existing licensed services
    foreach (var serviceLicense in licenseXML['grants/service-license']) {
        var sid = string.Match(xml.text(serviceLicense), 'sid="(.*?)"');
    
        // if valid sid, add with expiration date 
        if (#sid > 0) {
            var sidExpires = licenseExpires;
    
            // attempt to find expiration date in text or as attribute
            var expires = string.Match(xml.text(serviceLicense), 'expire="(.*?)"');
    
            if (#expires > 0) {
                let sidExpires = date.parse(expires);
            } else if (#xml.text(serviceLicense, '@date.expire') > 0) {
                let sidExpires = xml.date(serviceLicense, '@date.expire');
            }
    
            let sidList = sidList .. [{sid: sid, expires: sidExpires}];
        }
    }
    
    // gather licensed capabilities
    var capabilityGrants = {};
    foreach (var grant in licenseXML['grants/*[not(name()="service-license")]']) {
        var grantName = xml.name(grant);
        var grantValue = xml.text(grant);
        let capabilityGrants = capabilityGrants .. { (grantName): grantValue};
    }
    
    // check license
    if (license == 'commercial') {
        var currentLicense = xml.text(licenseXML, '@type');
    
        if (license != currentLicense && currentLicense != 'trial') {
            let licenseError = wiki.localize(prefix .. 'error.license');
        }
        else if (date.Compare(date.now, licenseExpires) > 0 ) {
            let licenseError = wiki.localize(prefix .. 'error.license.expired');
        }
    }
    
    // check user permissions
    if (permission == 'admin') {
        if (!user.admin) {
            let permissionError = wiki.localize(prefix .. 'error.permission');
        }
    }
    
    // check components
    foreach (var component in components) {
        var errorMessage = nil;
        var title = component.title ?? component.name;
        var link = component.link ?? 'http://www.mindtouch.com/redir/dependency/';
    
        // if component.requires available is a cabality check
        var serviceCheck = component.requires is nil;
    
        // admins are able to check if service licensed
        if (user.admin && component.sid && serviceCheck) {
    
            // component is valid if any licensed sid is a prefix match
            var foundLicense = false;
            var expiredLicense = false;
            foreach (var sidItem in sidList) {
                if (string.StartsWith(component.sid, sidItem.sid)) {
                    let foundLicense = true;
                
                    if (date.Compare(date.now, sidItem.expires) > 0 ) {
                        let expiredLicense = true;
                    }
    
                    // found component, avoid searching others
                    break;
                }
            }
    
            if (!foundLicense) {
                let errorMessage = <a href=(link) rel="component-unlicensed">wiki.localize(prefix .. 'error.component.unlicensed', [title])</a>
            } else if (expiredLicense) {
                let errorMessage = <a href=(link) rel="component-expired">wiki.localize(prefix .. 'error.component.expired', [title])</a>
            }
        }
    
        // name is required
        if (!component.name) {
            let errorMessage = wiki.localize(prefix .. 'error.component.unnamed');
        }
        else if (!errorMessage && !__env[component.name] && serviceCheck) {
    
            // @TODO kalida: in future, have separate checks for not installed vs. not running
            let errorMessage = <a href=(link) rel="component-missing">wiki.localize(prefix .. 'error.component.missing', [title])</a>
        }
    
        // if capability check, ensure it is granted 
        if (!serviceCheck && capabilityGrants[component.name] != component.requires) {
            var currentValue = capabilityGrants[component.name] ?? wiki.localize(prefix .. 'error.capability.missing.default');
            let errorMessage = <a href=(link) rel="capability-missing">
                wiki.localize(prefix .. 'error.capability.missing', [title, component.requires, currentValue])
                </a>;
        }
    
        // add this error to the list
        if (errorMessage) {
            let componentErrors = componentErrors .. [{component: component, message: errorMessage}];
        }
    }
    
    // list missing dependencies
    if (licenseError) {
        <div class="error-dependency error-license">
            licenseError;
        </div>
    } else if (permissionError) {
        <div class="error-dependency error-permission">
            permissionError;
        </div>
    } else if (componentErrors) {
        <div class="error-dependency error-component">
            wiki.localize(prefix .. 'label.components.error');
            <ul>
                foreach (var error in componentErrors) {
                    <li class=(error.component.name)>
                        error.message;
                    </li>
                }
            </ul>
        </div>
    }
    Powered by MindTouch Core