Completes: U4-3194 member editor needs group/role support

This commit is contained in:
Shannon
2013-10-21 17:02:33 +11:00
parent 3af8354a93
commit 49df332734
10 changed files with 144 additions and 14 deletions

View File

@@ -99,6 +99,11 @@ namespace Umbraco.Core
/// </summary>
public static class Member
{
/// <summary>
/// if a role starts with __umbracoRole we won't show it as it's an internal role used for public access
/// </summary>
public static readonly string InternalRolePrefix = "__umbracoRole";
public static readonly string UmbracoMemberProviderName = "UmbracoMembershipProvider";
public static readonly string UmbracoRoleProviderName = "UmbracoRoleProvider";

View File

@@ -245,10 +245,21 @@ function umbDataFormatter() {
var propPass = _.find(genericTab.properties, function (item) {
return item.alias === "_umb_password";
});
var propGroups = _.find(genericTab.properties, function (item) {
return item.alias === "_umb_membergroup";
});
saveModel.email = propEmail.value;
saveModel.username = propLogin.value;
saveModel.password = propPass.value;
var selectedGroups = [];
for (var n in propGroups.value) {
if (propGroups.value[n] === true) {
selectedGroups.push(n);
}
}
saveModel.memberGroups = selectedGroups;
return saveModel;
},

View File

@@ -281,4 +281,18 @@ ul.color-picker li a {
}
.umb-fileupload input {
font-size: 12px
}
}
//
// Member group picker
// --------------------------------------------------
.umb-member-group-box {
width: 45%;
}
.umb-member-group-box:nth-child(1){
float:left;
}
.umb-member-group-box:nth-child(2){
float:right;
}

View File

@@ -0,0 +1,36 @@
function memberGroupController($rootScope, $scope, dialogService, mediaResource, imageHelper, $log) {
//set the available to the keys of the dictionary who's value is true
$scope.getAvailable = function () {
var available = [];
for (var n in $scope.model.value) {
if ($scope.model.value[n] === false) {
available.push(n);
}
}
return available;
};
//set the selected to the keys of the dictionary who's value is true
$scope.getSelected = function () {
var selected = [];
for (var n in $scope.model.value) {
if ($scope.model.value[n] === true) {
selected.push(n);
}
}
return selected;
};
$scope.addItem = function(item) {
//keep the model up to date
$scope.model.value[item] = true;
};
$scope.removeItem = function (item) {
//keep the model up to date
$scope.model.value[item] = false;
};
}
angular.module('umbraco').controller("Umbraco.PropertyEditors.MemberGroupController", memberGroupController);

View File

@@ -0,0 +1,18 @@
<div ng-controller="Umbraco.PropertyEditors.MemberGroupController">
<div class="umb-member-group-box">
<h5>Not a member of group(s)</h5>
<ul>
<li ng-repeat="item in getAvailable()">
<a href="" ng-click="addItem(item)">{{item}}</a>
</li>
</ul>
</div>
<div class="umb-member-group-box">
<h5>Member of group(s)</h5>
<ul>
<li ng-repeat="item in getSelected()">
<a href="" ng-click="removeItem(item)">{{item}}</a>
</li>
</ul>
</div>
</div>

View File

@@ -157,6 +157,20 @@ namespace Umbraco.Web.Editors
throw new HttpResponseException(Request.CreateValidationErrorResponse(forDisplay));
}
//Now let's do the role provider stuff
var currGroups = Roles.GetRolesForUser(contentItem.PersistedContent.Username);
//find the ones to remove and remove them
var toRemove = currGroups.Except(contentItem.Groups).ToArray();
if (toRemove.Any())
{
Roles.RemoveUserFromRoles(contentItem.PersistedContent.Username, toRemove);
}
if (contentItem.Groups.Any())
{
//add the ones submitted
Roles.AddUserToRoles(contentItem.PersistedContent.Username, contentItem.Groups.ToArray());
}
//save the item
//NOTE: We are setting the password to NULL - this indicates to the system to not actually save the password
// so it will not get overwritten!

View File

@@ -1,4 +1,5 @@
using System.Runtime.Serialization;
using System.Collections.Generic;
using System.Runtime.Serialization;
using Newtonsoft.Json.Linq;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Validation;
@@ -25,5 +26,8 @@ namespace Umbraco.Web.Models.ContentEditing
[DataMember(Name = "password")]
public ChangingPasswordModel Password { get; set; }
[DataMember(Name = "memberGroups")]
public IEnumerable<string> Groups { get; set; }
}
}

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Web.Security;
using AutoMapper;
using Umbraco.Core;
@@ -66,7 +67,7 @@ namespace Umbraco.Web.Models.Mapping
/// <param name="member"></param>
/// <param name="display"></param>
private static void MapGenericCustomProperties(IMember member, MemberDisplay display)
{
{
TabsAndPropertiesResolver.MapGenericProperties(
member, display,
new ContentPropertyDisplay
@@ -77,6 +78,14 @@ namespace Umbraco.Web.Models.Mapping
View = "textbox",
Config = new Dictionary<string, object> {{"IsRequired", true}}
},
new ContentPropertyDisplay
{
Alias = string.Format("{0}email", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
Label = ui.Text("general", "email"),
Value = display.Email,
View = "email",
Config = new Dictionary<string, object> {{"IsRequired", true}}
},
new ContentPropertyDisplay
{
Alias = string.Format("{0}password", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
@@ -89,22 +98,40 @@ namespace Umbraco.Web.Models.Mapping
//TODO: Hard coding this because the changepassword doesn't necessarily need to be a resolvable (real) property editor
View = "changepassword",
Config = new Dictionary<string, object>(
//initialize the dictionary with the configuration from the default membership provider
Membership.Provider.GetConfiguration())
//initialize the dictionary with the configuration from the default membership provider
Membership.Provider.GetConfiguration())
{
//the password change toggle will only be displayed if there is already a password assigned.
{"hasPassword", member.Password.IsNullOrWhiteSpace() == false}
{"hasPassword", member.Password.IsNullOrWhiteSpace() == false}
}
},
new ContentPropertyDisplay
{
Alias = string.Format("{0}email", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
Label = ui.Text("general", "email"),
Value = display.Email,
View = "email",
Alias = string.Format("{0}membergroup", Constants.PropertyEditors.InternalGenericPropertiesPrefix),
Label = ui.Text("content", "membergroup"),
Value = GetMemberGroupValue(display.Username),
View = "membergroups",
Config = new Dictionary<string, object> {{"IsRequired", true}}
});
}
internal static IDictionary<string, bool> GetMemberGroupValue(string username)
{
var result = new Dictionary<string, bool>();
foreach (var role in Roles.GetAllRoles().Distinct())
{
result.Add(role, false);
// if a role starts with __umbracoRole we won't show it as it's an internal role used for public access
if (role.StartsWith(Constants.Conventions.Member.InternalRolePrefix) == false)
{
if (Roles.IsUserInRole(username, role))
{
result[role] = true;
}
}
}
return result;
}
/// <summary>

View File

@@ -104,8 +104,6 @@ namespace Umbraco.Web.Security
return allowAction;
}
private static readonly int UmbracoTimeOutInMinutes = GlobalSettings.TimeOutInMinutes;
private IUser _currentUser;
/// <summary>

View File

@@ -15,6 +15,9 @@ namespace Umbraco.Web.WebApi.Filters
{
base.OnActionExecuted(actionExecutedContext);
//this can occur if an error has already occurred.
if (actionExecutedContext.Response == null) return;
var httpContextAttempt = actionExecutedContext.Request.TryGetHttpContext();
if (httpContextAttempt.Success)
{