public async Task OD_FIX_NameEncoding_CreateAndRename() { await IsolatedODataTestAsync(async() => { var testRoot = CreateTestRoot("ODataTestRoot"); var guid = Guid.NewGuid().ToString().Replace("-", ""); var name = "*_|" + guid; var encodedName = ContentNamingProvider.GetNameFromDisplayName(name); var newName = ContentNamingProvider.GetNameFromDisplayName("___" + guid); // ACTION 1: Create var json = string.Concat(@"models=[{""Name"":""", name, @"""}]"); var response = await ODataPostAsync("/OData.svc/" + testRoot.Path, "", json).ConfigureAwait(false);; // ASSERT 1 AssertNoError(response); var entity = GetEntity(response); Assert.AreEqual(encodedName, entity.Name); // ACTION 2: Rename json = string.Concat(@"models=[{""Name"":""", newName, @"""}]"); response = await ODataPatchAsync("/OData.svc/" + testRoot.Path, "", json).ConfigureAwait(false);; // ASSERT 2 AssertNoError(response); entity = GetEntity(response); var node = Node.LoadNode(entity.Id); Assert.AreEqual(newName, node.Name); }).ConfigureAwait(false);; }
protected async Task <User> CreateUser(string nameCandidate, string loginName, string email, string fullName, Action <Content> setProperties, CancellationToken cancellationToken) { var parentPath = string.IsNullOrEmpty(_options.ParentPath) ? "/Root/IMS/Public" : _options.ParentPath; var userType = string.IsNullOrEmpty(_options.UserType) ? "User" : _options.UserType; var parent = RepositoryTools.CreateStructure(parentPath, "Domain") ?? await Content.LoadAsync(parentPath, cancellationToken).ConfigureAwait(false); // If a user with the same name exists, make sure we create // a new one and let the application deal with merging them later. var name = ContentNamingProvider.GetNameFromDisplayName(nameCandidate); if (Node.Exists(RepositoryPath.Combine(parent.Path, name))) { name = ContentNamingProvider.IncrementNameSuffixToLastName(name, parent.Id); } var user = Content.CreateNew(userType, parent.ContentHandler, name); user["LoginName"] = loginName; user["Email"] = email; user["FullName"] = string.IsNullOrEmpty(fullName) ? name : fullName; user.DisplayName = string.IsNullOrEmpty(fullName) ? name : fullName; user["Enabled"] = true; setProperties?.Invoke(user); user.Save(); await AddUserToDefaultGroupsAsync(user.ContentHandler as User, cancellationToken).ConfigureAwait(false); return(user.ContentHandler as User); }
// ======================================================================== POTENTIAL Virtual methods protected async Task <Content> GetContentAsync(Content parent, string fileName, string contentTypeName, bool overwrite, CancellationToken cancellationToken) { var contentname = ContentNamingProvider.GetNameFromDisplayName(fileName); var path = RepositoryPath.Combine(Content.Path, contentname); Content content; if (overwrite) { // check if content exists content = await Content.LoadAsync(path, cancellationToken).ConfigureAwait(false); if (content != null) { SetPreviewGenerationPriority(content); return(content); } } // create new content content = Content.CreateNew(contentTypeName, parent.ContentHandler, contentname); // prevent autonaming feature in case of preview images if (string.Compare(contentTypeName, DocumentPreviewProvider.PREVIEWIMAGE_CONTENTTYPE, StringComparison.InvariantCultureIgnoreCase) != 0) { content.ContentHandler.AllowIncrementalNaming = true; } SetPreviewGenerationPriority(content); return(content); }
// ========================================================================================= Helper methods private static void AddContentListField(ContentRepository.Content content) { if (content == null) { return; } var contentList = ContentList.GetContentListByParentWalk(content.ContentHandler); if (contentList == null) { return; } // build longtext field for custom status messages var fs = new LongTextFieldSetting { ShortName = "LongText", Name = "#" + ContentNamingProvider.GetNameFromDisplayName(content.Name, content.DisplayName) + "_status", DisplayName = content.DisplayName + " status", Icon = content.Icon }; contentList.AddOrUpdateField(fs); }
protected override void Execute(NativeActivityContext context) { var displayName = ContentDisplayName.Get(context); var originalName = ContentOriginalName.Get(context); var newName = ContentNamingProvider.GetNameFromDisplayName(originalName, displayName); Result.Set(context, newName); }
protected override void Execute(NativeActivityContext context) { var parent = Node.LoadNode(ParentPath.Get(context)); if (parent == null) { throw new ApplicationException("Cannot create content because parent does not exist. Path: " + ParentPath.Get(context)); } var name = Name.Get(context); var displayName = ContentDisplayName.Get(context); if (string.IsNullOrEmpty(name)) { name = ContentNamingProvider.GetNameFromDisplayName(displayName); } var content = CreateContentInternal(GetContentTypeName(context), name, ParentPath.Get(context)); if (!string.IsNullOrEmpty(displayName)) { content.DisplayName = displayName; } var fieldValues = FieldValues.Get(context); if (fieldValues != null) { foreach (var key in fieldValues.Keys) { content[key] = fieldValues[key]; } } SetContentFields(content, context); content.ContentHandler.DisableObserver(typeof(WorkflowNotificationObserver)); try { content.Save(); } catch (Exception e) { throw new ApplicationException(String.Concat("Cannot create content. See inner exception. Expected path: " , ParentPath.Get <string>(context), "/", Name.Get(context)), e); } Result.Set(context, new WfContent(content.ContentHandler)); }
public void ContentNaming_FromDisplayName() { var providers = new[] { (ContentNamingProvider) new CharReplacementContentNamingProvider(), (ContentNamingProvider) new Underscore5FContentNamingProvider() }; var contentNamingProviderAcc = new PrivateType(typeof(ContentNamingProvider)); var originalProvider = contentNamingProviderAcc.GetStaticField("__instance"); try { foreach (var provider in providers) { contentNamingProviderAcc.SetStaticField("__instance", provider); var providerName = provider.GetType().Name; Assert.AreEqual("árvíztűrőtükörfúrógép", ContentNamingProvider.GetNameFromDisplayName("árvíztűrőtükörfúrógép")); Assert.AreEqual("ÁRVÍZTŰRŐTÜKÖRFÚRÓGÉP", ContentNamingProvider.GetNameFromDisplayName("ÁRVÍZTŰRŐTÜKÖRFÚRÓGÉP")); Assert.AreEqual("ÁrvíztűrőTükörfúrógép", ContentNamingProvider.GetNameFromDisplayName("ÁrvíztűrőTükörfúrógép")); Assert.AreEqual("árvíztűrőtükörfúrógép.txt", ContentNamingProvider.GetNameFromDisplayName("árvíztűrőtükörfúrógép.txt")); Assert.AreEqual("árvíztűrőtükörfúrógép.doc.txt", ContentNamingProvider.GetNameFromDisplayName("árvíztűrőtükörfúrógép.txt", "árvíztűrőtükörfúrógép.doc")); Assert.AreEqual("árvíztűrőtükörfúrógép.doc.txt", ContentNamingProvider.GetNameFromDisplayName(".txt", "árvíztűrőtükörfúrógép.doc")); var name = ContentNamingProvider.GetNameFromDisplayName("!*_~@#$%a^&()b{}+\"'|:<>?c/.,"); if (providerName == typeof(CharReplacementContentNamingProvider).Name) { Assert.AreEqual("!-_-a-()b-c", name); } else if (providerName == typeof(Underscore5FContentNamingProvider).Name) { Assert.AreEqual("!_2a_5f_7e_40_23_24_25a_5e_26()b_7b_7d_2b_22_27_7c_3a_3c_3e_3fc_2f._2c", name); } else { Assert.Inconclusive("Unknown ContentNamingProvider: " + providerName); } } } finally { contentNamingProviderAcc.SetStaticField("__instance", originalProvider); } }
public async Task <User> CreateProviderUserAsync(Content content, HttpContext context, string provider, string userId, ClaimInfo[] claims, CancellationToken cancellationToken) { var parentPath = string.IsNullOrEmpty(DefaultParentPath) ? "/Root/IMS/Public" : DefaultParentPath; var userType = string.IsNullOrEmpty(DefaultUserType) ? "User" : DefaultUserType; var parent = RepositoryTools.CreateStructure(parentPath, "Domain") ?? await Content.LoadAsync(parentPath, cancellationToken).ConfigureAwait(false); var fullName = claims.FirstOrDefault(c => c.Type == ClaimTypes.Name)?.Value ?? string.Empty; var email = claims.FirstOrDefault(c => c.Type == ClaimTypes.Email)?.Value ?? string.Empty; // Fill the field with an initial JSON data containing a single provider data. // Later, if the user already exists, this field needs to be edited: the new id // should be inserted instead of overwriting the current value. var external = $"{{ \"{provider}\": {{ \"Id\": \"{userId}\", \"Completed\": false }} }}"; // User content name will be the email. // Current behavior: if a user with the same name exists, make sure we create // a new one and let the application deal with merging them later. var name = ContentNamingProvider.GetNameFromDisplayName(email); if (Node.Exists(RepositoryPath.Combine(parent.Path, name))) { name = ContentNamingProvider.IncrementNameSuffixToLastName(name, parent.Id); } var user = Content.CreateNew(userType, parent.ContentHandler, name); user["ExternalUserProviders"] = external; user["Email"] = email; user["FullName"] = fullName; user.DisplayName = fullName; user.Save(); await AddUserToDefaultGroupsAsync(user.ContentHandler as User, cancellationToken).ConfigureAwait(false); return(user.ContentHandler as User); }
public void ContentNaming_FromDisplayName() { var namingProviders = new[] { (ContentNamingProvider) new CharReplacementContentNamingProvider(), (ContentNamingProvider) new Underscore5FContentNamingProvider() }; foreach (var namingProvider in namingProviders) { var services = new ServiceCollection() .AddSingleton <IContentNamingProvider>(namingProvider) .BuildServiceProvider(); Providers.Instance = new Providers(services); var providerName = namingProvider.GetType().Name; Assert.AreEqual("árvíztűrőtükörfúrógép", ContentNamingProvider.GetNameFromDisplayName("árvíztűrőtükörfúrógép")); Assert.AreEqual("ÁRVÍZTŰRŐTÜKÖRFÚRÓGÉP", ContentNamingProvider.GetNameFromDisplayName("ÁRVÍZTŰRŐTÜKÖRFÚRÓGÉP")); Assert.AreEqual("ÁrvíztűrőTükörfúrógép", ContentNamingProvider.GetNameFromDisplayName("ÁrvíztűrőTükörfúrógép")); Assert.AreEqual("árvíztűrőtükörfúrógép.txt", ContentNamingProvider.GetNameFromDisplayName("árvíztűrőtükörfúrógép.txt")); Assert.AreEqual("árvíztűrőtükörfúrógép.doc.txt", ContentNamingProvider.GetNameFromDisplayName("árvíztűrőtükörfúrógép.txt", "árvíztűrőtükörfúrógép.doc")); Assert.AreEqual("árvíztűrőtükörfúrógép.doc.txt", ContentNamingProvider.GetNameFromDisplayName(".txt", "árvíztűrőtükörfúrógép.doc")); var name = ContentNamingProvider.GetNameFromDisplayName("!*_~@#$%a^&()b{}+\"'|:<>?c/.,"); if (providerName == typeof(CharReplacementContentNamingProvider).Name) { Assert.AreEqual("!-_-a-()b-c", name); } else if (providerName == typeof(Underscore5FContentNamingProvider).Name) { Assert.AreEqual("!_2a_5f_7e_40_23_24_25a_5e_26()b_7b_7d_2b_22_27_7c_3a_3c_3e_3fc_2f._2c", name); } else { Assert.Inconclusive("Unknown ContentNamingProvider: " + providerName); } } }
/// <summary> /// Helper method for updating the given <see cref="Content"/> with a model represented by JObject. /// The <see cref="Content"/> will not be saved. /// </summary> /// <param name="content">The <see cref="Content"/> that will be modified. Cannot be null.</param> /// <param name="model">The modifier JObject instance. Cannot be null.</param> public static void UpdateFields(Content content, JObject model) { if (content == null) { throw new ArgumentNullException(nameof(content)); } if (model == null) { throw new ArgumentNullException(nameof(model)); } var isNew = content.Id == 0; foreach (var prop in model.Properties()) { if (string.IsNullOrEmpty(prop.Name) || prop.Name == "__ContentType" || prop.Name == "__ContentTemplate" || prop.Name == "Type" || prop.Name == "ContentType") { continue; } var hasField = content.Fields.TryGetValue(prop.Name, out var field); if (!hasField && content.SupportsAddingFieldsOnTheFly && (prop.Value as JValue)?.Value != null) { var value = ((JValue)prop.Value).Value; var fieldSetting = FieldSetting.InferFieldSettingFromType(value.GetType(), prop.Name); var meta = new FieldMetadata(true, true, prop.Name, prop.Name, fieldSetting); hasField = content.AddFieldsOnTheFly(new[] { meta }) && content.Fields.TryGetValue(prop.Name, out field); } if (hasField) { if (!field.ReadOnly) { if (prop.Value is JValue jvalue) { if (field is IntegerField) { field.SetData(Convert.ToInt32(jvalue.Value)); continue; } if (field is DateTimeField && jvalue.Value == null) { continue; } if (isNew && field is ReferenceField && jvalue.Value == null) { if (field.Name == "CreatedBy" || field.Name == "ModifiedBy") { continue; } } if (field is ReferenceField && jvalue.Value != null) { var refNode = jvalue.Type == JTokenType.Integer ? Node.LoadNode(Convert.ToInt32(jvalue.Value)) : Node.LoadNode(jvalue.Value.ToString()); field.SetData(refNode); continue; } if (isNew && field.Name == "Name" && jvalue.Value != null) { field.SetData(ContentNamingProvider.GetNameFromDisplayName(jvalue.Value.ToString())); continue; } field.SetData(jvalue.Value); continue; } if (prop.Value is JObject) { //TODO: ODATA: setting field when posted value is JObject. // field.SetData(jvalue.Value); continue; } if (prop.Value is JArray avalue) { if (field is ReferenceField) { var refValues = avalue.Values().ToList(); if (refValues.Count == 0) { field.SetData(null); continue; } var fsetting = field.FieldSetting as ReferenceFieldSetting; var nodes = refValues.Select(rv => rv.Type == JTokenType.Integer ? Node.LoadNode(Convert.ToInt32(rv.ToString())) : Node.LoadNode(rv.ToString())); if (fsetting?.AllowMultiple != null && fsetting.AllowMultiple.Value) { field.SetData(nodes); } else { field.SetData(nodes.First()); } } else if (field is ChoiceField) { // ChoiceField expects the value to be of type List<string> var list = new List <string>(); foreach (var token in avalue) { if (token is JValue value) { list.Add(value.Value.ToString()); } else { throw new Exception( $"Token type {token.GetType().Name} for field {field.Name} (type {field.GetType().Name}) is not supported."); } } field.SetData(list); } else if (field is AllowedChildTypesField && field.Name == "AllowedChildTypes" && content.ContentHandler is GenericContent gc) { var types = avalue.Values().Select(rv => { switch (rv.Type) { case JTokenType.Integer: return(Node.LoadNode(Convert.ToInt32(rv.ToString())) as ContentType); default: var typeId = rv.ToString(); if (RepositoryPath.IsValidPath(typeId) == RepositoryPath.PathResult.Correct) { return(Node.LoadNode(typeId) as ContentType); } return(ContentType.GetByName(typeId)); } }).Where(ct => ct != null).ToArray(); gc.SetAllowedChildTypes(types); } continue; } throw new SnNotSupportedException(); } } } }
private Content CreateContent(JObject model, ODataRequest odataRequest) { var contentTypeName = GetPropertyValue <string>("__ContentType", model); var templateName = GetPropertyValue <string>("__ContentTemplate", model); var name = GetPropertyValue <string>("Name", model); if (string.IsNullOrEmpty(name)) { var displayName = GetPropertyValue <string>("DisplayName", model); name = ContentNamingProvider.GetNameFromDisplayName(displayName); } else { // do not allow saving a content with unencoded name name = ContentNamingProvider.GetNameFromDisplayName(name); } var parent = Node.Load <GenericContent>(odataRequest.RepositoryPath); if (string.IsNullOrEmpty(contentTypeName)) { var allowedChildTypeNames = parent.GetAllowedChildTypeNames(); if (allowedChildTypeNames is AllContentTypeNames) { contentTypeName = typeof(ContentRepository.File).Name; } else { var allowedContentTypeNames = parent.GetAllowedChildTypeNames().ToArray(); contentTypeName = allowedContentTypeNames.FirstOrDefault(); if (string.IsNullOrEmpty(contentTypeName)) { contentTypeName = typeof(ContentRepository.File).Name; } } } Content content; Node template = null; if (templateName != null) { template = ContentTemplate.GetNamedTemplate(contentTypeName, templateName); } if (template == null) { content = Content.CreateNew(contentTypeName, parent, name); } else { var templated = ContentTemplate.CreateFromTemplate(parent, template, name); content = Content.Create(templated); } UpdateFields(content, model); if (odataRequest.MultistepSave) { content.Save(SavingMode.StartMultistepSave); } else { content.Save(); } return(content); }
protected override void Execute(NativeActivityContext context) { var message = Message.Get(context); var parentPath = ParentPath.Get(context); var overwrite = OverwriteExistingContent.Get(context); var displayName = ContentDisplayName.Get(context); var name = ContentName.Get(context); if (string.IsNullOrEmpty(name)) { name = ContentNamingProvider.GetNameFromDisplayName(displayName) + ".eml"; } var parent = Node.LoadNode(parentPath); if (parent == null) { throw new ApplicationException("Cannot create content because parent does not exist. Path: " + parentPath); } // check existing file var node = Node.LoadNode(RepositoryPath.Combine(parentPath, name)); File file; if (node == null) { // file does not exist, create new one file = new File(parent); if (!string.IsNullOrEmpty(displayName)) { file.DisplayName = displayName; } file.Name = name; } else { // file exists if (overwrite) { // overwrite it, so we open it file = node as File; // node exists and it is not a file -> delete it and create a new one if (file == null) { node.ForceDelete(); file = new File(parent); } file.DisplayName = displayName; file.Name = name; } else { // do not overwrite it file = new File(parent); if (!string.IsNullOrEmpty(displayName)) { file.DisplayName = displayName; } file.Name = name; file.AllowIncrementalNaming = true; } } try { using (var memoryStream = new System.IO.MemoryStream(message.MimeContent.Content)) { var binaryData = new BinaryData(); binaryData.SetStream(memoryStream); file.Binary = binaryData; file.Save(); } } catch (Exception ex) { SnLog.WriteException(ex); } }
public static void UpdateFields(Content content, JObject model) { Field field; var isNew = content.Id == 0; foreach (var prop in model.Properties()) { if (string.IsNullOrEmpty(prop.Name) || prop.Name == "__ContentType" || prop.Name == "__ContentTemplate" || prop.Name == "Type" || prop.Name == "ContentType") { continue; } var hasField = content.Fields.TryGetValue(prop.Name, out field); if (!hasField && content.SupportsAddingFieldsOnTheFly && prop.Value is JValue && ((JValue)prop.Value).Value != null) { var value = ((JValue)prop.Value).Value; var fieldSetting = FieldSetting.InferFieldSettingFromType(value.GetType(), prop.Name); var meta = new FieldMetadata(true, true, prop.Name, prop.Name, fieldSetting); hasField = content.AddFieldsOnTheFly(new[] { meta }) && content.Fields.TryGetValue(prop.Name, out field); } if (hasField) { if (!field.ReadOnly) { var jvalue = prop.Value as JValue; if (jvalue != null) { if (field is IntegerField) { field.SetData(Convert.ToInt32(jvalue.Value)); continue; } if (field is DateTimeField && jvalue.Value == null) { continue; } if (isNew && field is ReferenceField && jvalue.Value == null) { if (field.Name == "CreatedBy" || field.Name == "ModifiedBy") { continue; } } if (field is ReferenceField && jvalue.Value != null) { var refNode = jvalue.Type == JTokenType.Integer ? Node.LoadNode(Convert.ToInt32(jvalue.Value)) : Node.LoadNode(jvalue.Value.ToString()); field.SetData(refNode); continue; } if (isNew && field.Name == "Name" && jvalue.Value != null) { field.SetData(ContentNamingProvider.GetNameFromDisplayName(jvalue.Value.ToString())); continue; } field.SetData(jvalue.Value); continue; } var ovalue = prop.Value as JObject; if (ovalue != null) { //TODO: ODATA: setting field when posted value is JObject. // field.SetData(jvalue.Value); continue; } var avalue = prop.Value as JArray; if (avalue != null) { if (field is ReferenceField) { var refValues = avalue.Values().ToList(); if (refValues.Count == 0) { field.SetData(null); continue; } var fsetting = field.FieldSetting as ReferenceFieldSetting; var nodes = refValues.Select(rv => rv.Type == JTokenType.Integer ? Node.LoadNode(Convert.ToInt32(rv.ToString())) : Node.LoadNode(rv.ToString())); if (fsetting.AllowMultiple.HasValue && fsetting.AllowMultiple.Value) { field.SetData(nodes); } else { field.SetData(nodes.First()); } continue; } else if (field is ChoiceField) { // ChoiceField expects the value to be of type List<string> var list = new List <string>(); foreach (var token in avalue) { if (token is JValue) { list.Add(((JValue)token).Value.ToString()); } else { throw new Exception(string.Format("Token type {0} for field {1} (type {2}) is not supported.", token.GetType().Name, field.Name, field.GetType().Name)); } } field.SetData(list); } continue; } throw new SnNotSupportedException(); } } } }
private static string GetTagName(string tag) { return(ContentNamingProvider.GetNameFromDisplayName("", tag).Trim().Replace('.', '_').Replace('"', '_').Replace('\'', '_')); }
public override object GetData() { if (this.ControlMode == FieldControlControlMode.Browse || this.ReadOnly) { return(_innerData); } var nameAvailableControl = GetNameAvailableControl(); // name control is available var nameControlAvailable = false; if (nameAvailableControl != null) { if (nameAvailableControl.Text != "0") { nameControlAvailable = true; } } var displayName = string.Empty; var innerControl = GetInnerControl() as TextBox; displayName = innerControl.Text; string className; string name; if (SenseNetResourceManager.ParseResourceKey(displayName, out className, out name)) { // get resources var allresStr = GetResourcesBoxControl().Text; // if resources JSON is empty, we just entered a resource key into displayname control, but it does not yet come from the resource editor if (!string.IsNullOrEmpty(allresStr)) { var ser = new JavaScriptSerializer(); var allres = ser.Deserialize <ResourceEditorApi.ResourceKeyData>(allresStr); // value comes from the resource editor ui displayName = allres.Name; // if the entered value is a resource key, then update corresponding resources if (SenseNetResourceManager.ParseResourceKey(displayName, out className, out name)) { ResourceEditorApi.SaveResource(className, name, allres.Datas); } } } if (!nameControlAvailable && (this.Content.Id == 0 || AlwaysUpdateName)) { // content name should be set automatically generated from displayname var newName = ContentNamingProvider.GetNameFromDisplayName(this.Content.Name, displayName); if (newName.Length > 0) { this.Content["Name"] = newName; } } return(displayName); }