Esempio n. 1
0
 //--- Methods ---
 public string GetCapability(XDoc licenseDoc, string name)
 {
     return(DekiLicense.GetCapability(licenseDoc, name));
 }
Esempio n. 2
0
        private IEnumerator <IYield> UpdatePackages_Helper(Plug api, string wikiId, string apikey, bool force, bool init, Result <XDoc> result)
        {
            try {
                _status = PackageUpdaterStatus.Importing;
                yield return(Coroutine.Invoke(AuthenticateImportUser, api, wikiId, apikey, new Result <Plug>()).Set(x => api = x));

                XDoc license = null;
                yield return(api.At("license").With("apikey", apikey).Get(new Result <XDoc>()).Set(x => license = x));

                var importReport = new XDoc("packages");
                var first        = true;
                foreach (var directory in Directory.GetDirectories(_templatePackagePath))
                {
                    var    directoryName = Path.GetFileName(directory);
                    string restriction   = null;
                    if (directoryName.EqualsInvariantIgnoreCase("public"))
                    {
                        restriction = "Public";
                    }
                    else if (directoryName.EqualsInvariantIgnoreCase("semi-public"))
                    {
                        restriction = "Semi-Public";
                    }
                    else if (directoryName.EqualsInvariantIgnoreCase("private"))
                    {
                        restriction = "Private";
                    }
                    foreach (var package in Directory.GetFiles(directory, "*.mt*").OrderBy(x => x))
                    {
                        var ext = Path.GetExtension(package);
                        if (!(ext.EqualsInvariantIgnoreCase(".mtarc") || ext.EqualsInvariantIgnoreCase(".mtapp")))
                        {
                            continue;
                        }
                        if (!first)
                        {
                            importReport.End();
                        }
                        first = false;
                        importReport.Start("package").Elem("path", package);
                        ArchivePackageReader packageReader;
                        _log.DebugFormat("contemplating import of '{0}' for '{1}'", package, wikiId);
                        try {
                            packageReader = new ArchivePackageReader(package);
                        } catch (Exception e) {
                            SetError(importReport, wikiId, "error", e, "Unable to open package.");
                            continue;
                        }
                        Result <XDoc> manifestResult;
                        yield return(manifestResult = packageReader.ReadManifest(new Result <XDoc>()).Catch());

                        if (manifestResult.HasException)
                        {
                            SetError(importReport, wikiId, "error", manifestResult.Exception, "Unable to read package manifest.");
                            continue;
                        }
                        var manifest = manifestResult.Value;

                        // check for required capabilities
                        var capabilitiesSatisfied = true;
                        foreach (var capability in manifest["capability"])
                        {
                            var capabilityName  = capability["@name"].AsText;
                            var capabilityValue = capability["@value"].AsText.IfNullOrEmpty("enabled");
                            if (string.IsNullOrEmpty(capabilityName))
                            {
                                continue;
                            }
                            var licenseCapabilityValue = DekiLicense.GetCapability(license, capabilityName) ?? "";
                            if (!string.IsNullOrEmpty(capabilityName) && licenseCapabilityValue.EqualsInvariant(capabilityValue))
                            {
                                continue;
                            }
                            capabilitiesSatisfied = false;
                            SetError(importReport, wikiId, "error", null, "Missing capability '{0}' or incorrect capability value, expected '{1}' and got '{2}'.", capabilityName, capabilityValue, licenseCapabilityValue);
                        }
                        if (!capabilitiesSatisfied)
                        {
                            continue;
                        }

                        // add security xml if we are in a restriction enforcing path
                        if (!string.IsNullOrEmpty(restriction))
                        {
                            manifest.Start("security")
                            .Start("permissions.page")
                            .Elem("restriction", restriction)
                            .End()
                            .End();
                        }

                        // if package predates @date.created, take file modified
                        var dateCreated = manifest["@date.created"].AsDate ?? new FileInfo(package).LastWriteTime;

                        // check whether we should import this package
                        var filename    = Path.GetFileName(package);
                        var importOnce  = manifest["@import-once"].AsBool ?? false;
                        var initPackage = manifest["@init-only"].AsBool ?? false;
                        importReport.Elem("name", filename).Attr("date.created", dateCreated).Attr("preserve-local", manifest["@preserve-local"].AsBool ?? false);
                        var importPropertyName = XUri.EncodeSegment(PACKAGE_PROPERTY_NS + filename);
                        if (initPackage && !init && !force)
                        {
                            SetError(importReport, wikiId, "skipped", null, "package '{0}' is an init package and neither init or force flags were set, skipping", package);
                            continue;
                        }
                        if (force && !importOnce)
                        {
                            _log.DebugFormat("force is set and package '{0}' is not marked as oneTimeOnly, proceeding with import", package);
                        }
                        else
                        {
                            DreamMessage propertyResponse = null;
                            yield return(api.At("site", "properties", importPropertyName).Get(new Result <DreamMessage>()).Set(x => propertyResponse = x));

                            if (propertyResponse.IsSuccessful)
                            {
                                var importedPackage     = propertyResponse.ToDocument();
                                var importedPackageDate = importedPackage["date.created"].AsDate;
                                if (!importedPackageDate.HasValue)
                                {
                                    _log.WarnFormat("unable to retrieve imported package date.created for '{0}', treating package as new", package);
                                }
                                else if (dateCreated > importedPackageDate.Value)
                                {
                                    _log.DebugFormat("package '{0}' is newer, proceed with import ({1} > {2}", package, dateCreated, importedPackageDate.Value);
                                }
                                else
                                {
                                    SetError(importReport, wikiId, "skipped", null,
                                             "package '{0}' is not newer, skip import ({1} <= {2}.)",
                                             package,
                                             dateCreated,
                                             importedPackageDate.Value);
                                    continue;
                                }
                            }
                            else if (propertyResponse.Status == DreamStatus.Unauthorized)
                            {
                                _log.WarnFormat("apiuri has lost its authentication, dropping out");
                                throw new UnauthorizedAccessException("Authentication for was lost");
                            }
                            else
                            {
                                _log.DebugFormat("package '{0}' has not previously been imported, proceeding with import", package);
                            }
                        }

                        // import package
                        Result <Importer> importerResult;
                        yield return(importerResult = Importer.CreateAsync(api, manifest, "/", new Result <Importer>()).Catch());

                        if (importerResult.HasException)
                        {
                            SetError(importReport, wikiId, "error", importerResult.Exception, "Unable to create importer for package.");
                            continue;
                        }
                        var    importer      = importerResult.Value;
                        var    importManager = new ImportManager(importer, packageReader);
                        Result importResult;
                        yield return(importResult = importManager.ImportAsync(new Result()).Catch());

                        if (importResult.HasException)
                        {
                            SetError(importReport, wikiId, "error", importResult.Exception, "Import did not complete successfully.");
                            continue;
                        }

                        // write import data as site property
                        yield return(api.At("site", "properties", importPropertyName)
                                     .With("abort", "never")
                                     .With("description", string.Format("Import of package '{0}'", filename))
                                     .Put(new XDoc("package").Elem("date.created", dateCreated), new Result <DreamMessage>()));

                        importReport.Start("status").Attr("code", "ok").End();
                        _log.DebugFormat("sucessfully imported package '{0}'", package);
                    }
                }
                if (!first)
                {
                    importReport.End();
                }
                result.Return(importReport);
                yield break;
            } finally {
                _status = PackageUpdaterStatus.Idle;
            }
        }
