Commit 5f0685c6 by Liv Haapala

Merge branch 'master' of gitlab.codecrew.fi:codecrew/moya into feature/route-protection

2 parents 7446fd2b 47fe7561
Showing with 625 additions and 54 deletions
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;
import javax.ejb.Local;
import fi.codecrew.moya.entitysearch.UserSearchQuery;
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.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.model.*;
import fi.codecrew.moya.util.MailMessage;
import fi.codecrew.moya.utilities.SearchQuery;
import fi.codecrew.moya.utilities.SearchResult;
......@@ -222,4 +212,5 @@ public interface UserBeanLocal {
Map<Role,List<String>> findUsersRolesWithReason(EventUser user);
Map<MoyaFeature, FeaturePermission> getUsersFeaturepermissions(EventUser source);
}
......@@ -631,8 +631,16 @@ public class BootstrapBean implements BootstrapBeanLocal {
"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() {
}
......
......@@ -43,6 +43,7 @@ import javax.imageio.ImageIO;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import fi.codecrew.moya.model.*;
import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -68,22 +69,6 @@ import fi.codecrew.moya.facade.RoleFacade;
import fi.codecrew.moya.facade.UserApprovalFacade;
import fi.codecrew.moya.facade.UserFacade;
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.utilities.I18n;
import fi.codecrew.moya.utilities.PasswordFunctions;
......@@ -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 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 EventFeature(){
super();
}
public EventFeature(LanEvent event, MoyaFeature moyaFeature) {
super();
this.event = event;
this.feature = moyaFeature;
}
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 EventRoleFeature() {
super();
}
public EventRoleFeature(Role role, MoyaFeature f) {
super();
this.role = role;
this.feature = f;
}
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;
}
}
......@@ -22,6 +22,7 @@ import java.beans.Transient;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
import javax.persistence.CascadeType;
import javax.persistence.Column;
......@@ -143,6 +144,10 @@ public class LanEvent extends GenericEntity {
@Column(name="codecrew_notes")
private String codecrewNotes;
@OneToMany(mappedBy = "event")
@PrivateOwned
private List<EventFeature> features = new ArrayList<>();
// @OneToMany(mappedBy = "event")
// private List<Vip> vips;
......@@ -388,6 +393,23 @@ public class LanEvent extends GenericEntity {
return getDomains().get(0).getDomain();
}
public List<EventFeature> getFeatures() {
return features;
}
public void setFeatures(List<EventFeature> features) {
this.features = features;
}
// Helper for storing and fetching features, as enum strings
public List<String> getStringFeatures(){
return features.stream().map(f -> f.getFeature().name()).collect(Collectors.toList());
}
public void setStringFeatures(List<String> strings){
features = strings.stream().map(str -> features.stream().filter(f -> f.getFeature().name().equals(str)).findFirst().orElse(new EventFeature(this, MoyaFeature.valueOf(str)))).collect(Collectors.toList());
}
// public List<Vip> getVips() {
// return vips;
// }
......
......@@ -2,6 +2,7 @@ package fi.codecrew.moya.model;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class LanguageAwareString {
......@@ -9,7 +10,6 @@ public class LanguageAwareString {
private Map<String, String> values = new HashMap<>();
public String getValue(String language) {
if (values.isEmpty()) {
return null;
......@@ -20,12 +20,16 @@ public class LanguageAwareString {
ret = values.get(defaultLanguage);
// If everything else fails, get a random entry from the map.
if (ret == null) {
ret = values.get(0);
Iterator<String> rndIter = values.values().iterator();
if (rndIter.hasNext()) {
ret = rndIter.next();
}
}
}
return ret;
}
public String getDefaultValue(){
public String getDefaultValue() {
return getValue(defaultLanguage);
}
......
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,
BADGES,
/**
* Most events have some content added on the pages
* - User: View content
* - Org: No special permissions
* - Admin: Manage and create content
*/
SITE;
public String getI18nKey() {
return "moyaFeature." + name();
}
}
......@@ -105,6 +105,9 @@ public class Role extends GenericEntity {
@ManyToMany(mappedBy = "openForRoles")
private List<Lecture> lectures = new ArrayList<Lecture>();
@OneToMany(mappedBy="role", cascade = CascadeType.ALL)
@PrivateOwned
private List<EventRoleFeature> features = new ArrayList<>();
public Role() {
super();
......@@ -247,4 +250,11 @@ public class Role extends GenericEntity {
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
......@@ -71,6 +71,13 @@
</p:selectOneMenu>
<p:message for="defaultrole" />
<p:outputLabel for="eventFeatures" value="#{i18n['event.features']}"/>
<p:selectManyCheckbox layout="pageDirection" id="eventFeatures" value="#{eventorgView.event.stringFeatures}">
<f:selectItems value="#{eventorgView.allFeatures}" var="feature" itemValue="#{feature.name()}" itemLabel="#{i18n[feature.i18nKey]}" />
</p:selectManyCheckbox>
<p:message for="eventFeatures" />
</p:panelGrid>
<p:commandButton id="commitbtn" actionListener="#{eventorgView.saveEvent()}" value="#{i18n['event.save']}" ajax="false" />
</p:fieldset>
......
# Installing graphiql to moya.
- `git clone https://github.com/graphql/graphiql.git /tmp/graphiql`
- `cd /tmp/graphiql && npm install && npm run build`
- `cp graphiql.js graphiql.css examples/index.html ~/moya/code/moya-web/WebContent/graphiql`
- Modify index.html
- Change `graphiql.js` and `graphiql.css` paths in header
- Change graphql path to `/MoyaWeb/graphql`
This diff could not be displayed because it is too large.
<!--
* Copyright (c) Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the license found in the
* LICENSE file in the root directory of this source tree.
-->
<!DOCTYPE html>
<html>
<head>
<style>
body {
height: 100%;
margin: 0;
width: 100%;
overflow: hidden;
}
#graphiql {
height: 100vh;
}
</style>
<!--
This GraphiQL example depends on Promise and fetch, which are available in
modern browsers, but can be "polyfilled" for older browsers.
GraphiQL itself depends on React DOM.
If you do not want to rely on a CDN, you can host these files locally or
include them directly in your favored resource bunder.
-->
<script src="//cdn.jsdelivr.net/es6-promise/4.0.5/es6-promise.auto.min.js"></script>
<script src="//cdn.jsdelivr.net/fetch/0.9.0/fetch.min.js"></script>
<script src="//cdn.jsdelivr.net/react/15.4.2/react.min.js"></script>
<script src="//cdn.jsdelivr.net/react/15.4.2/react-dom.min.js"></script>
<!--
These two files can be found in the npm module, however you may wish to
copy them directly into your environment, or perhaps include them in your
favored resource bundler.
-->
<link rel="stylesheet" href="graphiql.css" />
<script src="graphiql.js" charset="utf-8"></script>
</head>
<body>
<div id="graphiql">Loading...</div>
<script>
/**
* This GraphiQL example illustrates how to use some of GraphiQL's props
* in order to enable reading and updating the URL parameters, making
* link sharing of queries a little bit easier.
*
* This is only one example of this kind of feature, GraphiQL exposes
* various React params to enable interesting integrations.
*/
// Parse the search string to get url parameters.
var search = window.location.search;
var parameters = {};
search.substr(1).split('&').forEach(function (entry) {
var eq = entry.indexOf('=');
if (eq >= 0) {
parameters[decodeURIComponent(entry.slice(0, eq))] =
decodeURIComponent(entry.slice(eq + 1));
}
});
// if variables was provided, try to format it.
if (parameters.variables) {
try {
parameters.variables = JSON.stringify(JSON.parse(parameters.variables), null, 2);
} catch (e) {
// Do nothing, we want to display the invalid JSON as a string, rather
// than present an error.
}
}
// When the query and variables string is edited, update the URL bar so
// that it can be easily shared
function onEditQuery(newQuery) {
parameters.query = newQuery;
updateURL();
}
function onEditVariables(newVariables) {
parameters.variables = newVariables;
updateURL();
}
function onEditOperationName(newOperationName) {
parameters.operationName = newOperationName;
updateURL();
}
function updateURL() {
var newSearch = '?' + Object.keys(parameters).filter(function (key) {
return Boolean(parameters[key]);
}).map(function (key) {
return encodeURIComponent(key) + '=' +
encodeURIComponent(parameters[key]);
}).join('&');
history.replaceState(null, null, newSearch);
}
// Defines a GraphQL fetcher using the fetch API. You're not required to
// use fetch, and could instead implement graphQLFetcher however you like,
// as long as it returns a Promise or Observable.
function graphQLFetcher(graphQLParams) {
// This example expects a GraphQL server at the path /graphql.
// Change this to point wherever you host your GraphQL server.
return fetch('/MoyaWeb/graphql', {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(graphQLParams),
credentials: 'include',
}).then(function (response) {
return response.text();
}).then(function (responseBody) {
try {
return JSON.parse(responseBody);
} catch (error) {
return responseBody;
}
});
}
// Render <GraphiQL /> into the body.
// See the README in the top level of this module to learn more about
// how you can customize GraphiQL by providing different values or
// additional child elements.
ReactDOM.render(
React.createElement(GraphiQL, {
fetcher: graphQLFetcher,
query: parameters.query,
variables: parameters.variables,
operationName: parameters.operationName,
onEditQuery: onEditQuery,
onEditVariables: onEditVariables,
onEditOperationName: onEditOperationName
}),
document.getElementById('graphiql')
);
</script>
</body>
</html>
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:composite="http://java.sun.com/jsf/composite" xmlns:ui="http://java.sun.com/jsf/facelets"
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:composite="http://java.sun.com/jsf/composite"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:p="http://primefaces.org/ui" xmlns:tools="http://java.sun.com/jsf/composite/tools" xmlns:role="http://java.sun.com/jsf/composite/tools/role">
......@@ -14,18 +15,56 @@
<p>
<h:form id="roleform">
<f:facet name="errorMessage">
<h:outputText value="#{i18n['nasty.user']}" />
<h:outputText value="#{i18n['nasty.user']}"/>
</f:facet>
<ui:include src="form.xhtml" />
<h:commandButton rendered="#{roleView.canWriteRoles}" id="saverole" value="#{i18n['roleView.save']}" action="#{roleView.save}" />
<h:panelGrid columns="2">
<h:outputText value="#{i18n['role.name']}"/>
<h:inputText value="#{roleView.role.name}"/>
<h:outputText value="#{i18n['role.userSelectableRole']}"/>
<p:selectBooleanCheckbox value="#{roleView.role.userSelectableRole}"/>
<h:outputText value="#{i18n['role.parents']}"/>
<h:selectManyCheckbox converter="#{roleConverter}" layout="pageDirection" id="roleparents"
value="#{roleView.role.parents}">
<f:selectItems var="par" itemLabel="#{par.name}" value="#{roleView.possibleParents}"/>
</h:selectManyCheckbox>
<h:outputLabel value="#{i18n['role.cardtemplate']}"/>
<h:selectOneMenu converter="#{cardTemplateConverter}" value="#{roleView.role.cardTemplate}">
<f:selectItems var="role" itemLabel="#{role.name}" value="#{cardView.templatesWithNull}"/>
</h:selectOneMenu>
<h:outputText value="#{i18n['role.permissions']}"></h:outputText>
<p:dataTable style="width: auto" value="#{roleView.role.features}" var="feature">
<p:column headerText="#{i18n['feature.name']}">
<h:outputText value="#{feature.feature.name()}"/>
</p:column>
<p:column headerText="#{i18n['feature.user_permission']}">
<p:selectBooleanCheckbox value="#{feature.user}" />
</p:column>
<p:column headerText="#{i18n['feature.info_permission']}">
<p:selectBooleanCheckbox value="#{feature.info}" />
</p:column>
<p:column headerText="#{i18n['feature.admin_permission']}">
<p:selectBooleanCheckbox value="#{feature.admin}" />
</p:column>
</p:dataTable>
</h:panelGrid>
<h:commandButton rendered="#{roleView.canWriteRoles}" id="saverole" value="#{i18n['roleView.save']}" action="#{roleView.save}"/>
</h:form>
</p>
<h:form id="addmember">
<h:outputText value="#{i18n['roleView.adduser']}" />
<h:outputText value="#{i18n['roleView.adduser']}"/>
<p:autoComplete id="useradder" value="#{roleView.addableUser}" completeMethod="#{roleView.searchUser}" converter="#{userConverter}" var="usr" itemValue="#{usr}" itemLabel="#{usr.shortUserDescriptor}">
<p:ajax onerror="location.reload(true);" update=":editor:addmember,:editor:memberlist" event="itemSelect" listener="#{roleView.addUser}" />
<p:autoComplete id="useradder" value="#{roleView.addableUser}" completeMethod="#{roleView.searchUser}" converter="#{userConverter}" var="usr" itemValue="#{usr}"
itemLabel="#{usr.shortUserDescriptor}">
<p:ajax onerror="location.reload(true);" update=":editor:addmember,:editor:memberlist" event="itemSelect" listener="#{roleView.addUser}"/>
</p:autoComplete>
</h:form>
......@@ -35,44 +74,45 @@
<p:dataTable id="memberlist" value="#{roleView.role.users}" var="usr">
<p:column>
<h:outputText value="#{usr.login}" />
<h:outputText value="#{usr.login}"/>
</p:column>
<p:column>
<h:outputText value="#{usr.nick}" />
<h:outputText value="#{usr.nick}"/>
</p:column>
<p:column>
<h:outputText value="#{usr.wholeName}" />
<h:outputText value="#{usr.wholeName}"/>
</p:column>
<p:column>
<h:outputText value="#{usr.email}" />
<h:outputText value="#{usr.email}"/>
</p:column>
</p:dataTable>
</p:fieldset>
<h2>Old permissions</h2>
<p:fieldset legend="#{i18n['role.permissionheader']}" toggleable="true" collapsed="true">
<h:form id="permissionform">
<h:commandButton id="save1" value="#{i18n['role.savePermissions']}" action="#{roleView.savePermissions}" />
<h:commandButton id="save1" value="#{i18n['role.savePermissions']}" action="#{roleView.savePermissions}"/>
<h:dataTable border="1" id="bortalApps" value="#{roleView.rolePermissions}" var="bapp">
<h:column>
<f:facet name="header">
<h:outputText value="#{i18n['applicationPermission.name']}" />
<h:outputText value="#{i18n['applicationPermission.name']}"/>
</f:facet>
<h:outputText value="#{bapp.name}" />
<h:outputText value="#{bapp.name}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{i18n['applicationPermission.description']}" />
<h:outputText value="#{i18n['applicationPermission.description']}"/>
</f:facet>
<h:outputText value="#{i18n[bapp.key]}" />
<h:outputText value="#{i18n[bapp.key]}"/>
</h:column>
<h:column>
<h:selectManyCheckbox id="permissions" layout="pageDirection" value="#{bapp.selected}">
<f:selectItems value="#{bapp.permissions}" var="per" itemLabel="#{i18n[per.i18nKey]}" />
<f:selectItems value="#{bapp.permissions}" var="per" itemLabel="#{i18n[per.i18nKey]}"/>
</h:selectManyCheckbox>
</h:column>
</h:dataTable>
<h:commandButton id="save2" value="#{i18n['role.savePermissions']}" action="#{roleView.savePermissions}" />
<h:commandButton id="save2" value="#{i18n['role.savePermissions']}" action="#{roleView.savePermissions}"/>
</h:form>
</p:fieldset>
......
......@@ -22,5 +22,5 @@ import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
public interface ICommandlineCommand {
public int execute(String[] argv, InputStreamReader stdin, OutputStreamWriter stdout, OutputStreamWriter errstream);
int execute(String[] argv, InputStreamReader stdin, OutputStreamWriter stdout, OutputStreamWriter errstream);
}
......@@ -133,7 +133,7 @@ public class MoyaGraphQLServlet extends HttpServlet {
String query = request.getParameter("query");
if(query == null) {
if (query == null) {
String q = request.getReader().lines().collect(Collectors.joining());
......@@ -141,7 +141,8 @@ public class MoyaGraphQLServlet extends HttpServlet {
Map<String, Object> queryJson = new Gson()
.fromJson(
q,
new TypeToken<Map<String, Object>>(){}
new TypeToken<Map<String, Object>>() {
}
.getType());
query = queryJson.get("query").toString();
......@@ -319,7 +320,14 @@ public class MoyaGraphQLServlet extends HttpServlet {
b.addField(Place_.currentUser);
b.addField(Place_.meta);
}
{
EntityGQLBuilder<FeaturePermission> b = builder.createEntity(FeaturePermission.class);
b.addField().type(GraphQLString).name("feature").dataFetcher(environment -> ((FeaturePermission) environment.getSource()).getFeature().name());
b.addField().type(GraphQLBoolean).name("user").dataFetcher(environment -> ((FeaturePermission) environment.getSource()).isUser());
b.addField().type(GraphQLBoolean).name("info").dataFetcher(environment -> ((FeaturePermission) environment.getSource()).isInfo());
b.addField().type(GraphQLBoolean).name("admin").dataFetcher(environment -> ((FeaturePermission) environment.getSource()).isAdmin());
}
{
EntityGQLBuilder<EventUser> b = builder.createEntity(EventUser.class);
b.addField(EventUser_.id);
......@@ -327,8 +335,9 @@ public class MoyaGraphQLServlet extends HttpServlet {
b.addField(EventUser_.event).type(builder.typeFor(SIMPLE_EVENT_TYPE_NAME));
b.addField(EventUser_.eventuserCreated);
b.addListField(Role.class).dataFetcher(environment -> userbean.findUsersRoles(environment.getSource()));
b.addListField(UsersEventUserproperty.class).dataFetcher(environment -> eventUserPropertyBean.getUserPropertiesForUser(environment.getSource()).stream().sorted(ENTITY_ID_SORTER).collect(toList()));
b.addListField(UsersEventUserproperty.class).name("properties").dataFetcher(environment -> eventUserPropertyBean.getUserPropertiesForUser(environment.getSource()).stream().sorted(ENTITY_ID_SORTER).collect(toList()));
b.addField(EventUser_.currentPlaces);
b.addListField(FeaturePermission.class).name("permissions").dataFetcher(environment -> userbean.getUsersFeaturepermissions(environment.getSource()).values());
}
{
......@@ -662,9 +671,14 @@ public class MoyaGraphQLServlet extends HttpServlet {
.name("vips")
.type(GraphQLList.list(builder.typeFor(Vip.class)))
.dataFetcher(environment -> vipBean.getAvailableVips()))
.field(
newFieldDefinition()
.name("features")
.description("Fetch all features available in moya")
.type(GraphQLList.list(GraphQLString))
.dataFetcher(environment -> Arrays.asList(MoyaFeature.values())))
);
return schemaBld.build();
}
......
......@@ -19,6 +19,7 @@
package fi.codecrew.moya.web.cdiview.organisation;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.ejb.EJB;
......@@ -329,5 +330,10 @@ public class EventOrgView extends GenericCDIView {
return permbean.getCurrentUser().isSuperadmin();
}
public List<MoyaFeature> getAllFeatures() {
return Arrays.asList(MoyaFeature.values());
}
}
......@@ -122,6 +122,16 @@ public class RoleView extends GenericCDIView {
private void initPermissions() {
// New way
role.setFeatures(Arrays.asList(MoyaFeature.values()).stream()
.map(f -> role.getFeatures().stream()
.filter(rf -> rf.getFeature().equals(f))
.findFirst()
.orElse(new EventRoleFeature(role, f)))
.sorted(Comparator.comparing(EventRoleFeature::getFeature))
.collect(Collectors.toList()));
// Old way...
logger.info("Initializing permissions for role {}", role);
EnumMap<BortalApplication, Set<IAppPermission>> rolePermissionMap = new EnumMap<BortalApplication, Set<IAppPermission>>(BortalApplication.class);
if (role.getPermissions() == null) {
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!