Simplify security model.

This commit is contained in:
Paulo Gustavo Veiga 2012-06-12 11:23:47 -03:00
parent 249080cc20
commit cbdd6dd146
25 changed files with 101 additions and 166 deletions

View File

@ -166,7 +166,7 @@ public class MindmapManagerImpl
@Override
public MindMap getMindmapByTitle(final String title, final User user) {
final MindMap result;
List<MindMap> mindMaps = getHibernateTemplate().find("from com.wisemapping.model.MindMap wisemapping where title=? and creator=?", new Object[]{title, user.getUsername()});
List<MindMap> mindMaps = getHibernateTemplate().find("from com.wisemapping.model.MindMap wisemapping where title=? and creator=?", new Object[]{title, user});
if (mindMaps != null && !mindMaps.isEmpty()) {
result = mindMaps.get(0);
} else {

View File

@ -115,7 +115,7 @@ public class UserManagerImpl
newMapUser.setRoleId(collaboration.getRole().ordinal());
newMapUser.setMindMap(collaboration.getMindMap());
newMapUser.setCollaborator(user);
user.addMindmapUser(newMapUser);
user.addCollaboration(newMapUser);
}
getHibernateTemplate().delete(col);

View File

@ -38,7 +38,7 @@ public class Collaboration {
// Guarantee referential integrity
mindmap.addCollaboration(this);
collaborator.addMindmapUser(this);
collaborator.addCollaboration(this);
}
public long getId() {
@ -65,18 +65,6 @@ public class Collaboration {
this.role = role;
}
public boolean isOwner() {
return getRole() == CollaborationRole.OWNER;
}
public boolean isEditor() {
return getRole() == CollaborationRole.EDITOR;
}
public boolean isViewer() {
return getRole() == CollaborationRole.VIEWER;
}
public MindMap getMindMap() {
return mindMap;
}
@ -101,4 +89,9 @@ public class Collaboration {
public void setCollaborationProperties(@NotNull CollaborationProperties collaborationProperties) {
this.collaborationProperties = collaborationProperties;
}
public boolean hasPermissions(@NotNull CollaborationRole role) {
return this.getRole().ordinal() <= role.ordinal();
}
}

View File

@ -18,10 +18,8 @@
package com.wisemapping.model;
import org.jetbrains.annotations.NotNull;
public class CollaborationProperties {
private long id;
private int id;
private boolean starred;
public CollaborationProperties(){
@ -36,11 +34,11 @@ public class CollaborationProperties {
this.starred = starred;
}
public long getId() {
public int getId() {
return id;
}
public void setId(long id) {
public void setId(int id) {
this.id = id;
}
}

View File

@ -19,27 +19,9 @@
package com.wisemapping.model;
public enum CollaborationRole {
OWNER(true, true, true), EDITOR(true, true, false), VIEWER(false, true, false);
OWNER, EDITOR, VIEWER;
private final boolean hasEditPermission;
private final boolean hasViewPermission;
private final boolean hasDeletePermission;
private CollaborationRole(boolean hasEditPermission, boolean hasViewPermission, boolean hasDeletePermission) {
this.hasEditPermission = hasEditPermission;
this.hasViewPermission = hasViewPermission;
this.hasDeletePermission = hasDeletePermission;
}
public boolean hasEditPermission() {
return hasEditPermission;
}
public boolean hasViewPermission() {
return hasViewPermission;
}
public boolean hasDeletePermission() {
return hasDeletePermission;
public String getLabel(){
return this.name().toLowerCase();
}
}

View File

@ -18,6 +18,8 @@
package com.wisemapping.model;
import org.jetbrains.annotations.NotNull;
import java.util.Calendar;
import java.util.Set;
import java.util.HashSet;
@ -40,9 +42,9 @@ public class Collaborator {
this.collaborations = collaborations;
}
public void addMindmapUser(Collaboration mindmaUser)
public void addCollaboration(@NotNull Collaboration collaboration)
{
collaborations.add(mindmaUser);
collaborations.add(collaboration);
}
public Set<Collaboration> getCollaborations()

View File

@ -36,7 +36,6 @@ public class MindMap {
//~ Instance fields ......................................................................................
private int id;
private Calendar creationTime;
private String creator;
private String description;
private boolean isPublic;
@ -45,7 +44,7 @@ public class MindMap {
private Set<Collaboration> collaborations = new HashSet<Collaboration>();
private User owner;
private User creator;
private String properties;
private String tags;
private String title;
@ -169,14 +168,6 @@ public class MindMap {
this.lastModifierUser = lastModifierUser;
}
public String getCreator() {
return creator;
}
public void setCreator(String creatorUser) {
this.creator = creatorUser;
}
public int getId() {
return id;
}
@ -229,15 +220,15 @@ public class MindMap {
this.creationTime = creationTime;
}
public void setOwner(@NotNull User owner) {
if (owner == null) {
public void setCreator(@NotNull User creator) {
if (creator == null) {
throw new IllegalArgumentException("Owner can not be null");
}
this.owner = owner;
this.creator = creator;
}
public User getOwner() {
return owner;
public User getCreator() {
return creator;
}
private CollaborationProperties findUserProperty(@NotNull Collaborator collaborator) {
@ -251,7 +242,7 @@ public class MindMap {
}
final Collaboration collaboration = this.findCollaboration(collaborator);
if(collaboration==null){
if (collaboration == null) {
throw new WiseMappingException("User is not collaborator");
}
@ -286,4 +277,14 @@ public class MindMap {
return result;
}
public boolean hasPermissions(@NotNull Collaborator collaborator, @NotNull CollaborationRole role) {
final Collaboration collaboration = this.findCollaboration(collaborator);
boolean result = false;
if (collaboration != null) {
result = collaboration.hasPermissions(role);
}
return result;
}
}

View File

@ -207,8 +207,10 @@ public class MindmapController extends BaseController {
@ResponseStatus(value = HttpStatus.NO_CONTENT)
public void updateCollabs(@PathVariable int id, @NotNull @RequestBody RestCollaborationList restCollabs) throws CollaborationException {
final MindMap mindMap = mindmapService.getMindmapById(id);
// Only owner can change collaborators...
final User user = Utils.getUser();
if (!mindMap.getOwner().equals(user)) {
if (!mindMap.hasPermissions(user, CollaborationRole.OWNER)) {
throw new IllegalArgumentException("No enough permissions");
}
@ -276,9 +278,9 @@ public class MindmapController extends BaseController {
public void updatePublishState(@RequestBody String value, @PathVariable int id) throws WiseMappingException {
final MindMap mindMap = mindmapService.getMindmapById(id);
final User user = Utils.getUser();
if (!mindMap.getOwner().equals(user)) {
final User user = Utils.getUser();
if (!!mindMap.hasPermissions(user, CollaborationRole.OWNER)) {
throw new IllegalArgumentException("No enough to execute this operation");
}
@ -393,7 +395,7 @@ public class MindmapController extends BaseController {
final MindMap clonedMap = mindMap.shallowClone();
clonedMap.setTitle(restMindmap.getTitle());
clonedMap.setDescription(restMindmap.getDescription());
clonedMap.setOwner(user);
clonedMap.setCreator(user);
// Add new mindmap ...
mindmapService.addMindmap(clonedMap, user);

View File

@ -36,7 +36,7 @@ public enum MindmapFilter {
MY_MAPS("my_maps") {
@Override
boolean accept(@NotNull MindMap mindmap, @NotNull User user) {
return mindmap.getOwner().equals(user);
return mindmap.getCreator().equals(user);
}
},
STARRED("starred") {

View File

@ -5,7 +5,6 @@ import com.wisemapping.exceptions.WiseMappingException;
import com.wisemapping.model.Collaborator;
import com.wisemapping.model.MindMap;
import com.wisemapping.model.User;
import com.wisemapping.security.Utils;
import org.codehaus.jackson.annotate.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -75,7 +74,7 @@ public class RestMindmap {
}
public String getCreator() {
return mindmap.getCreator();
return mindmap.getCreator().getEmail();
}
public String getLastModifierUser() {
@ -132,7 +131,7 @@ public class RestMindmap {
}
public String getOwner() {
final User owner = mindmap.getOwner();
final User owner = mindmap.getCreator();
return owner != null ? owner.getEmail() : null;
}

View File

@ -1,9 +1,11 @@
package com.wisemapping.rest.model;
import com.wisemapping.model.Collaboration;
import com.wisemapping.model.Collaborator;
import com.wisemapping.model.MindMap;
import com.wisemapping.model.User;
import com.wisemapping.security.Utils;
import org.codehaus.jackson.annotate.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -69,16 +71,20 @@ public class RestMindmapInfo {
}
public String getCreator() {
return mindmap.getCreator();
return mindmap.getCreator().getUsername();
}
public String getOwnerEmail() {
return mindmap.getOwner().getEmail();
public void setCreator() {
// Do nothing ...
}
public String getOwner() {
final User owner = mindmap.getOwner();
return owner.getUsername();
public String getRole() {
final Collaboration collaboration = mindmap.findCollaboration(Utils.getUser());
return collaboration != null ? collaboration.getRole().getLabel() : "none";
}
public void setRole() {
// Do nothing ...
}
public String getLastModifierUser() {
@ -117,7 +123,7 @@ public class RestMindmapInfo {
mindmap.setDescription(description);
}
public void setCreator(String creatorUser) {
public void setCreator(String email) {
}
@ -127,12 +133,6 @@ public class RestMindmapInfo {
public void setLastModifierUser(String value) {
}
public void setOwnerEmail(String value) {
}
public void setOwner(String value) {
}
@JsonIgnore
public MindMap getDelegated() {
return this.mindmap;

View File

@ -78,7 +78,7 @@ public class RestUser {
return user.getId();
}
public void setId(long id) {
public void setId(int id) {
user.setId(id);
}

View File

@ -30,8 +30,6 @@ public class UpdateSecurityAdvise
extends BaseSecurityAdvice
implements MethodInterceptor {
private CollaborationRole grantedRole = CollaborationRole.EDITOR;
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
checkRole(methodInvocation);
return methodInvocation.proceed();
@ -39,16 +37,16 @@ public class UpdateSecurityAdvise
protected boolean isAllowed(@NotNull User user, @NotNull MindMap map) {
boolean result;
if (map.getOwner() == null) {
if (map.getCreator() == null) {
// This means that the map is new and is an add operation.
result = true;
} else {
result = getMindmapService().isAllowedToView(user, map, grantedRole);
result = getMindmapService().hasPermissions(user, map, CollaborationRole.EDITOR);
}
return result;
}
protected boolean isAllowed(User user, int mapId) {
return getMindmapService().isAllowedToView(user, mapId, grantedRole);
return getMindmapService().hasPermissions(user, mapId, CollaborationRole.EDITOR);
}
}

View File

@ -28,7 +28,6 @@ import org.jetbrains.annotations.NotNull;
public class ViewBaseSecurityAdvise
extends BaseSecurityAdvice
implements MethodInterceptor {
private CollaborationRole grantedRole = CollaborationRole.VIEWER;
public Object invoke(@NotNull MethodInvocation methodInvocation) throws Throwable {
checkRole(methodInvocation);
@ -36,10 +35,10 @@ public class ViewBaseSecurityAdvise
}
protected boolean isAllowed(User user, MindMap map) {
return getMindmapService().isAllowedToView(user, map, grantedRole);
return getMindmapService().hasPermissions(user, map, CollaborationRole.VIEWER);
}
protected boolean isAllowed(User user, int mapId) {
return getMindmapService().isAllowedToView(user, mapId, grantedRole);
return getMindmapService().hasPermissions(user, mapId, CollaborationRole.VIEWER);
}
}

View File

@ -29,8 +29,6 @@ public interface MindmapService {
public static final String TAG_SEPARATOR = " ";
public Collaboration getMindmapUserBy(int mindmapId, User user);
public MindMap getMindmapById(int mindmapId);
public MindMap getMindmapByTitle(String title, User user);
@ -54,13 +52,9 @@ public interface MindmapService {
public List<MindMapHistory> getMindMapHistory(int mindmapId);
public boolean isAllowedToView(User user, MindMap map, CollaborationRole allowedRole);
public boolean hasPermissions(User user, MindMap map, CollaborationRole allowedRole);
public boolean isAllowedToView(User user, int mapId, CollaborationRole allowedRole);
public boolean isAllowedToCollaborate(User user, int mapId, CollaborationRole grantedRole);
public boolean isAllowedToCollaborate(User user, MindMap map, CollaborationRole grantedRole);
public boolean hasPermissions(User user, int mapId, CollaborationRole allowedRole);
public void addWelcomeMindmap(User user) throws WiseMappingException;

View File

@ -36,54 +36,29 @@ public class MindmapServiceImpl
private UserService userService;
private Mailer mailer;
public boolean isAllowedToCollaborate(@NotNull User user, int mapId, @NotNull CollaborationRole grantedRole) {
@Override
public boolean hasPermissions(@NotNull User user, int mapId, @NotNull CollaborationRole grantedRole) {
final MindMap map = mindmapManager.getMindmapById(mapId);
return isAllowedToCollaborate(user, map, grantedRole);
return hasPermissions(user, map, grantedRole);
}
public boolean isAllowedToView(User user, int mapId, CollaborationRole grantedRole) {
final MindMap map = mindmapManager.getMindmapById(mapId);
return isAllowedToView(user, map, grantedRole);
}
public boolean isAllowedToView(@NotNull User user, @NotNull MindMap map, @NotNull CollaborationRole grantedRole) {
@Override
public boolean hasPermissions(@Nullable User user, @Nullable MindMap map, @NotNull CollaborationRole role) {
boolean result = false;
if (map != null) {
if (map.isPublic()) {
if (map.isPublic() && role == CollaborationRole.VIEWER) {
result = true;
} else if (user != null) {
result = isAllowedToCollaborate(user, map, grantedRole);
final Collaboration collaboration = map.findCollaboration(user);
if (collaboration != null) {
result = collaboration.hasPermissions(role);
}
}
}
return result;
}
public boolean isAllowedToCollaborate(@NotNull User user, @Nullable MindMap map, CollaborationRole grantedRole) {
boolean isAllowed = false;
if (map != null) {
if (map.getOwner().getId() == user.getId()) {
isAllowed = true;
} else {
final Set<Collaboration> users = map.getCollaborations();
CollaborationRole rol = null;
for (Collaboration collaboration : users) {
if (collaboration.getCollaborator().getId() == user.getId()) {
rol = collaboration.getRole();
break;
}
}
// only if the user has a role for the current map
isAllowed = rol != null &&
(grantedRole.equals(rol) || rol.ordinal() < grantedRole.ordinal());
}
}
return isAllowed;
}
public Collaboration getMindmapUserBy(int mindmapId, User user) {
return mindmapManager.getMindmapUserBy(mindmapId, user);
}
@Override
public MindMap getMindmapByTitle(String title, User user) {
return mindmapManager.getMindmapByTitle(title, user);
@ -119,18 +94,18 @@ public class MindmapServiceImpl
final MindMap mindMap = collaboration.getMindMap();
final Set<Collaboration> collaborations = mindMap.getCollaborations();
// When you delete an object from hibernate you have to delete it from *all* collections it exists in...
if (mindMap.getOwner().getEmail().equals(collaboration.getCollaborator().getEmail())) {
if (mindMap.getCreator().getEmail().equals(collaboration.getCollaborator().getEmail())) {
throw new CollaborationException("User is the creator and must have ownership permissions");
}
// When you delete an object from hibernate you have to delete it from *all* collections it exists in...
mindmapManager.removeCollaboration(collaboration);
collaborations.remove(collaboration);
}
@Override
public void removeMindmap(@NotNull MindMap mindmap, @NotNull User user) throws WiseMappingException {
if (mindmap.getOwner().equals(user)) {
if (mindmap.getCreator().equals(user)) {
mindmapManager.removeMindmap(mindmap);
} else {
final Collaboration collaboration = mindmap.findCollaboration(user);
@ -155,11 +130,10 @@ public class MindmapServiceImpl
final Calendar creationTime = Calendar.getInstance();
final String username = user.getUsername();
map.setCreator(username);
map.setLastModifierUser(username);
map.setCreationTime(creationTime);
map.setLastModificationTime(creationTime);
map.setOwner(user);
map.setCreator(user);
// Add map creator with owner permissions ...
final User dbUser = userService.getUserBy(user.getId());
@ -174,8 +148,7 @@ public class MindmapServiceImpl
throws CollaborationException {
// Validate
final Collaborator owner = mindmap.getOwner();
final Set<Collaboration> collaborations = mindmap.getCollaborations();
final Collaborator owner = mindmap.getCreator();
if (owner.getEmail().equals(email)) {
throw new CollaborationException("The user " + owner.getEmail() + " is the owner");
}
@ -185,6 +158,7 @@ public class MindmapServiceImpl
}
final Set<Collaboration> collaborations = mindmap.getCollaborations();
Collaboration collaboration = getCollaborationBy(email, collaborations);
if (collaboration == null) {
final Collaborator collaborator = addCollaborator(email);
@ -224,7 +198,7 @@ public class MindmapServiceImpl
mindmapManager.updateMindmap(mindmap, false);
if (tags != null && tags.length() > 0) {
final String tag[] = tags.split(TAG_SEPARATOR);
final User user = mindmap.getOwner();
final User user = mindmap.getCreator();
// Add new Tags to User
boolean updateUser = false;
for (String userTag : tag) {

View File

@ -82,10 +82,6 @@ public class MindMapBean {
return DateFormat.getInstance().format(mindMap.getCreationTime().getTime());
}
public String getCreationUser() {
return mindMap.getCreator();
}
public String getTags() {
return mindMap.getTags();
}
@ -126,7 +122,7 @@ public class MindMapBean {
mindMap.setDescription(d);
}
public User getOwner() {
return mindMap.getOwner();
public User getCreator() {
return mindMap.getCreator();
}
}

View File

@ -13,11 +13,11 @@
<property name="creationDate" column="creation_date"/>
<set name="collaborations"
cascade="all, delete-orphan"
inverse="true">
cascade="all, delete-orphan"
inverse="true">
<key column="COLABORATOR_ID" not-null="true"/>
<one-to-many class="com.wisemapping.model.Collaboration"/>
</set>
</set>
<joined-subclass name="com.wisemapping.model.User" table="USER">
<key column="COLABORATOR_ID"/>
@ -30,7 +30,7 @@
<property name="allowSendEmail"/>
<set name="tags" table="TAG">
<key column="user_id"/>
<element column="name" type="string"/>
<element column="name" type="string"/>
</set>
</joined-subclass>
</class>

View File

@ -16,11 +16,10 @@
<property name="lastModifierUser" column="last_editor"/>
<property name="lastModificationTime" column="edition_date"/>
<property name="creationTime" column="creation_date"/>
<property name="creator" column="creator_user"/>
<property name="tags" column="tags"/>
<property name="properties" column="editor_properties"/>
<many-to-one name="owner" column="owner_id" unique="true" not-null="true"/>
<many-to-one name="creator" column="creator_id" unique="true" not-null="true"/>
<set name="collaborations"
cascade="all,delete-orphan"

View File

@ -195,7 +195,7 @@ function updateStatusToolbar() {
// Can be executed by the owner ?
var rowData = tableElem.dataTable().fnGetData(selectedRows[0]);
if (rowData.ownerEmail != principalEmail) {
if (rowData.role != 'owner') {
$("#buttonsToolbar").find('#publishBtn').hide().end().find('#shareBtn').hide();
}
} else {
@ -290,8 +290,8 @@ $(function() {
}
},
{
sTitle : "Owner",
mDataProp :"owner"
sTitle : "Creator",
mDataProp :"creator"
},
{
bSearchable : false,

View File

@ -4,7 +4,7 @@
<div>
<ul class="nav nav-tabs">
<li class="active"><a href="#general" data-toggle="pill">General</a></li>
<li><a href="#collaborators" data-toggle="pill">Collaborators</a></li>
<li><a href="#collaborators" data-toggle="pill">Shared</a></li>
<li><a href="#publish" data-toggle="pill">Publish</a></li>
</ul>
@ -13,7 +13,7 @@
<ul class="unstyled">
<li><strong><spring:message code="NAME"/>:</strong> ${wisemapDetail.title}</li>
<li><strong><spring:message code="DESCRIPTION"/>:</strong> ${wisemapDetail.description}</li>
<li><strong><spring:message code="OWNER"/>:</strong> ${wisemapDetail.creationUser}</li>
<li><strong><spring:message code="CREATOR"/>:</strong> ${wisemapDetail.creator.username}</li>
<li><strong><spring:message code="CREATION_TIME"/>:</strong> ${wisemapDetail.creationTime}</li>
<li><strong><spring:message code="LAST_UPDATE"/>:</strong> ${wisemapDetail.lastEditTime}</li>
<li><strong><spring:message code="LAST_UPDATE_BY"/>:</strong> ${wisemapDetail.lastEditor}</li>

View File

@ -82,7 +82,7 @@
<div id="zoomOut" class="button"></div>
<div id="mapDetails">
<span class="title"><spring:message code="CREATOR"/>:</span><span>${mindmap.creator}</span>
<span class="title"><spring:message code="CREATOR"/>:</span><span>${mindmap.creator.username}</span>
<span class="title"><spring:message code="DESCRIPTION"/>:</span><span>${mindmap.title}</span>
</div>
</div>

View File

@ -124,7 +124,7 @@
<div id="zoomOut" class="button"></div>
<div id="mapDetails">
<span class="title"><spring:message code="CREATOR"/>:</span><span>${mindmap.creator}</span>
<span class="title"><spring:message code="CREATOR"/>:</span><span>${mindmap.creator.username}</span>
<span class="title"><spring:message code="DESCRIPTION"/>:</span><span>${mindmap.title}</span>
</div>
</div>

View File

@ -24,12 +24,11 @@ xml LONGVARBINARY NOT NULL,
public BOOLEAN NOT NULL,
creation_date DATETIME,
edition_date DATETIME,
owner_id INTEGER NOT NULL,
creator_id INTEGER NOT NULL,
tags varchar(1014) ,
last_editor varchar(255) ,
creator_user varchar(255) ,
editor_properties varchar(512)
--FOREIGN KEY(owner_id) REFERENCES USER(colaborator_id)
--FOREIGN KEY(creator_id) REFERENCES USER(colaborator_id)
);

View File

@ -25,12 +25,11 @@ xml blob NOT NULL,
public BOOL not null default 0,
creation_date datetime,
edition_date datetime,
owner_id INTEGER not null,
creator_id INTEGER not null,
tags varchar(1014) CHARACTER SET utf8 ,
last_editor varchar(255) CHARACTER SET utf8 ,
creator_user varchar(255) CHARACTER SET utf8 ,
editor_properties varchar(512) CHARACTER SET utf8 ,
FOREIGN KEY(owner_id) REFERENCES USER(colaborator_id)
FOREIGN KEY(creator_id) REFERENCES USER(colaborator_id)
) CHARACTER SET utf8 ;