Esempio n. 3
0
        public LicenseData BuildLicenseData(XDoc license, bool verifyProductKey, bool seatLicensingEnabled)
        {
            var builtLicense = new LicenseData().WithLicenseDocument(license);

            // check if a valid license was passed in
            if (license.IsEmpty)
            {
                _log.Debug("license document was empty");
                return(builtLicense);
            }

            // check if the deki assembly is signed
            var assembly = typeof(DekiWikiService).Assembly;

            if (ArrayUtil.IsNullOrEmpty(assembly.GetName().GetPublicKey()))
            {
                // no signature, default to community
                _log.Warn("Unable to validate signature of license since the MindTouch Core service was not signed by MindTouch. Reverting to community edition.");
                return(builtLicense.WithState(LicenseStateType.COMMUNITY).WithPermissions(PermissionSets.ALL));
            }

            // assembly is signed: validate xml signature
            var rsa = RSAUtil.ProviderFrom(assembly);

            if ((rsa == null) || !license.HasValidSignature(rsa))
            {
                _log.Warn("License failed XML validation");
                return(builtLicense.WithState(LicenseStateType.INVALID));
            }

            // check license matched product key
            var productKey = license["licensee/product-key"].AsText;

            // license product key may be generated based on either the instance or master apikeys
            if (verifyProductKey && !IsValidProductKey(productKey, _instanceApiKey) && !IsValidProductKey(productKey, _masterApiKey))
            {
                _log.Warn("Invalid product-key in license");
                return(builtLicense.WithState(LicenseStateType.INVALID));
            }

            // determine license type
            switch (license["@type"].AsText ?? "inactive")
            {
            case "trial":
                builtLicense = builtLicense.WithState(LicenseStateType.TRIAL);
                break;

            case "inactive":
                builtLicense = builtLicense.WithState(LicenseStateType.INACTIVE);
                break;

            case "community":
                builtLicense = builtLicense.WithState(LicenseStateType.COMMUNITY);
                break;

            case "commercial":
                builtLicense = builtLicense.WithState(LicenseStateType.COMMERCIAL);
                break;

            default:
                _log.Warn("Unknown license type");
                builtLicense = builtLicense.WithState(LicenseStateType.INVALID);
                break;
            }

            // check expiration
            builtLicense = builtLicense.WithExpiration(license["date.expiration"].AsDate ?? DateTime.MaxValue);
            if (builtLicense.LicenseState == LicenseStateType.COMMERCIAL)
            {
                // check if license is passed grace period
                if (builtLicense.LicenseExpiration <= DateTime.UtcNow.AddDays(-GRACE_PERIOD))
                {
                    _log.DebugFormat("commercial license has expired and is past grace period: {0}", builtLicense.LicenseExpiration);
                    return(builtLicense.WithState(LicenseStateType.EXPIRED));
                }
                _log.DebugFormat("commercial license has not expired or is at least not past grace period: {0}", builtLicense.LicenseExpiration);
            }
            else if (builtLicense.LicenseExpiration <= DateTime.UtcNow)
            {
                _log.DebugFormat("non-commercial license has expired: {0}", builtLicense.LicenseExpiration);
                return(builtLicense.WithState(LicenseStateType.EXPIRED));
            }

            // check version
            var licenseVersion  = (license["version"].AsText ?? "*").Split('.');
            var assemblyVersion = typeof(LicenseBL).Assembly.GetName().Version;
            var appVersion      = new[] { assemblyVersion.Major, assemblyVersion.Minor, assemblyVersion.Revision, assemblyVersion.Build };

            for (var i = 0; (i < licenseVersion.Length) && (i < appVersion.Length); ++i)
            {
                var pattern = licenseVersion[i];
                int value;
                if (pattern.Equals("*") || (int.TryParse(pattern, out value) && (value >= appVersion[i])))
                {
                    continue;
                }
                return(builtLicense.WithState(LicenseStateType.EXPIRED));
            }

            // determine permissions for anonymous user
            builtLicense = builtLicense.WithPermissions(PermissionsBL.MaskFromString(DekiLicense.GetCapability(license, "anonymous-permissions")) | PermissionSets.MINIMAL_ANONYMOUS_PERMISSIONS);

            // retrieve the site owner from the license
            var siteOwnerUserId = GetSiteOwnerUserId(license);

            if (seatLicensingEnabled && (siteOwnerUserId ?? 0) == 0)
            {
                throw new MindTouchLicenseNoSiteOwnerDefinedException();
            }
            return(builtLicense.WithSiteOwnerUserId(siteOwnerUserId));
        }