//--- Methods --- public string GetCapability(XDoc licenseDoc, string name) { return(DekiLicense.GetCapability(licenseDoc, name)); }
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; } }
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)); }