Commit bf13678e by Tuukka Kivilahti

Merge branch 'feature-permissions' into 'master'

Feature permissions

See merge request !418
2 parents 922271b6 2f68d903
package fi.codecrew.moya.beans;
import fi.codecrew.moya.model.EventRoleFeature;
import fi.codecrew.moya.model.MoyaFeature;
public class FeaturePermission {
private final MoyaFeature feature;
private boolean admin = false;
private boolean user = false;
private boolean info = false;
public FeaturePermission(MoyaFeature f) {
this.feature = f;
}
public void addPermissions(EventRoleFeature erf) {
user = user || erf.isUser();
info = info || erf.isInfo();
admin = admin || erf.isAdmin();
}
public MoyaFeature getFeature() {
return feature;
}
public boolean isAdmin() {
return admin;
}
public void setAdmin(boolean admin) {
this.admin = admin;
}
public boolean isUser() {
return user;
}
public void setUser(boolean user) {
this.user = user;
}
public boolean isInfo() {
return info;
}
public void setInfo(boolean info) {
this.info = info;
}
}
...@@ -27,17 +27,7 @@ import java.util.Map; ...@@ -27,17 +27,7 @@ import java.util.Map;
import javax.ejb.Local; import javax.ejb.Local;
import fi.codecrew.moya.entitysearch.UserSearchQuery; import fi.codecrew.moya.entitysearch.UserSearchQuery;
import fi.codecrew.moya.model.EventUser; import fi.codecrew.moya.model.*;
import fi.codecrew.moya.model.Feedback;
import fi.codecrew.moya.model.GameID;
import fi.codecrew.moya.model.GroupMembership;
import fi.codecrew.moya.model.LanEvent;
import fi.codecrew.moya.model.PrintedCard;
import fi.codecrew.moya.model.Role;
import fi.codecrew.moya.model.TournamentGame;
import fi.codecrew.moya.model.User;
import fi.codecrew.moya.model.UserApproval;
import fi.codecrew.moya.model.UserImage;
import fi.codecrew.moya.util.MailMessage; import fi.codecrew.moya.util.MailMessage;
import fi.codecrew.moya.utilities.SearchQuery; import fi.codecrew.moya.utilities.SearchQuery;
import fi.codecrew.moya.utilities.SearchResult; import fi.codecrew.moya.utilities.SearchResult;
...@@ -222,4 +212,5 @@ public interface UserBeanLocal { ...@@ -222,4 +212,5 @@ public interface UserBeanLocal {
Map<Role,List<String>> findUsersRolesWithReason(EventUser user); Map<Role,List<String>> findUsersRolesWithReason(EventUser user);
Map<MoyaFeature, FeaturePermission> getUsersFeaturepermissions(EventUser source);
} }
...@@ -631,8 +631,16 @@ public class BootstrapBean implements BootstrapBeanLocal { ...@@ -631,8 +631,16 @@ public class BootstrapBean implements BootstrapBeanLocal {
"ALTER TABLE users DROP COLUMN postal_town;" "ALTER TABLE users DROP COLUMN postal_town;"
}); });
} dbUpdates.add(new String[]{
"CREATE TABLE event_features (id SERIAL NOT NULL, created TIMESTAMPTZ, feature TEXT NOT NULL, meta jsonb, event_id SERIAL NOT NULL, PRIMARY KEY (id))",
"CREATE TABLE event_role_features (id SERIAL NOT NULL, admin_permission BOOLEAN NOT NULL, created TIMESTAMPTZ, feature TEXT NOT NULL, info_permission BOOLEAN NOT NULL, meta jsonb, user_permission BOOLEAN NOT NULL, role_id SERIAL NOT NULL, PRIMARY KEY (id))",
"ALTER TABLE event_features ADD CONSTRAINT UNQ_event_features_0 UNIQUE (event_id, feature)",
"ALTER TABLE event_role_features ADD CONSTRAINT UNQ_event_role_features_0 UNIQUE (role_id, feature)",
"ALTER TABLE event_features ADD CONSTRAINT FK_event_features_event_id FOREIGN KEY (event_id) REFERENCES events (id)",
"ALTER TABLE event_role_features ADD CONSTRAINT FK_event_role_features_role_id FOREIGN KEY (role_id) REFERENCES roles (id)"
});
}
public BootstrapBean() { public BootstrapBean() {
} }
......
...@@ -43,6 +43,7 @@ import javax.imageio.ImageIO; ...@@ -43,6 +43,7 @@ import javax.imageio.ImageIO;
import javax.persistence.EntityManager; import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext; import javax.persistence.PersistenceContext;
import fi.codecrew.moya.model.*;
import org.apache.commons.codec.binary.Hex; import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -68,22 +69,6 @@ import fi.codecrew.moya.facade.RoleFacade; ...@@ -68,22 +69,6 @@ import fi.codecrew.moya.facade.RoleFacade;
import fi.codecrew.moya.facade.UserApprovalFacade; import fi.codecrew.moya.facade.UserApprovalFacade;
import fi.codecrew.moya.facade.UserFacade; import fi.codecrew.moya.facade.UserFacade;
import fi.codecrew.moya.facade.UserImageFacade; import fi.codecrew.moya.facade.UserImageFacade;
import fi.codecrew.moya.model.AccountEvent;
import fi.codecrew.moya.model.Approval;
import fi.codecrew.moya.model.EventUser;
import fi.codecrew.moya.model.Feedback;
import fi.codecrew.moya.model.GameID;
import fi.codecrew.moya.model.GroupMembership;
import fi.codecrew.moya.model.LanEvent;
import fi.codecrew.moya.model.LanEventPropertyKey;
import fi.codecrew.moya.model.PlaceGroup;
import fi.codecrew.moya.model.PrintedCard;
import fi.codecrew.moya.model.Product;
import fi.codecrew.moya.model.Role;
import fi.codecrew.moya.model.TournamentGame;
import fi.codecrew.moya.model.User;
import fi.codecrew.moya.model.UserApproval;
import fi.codecrew.moya.model.UserImage;
import fi.codecrew.moya.util.MailMessage; import fi.codecrew.moya.util.MailMessage;
import fi.codecrew.moya.utilities.I18n; import fi.codecrew.moya.utilities.I18n;
import fi.codecrew.moya.utilities.PasswordFunctions; import fi.codecrew.moya.utilities.PasswordFunctions;
...@@ -241,6 +226,16 @@ public class UserBean implements UserBeanLocal { ...@@ -241,6 +226,16 @@ public class UserBean implements UserBeanLocal {
} }
@Override
public Map<MoyaFeature, FeaturePermission> getUsersFeaturepermissions(EventUser user) {
EnumMap<MoyaFeature, FeaturePermission> ret = new EnumMap<>(MoyaFeature.class);
for(MoyaFeature f: MoyaFeature.values()){
ret.put(f, new FeaturePermission(f) );
}
findUsersRoles(user).forEach(role -> role.getFeatures().forEach(erf -> ret.get(erf.getFeature()).addPermissions(erf)));
return ret;
}
// private EventUser currentEventuser; // private EventUser currentEventuser;
// private ArrayList<Role> currentEventuserRoles; // private ArrayList<Role> currentEventuserRoles;
......
package fi.codecrew.moya.model;
import com.sun.istack.Nullable;
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "event_features", uniqueConstraints = {@UniqueConstraint(columnNames = {EventFeature.EVENT_ID_COLUMN, EventFeature.FEATURE_COLUMN})})
public class EventFeature extends GenericEntity {
public static final String EVENT_ID_COLUMN = "event_id";
public static final String FEATURE_COLUMN = "feature";
@Column(name = "created", updatable = false)
private LocalDateTime created = LocalDateTime.now();
@ManyToOne(optional = false)
@JoinColumn(name = EVENT_ID_COLUMN, nullable = false)
private LanEvent event;
@Enumerated(EnumType.STRING)
@Column(name = FEATURE_COLUMN, nullable = false)
private MoyaFeature feature;
public LanEvent getEvent() {
return event;
}
public void setEvent(LanEvent event) {
this.event = event;
}
public MoyaFeature getFeature() {
return feature;
}
public void setFeature(MoyaFeature feature) {
this.feature = feature;
}
public LocalDateTime getCreated() {
return created;
}
public void setCreated(LocalDateTime created) {
this.created = created;
}
}
package fi.codecrew.moya.model;
import javax.persistence.*;
import java.time.LocalDateTime;
@Table(name = "event_role_features", uniqueConstraints = {@UniqueConstraint(columnNames = {EventRoleFeature.ROLE_ID_COLUMN, EventRoleFeature.FEATURE_COLUMN})})
@Entity()
public class EventRoleFeature extends GenericEntity {
public static final String ROLE_ID_COLUMN = "role_id";
public static final String FEATURE_COLUMN = "feature";
@Column(name = "created", updatable = false)
private LocalDateTime created = LocalDateTime.now();
@ManyToOne(optional = false)
@JoinColumn(name = ROLE_ID_COLUMN, nullable = false, updatable = false)
private Role role;
@Enumerated(EnumType.STRING)
@Column(name = FEATURE_COLUMN, nullable = false, updatable = false)
private MoyaFeature feature;
@Column(nullable = false, name = "user_permission")
private boolean user = false;
@Column(nullable = false, name = "info_permission")
private boolean info = false;
@Column(nullable = false, name = "admin_permission")
private boolean admin = false;
public LocalDateTime getCreated() {
return created;
}
public void setCreated(LocalDateTime created) {
this.created = created;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public MoyaFeature getFeature() {
return feature;
}
public void setFeature(MoyaFeature feature) {
this.feature = feature;
}
public boolean isUser() {
return user;
}
public void setUser(boolean user) {
this.user = user;
}
public boolean isInfo() {
return info;
}
public void setInfo(boolean info) {
this.info = info;
}
public boolean isAdmin() {
return admin;
}
public void setAdmin(boolean admin) {
this.admin = admin;
}
}
...@@ -143,6 +143,10 @@ public class LanEvent extends GenericEntity { ...@@ -143,6 +143,10 @@ public class LanEvent extends GenericEntity {
@Column(name="codecrew_notes") @Column(name="codecrew_notes")
private String codecrewNotes; private String codecrewNotes;
@OneToMany(mappedBy = "event")
@PrivateOwned
private List<EventFeature> features = new ArrayList<>();
// @OneToMany(mappedBy = "event") // @OneToMany(mappedBy = "event")
// private List<Vip> vips; // private List<Vip> vips;
...@@ -388,7 +392,15 @@ public class LanEvent extends GenericEntity { ...@@ -388,7 +392,15 @@ public class LanEvent extends GenericEntity {
return getDomains().get(0).getDomain(); return getDomains().get(0).getDomain();
} }
// public List<Vip> getVips() { public List<EventFeature> getFeatures() {
return features;
}
public void setFeatures(List<EventFeature> features) {
this.features = features;
}
// public List<Vip> getVips() {
// return vips; // return vips;
// } // }
// //
......
package fi.codecrew.moya.model;
public enum MoyaFeature {
/**
* - Users have the permission to manage themselves
* - organizers have the permission to view all users
* - Admin has the rights to modify all users basic information
* <p>
* Note that nobody should have the right to reset a password or email
* because of security concerns. (except superadmin, maybe?)
*/
USER,
/**
* - User: No permissions
* - Org: View and give out vip list enries
* - Admin: Add vips
*/
VIPLIST,
/**
* - User: View and buy items in shop
* - Org: Sell products to others.
* - Admin: Create and modify products
*/
SHOP,
/**
* - User: View and reserve places from the map to themselves
* - Org: View all information about places, and assign people to places
* - Admin: Create and modify maps and layouts
*/
MAPS,
/**
* - Guest: Vote and submit entries to compos
* - Org: View compos and assist users in entry submissions
* - Admin: Create and manage categories, view results
*/
COMPOS,
ORGROLES,
TOURNAMENTS,
/**
* - User: View and enroll to lectures
* - Org: Enroll others to lectures and view all registrants
* - Admin: Create and modify lectures, remove enrollments
*/
COURSES,
/**
* - Guest: Answer the polls
* - Organizer: No special permissions
* - Admin: Create and manage polls, View results
*/
POLLS,
FOODWAVES,
BBADGES,
/**
* Most events have some content added on the pages
* - User: View content
* - Org: No special permissions
* - Admin: Manage and create content
*/
SITE
}
...@@ -104,7 +104,10 @@ public class Role extends GenericEntity { ...@@ -104,7 +104,10 @@ public class Role extends GenericEntity {
@ManyToMany(mappedBy = "openForRoles") @ManyToMany(mappedBy = "openForRoles")
private List<Lecture> lectures = new ArrayList<Lecture>(); private List<Lecture> lectures = new ArrayList<Lecture>();
@OneToMany(mappedBy="role")
@PrivateOwned
private List<EventRoleFeature> features = new ArrayList<>();
public Role() { public Role() {
super(); super();
...@@ -247,4 +250,11 @@ public class Role extends GenericEntity { ...@@ -247,4 +250,11 @@ public class Role extends GenericEntity {
this.userSelectableRole = user_selectable_group; this.userSelectableRole = user_selectable_group;
} }
public List<EventRoleFeature> getFeatures() {
return features;
}
public void setFeatures(List<EventRoleFeature> features) {
this.features = features;
}
} }
package fi.codecrew.moya.model.converters;
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.sql.Date;
@Converter(autoApply = true)
public class LocalDateAttributeConverter implements AttributeConverter<LocalDate, Date> {
@Override
public Date convertToDatabaseColumn(LocalDate locDate) {
return (locDate == null ? null : Date.valueOf(locDate));
}
@Override
public LocalDate convertToEntityAttribute(Date sqlDate) {
return (sqlDate == null ? null : sqlDate.toLocalDate());
}
}
\ No newline at end of file
package fi.codecrew.moya.model.converters;
import javax.persistence.AttributeConverter;
import java.sql.Timestamp;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Date;
import javax.persistence.Converter;
@Converter(autoApply = true)
public class LocalDateTimeAttributeConverter implements AttributeConverter<LocalDateTime, Timestamp> {
@Override
public Timestamp convertToDatabaseColumn(LocalDateTime locDate) {
return (locDate == null ? null : Timestamp.valueOf(locDate));
}
@Override
public LocalDateTime convertToEntityAttribute(Timestamp sqlTimestamp) {
return (sqlTimestamp == null ? null : sqlTimestamp.toLocalDateTime());
}
}
\ No newline at end of file
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!