diff --git a/src/main/java/de/bps/course/nodes/ChecklistCourseNode.java b/src/main/java/de/bps/course/nodes/ChecklistCourseNode.java index f16873bae268d6a120b7688bf0019057b5fee3d1..3341d7b8a7a7833ad309537c0ba962e55a1a0902 100644 --- a/src/main/java/de/bps/course/nodes/ChecklistCourseNode.java +++ b/src/main/java/de/bps/course/nodes/ChecklistCourseNode.java @@ -196,13 +196,12 @@ public class ChecklistCourseNode extends AbstractAccessableCourseNode { UserCourseEnvironment userCourseEnv, NodeEvaluation ne, String nodecmd) { ICourse course = CourseFactory.loadCourse(userCourseEnv.getCourseEnvironment().getCourseResourceableId()); CourseGroupManager cgm = course.getCourseEnvironment().getCourseGroupManager(); - boolean canEdit = cgm.isIdentityCourseAdministrator(ureq.getIdentity()); + boolean canEdit = userCourseEnv.isAdmin(); boolean canManage; if(canEdit) { canManage = true; } else { - canManage = cgm.isIdentityCourseCoach(ureq.getIdentity()) - || cgm.hasRight(ureq.getIdentity(), CourseRights.RIGHT_GROUPMANAGEMENT); + canManage = userCourseEnv.isCoach() || cgm.hasRight(ureq.getIdentity(), CourseRights.RIGHT_GROUPMANAGEMENT); } Checklist checklist = loadOrCreateChecklist(userCourseEnv.getCourseEnvironment().getCoursePropertyManager()); ChecklistDisplayController checkController = new ChecklistDisplayController(ureq, wControl, checklist, diff --git a/src/main/java/de/bps/course/nodes/VCCourseNode.java b/src/main/java/de/bps/course/nodes/VCCourseNode.java index 35b5aa4f04f3c88d92f42e08ee12762925a94866..5c2e0966deb6d18198a85088a1dcfad741901c8b 100644 --- a/src/main/java/de/bps/course/nodes/VCCourseNode.java +++ b/src/main/java/de/bps/course/nodes/VCCourseNode.java @@ -35,7 +35,6 @@ import org.olat.course.condition.ConditionEditController; import org.olat.course.editor.CourseEditorEnv; import org.olat.course.editor.NodeEditController; import org.olat.course.editor.StatusDescription; -import org.olat.course.groupsandrights.CourseGroupManager; import org.olat.course.nodes.AbstractAccessableCourseNode; import org.olat.course.nodes.CourseNode; import org.olat.course.nodes.StatusDescriptionHelper; @@ -134,8 +133,7 @@ public class VCCourseNode extends AbstractAccessableCourseNode { UserCourseEnvironment userCourseEnv, NodeEvaluation ne, String nodecmd) { updateModuleConfigDefaults(false); // check if user is moderator of the virtual classroom - CourseGroupManager cgm = userCourseEnv.getCourseEnvironment().getCourseGroupManager(); - boolean moderator = cgm.isIdentityCourseAdministrator(ureq.getIdentity()); + boolean moderator = userCourseEnv.isAdmin(); // load configuration final String providerId = getModuleConfiguration().getStringValue(CONF_PROVIDER_ID); diff --git a/src/main/java/de/bps/course/nodes/den/DENRunController.java b/src/main/java/de/bps/course/nodes/den/DENRunController.java index bf05c7f2a7dc8b0c1de4bcd84d7e37ead1e97d5e..db92a3158f385bdeea901b4deeafeabba24fa034 100644 --- a/src/main/java/de/bps/course/nodes/den/DENRunController.java +++ b/src/main/java/de/bps/course/nodes/den/DENRunController.java @@ -45,7 +45,6 @@ import org.olat.core.util.event.GenericEventListener; import org.olat.core.util.resource.OresHelper; import org.olat.course.CourseFactory; import org.olat.course.ICourse; -import org.olat.course.groupsandrights.CourseGroupManager; import org.olat.course.nodes.ObjectivesHelper; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.modules.ModuleConfiguration; @@ -110,9 +109,7 @@ public class DENRunController extends BasicController implements GenericEventLis runVC = new VelocityContainer("dateVC", VELOCITY_ROOT + "/run.html", getTranslator(), this); //show only the options for managing dates and participants if user is admin or course coach - - CourseGroupManager cgm = course.getCourseEnvironment().getCourseGroupManager(); - if(cgm.isIdentityCourseAdministrator(ureq.getIdentity()) || cgm.isIdentityCourseCoach(ureq.getIdentity())) { + if(userCourseEnv.isAdmin() || userCourseEnv.isCoach()) { // subscription subsContext = new SubscriptionContext(course, courseNode.getIdent()); // if sc is null, then no subscription is desired diff --git a/src/main/java/org/olat/course/CourseFactory.java b/src/main/java/org/olat/course/CourseFactory.java index 15b93c92580b6de18c92ef97c9e0894d070ebd94..32303428d76515548c35ecc1250593fd9f9d58ad 100644 --- a/src/main/java/org/olat/course/CourseFactory.java +++ b/src/main/java/org/olat/course/CourseFactory.java @@ -635,7 +635,7 @@ public class CourseFactory { ContextEntry ce = BusinessControlFactory.getInstance().createContextEntry(entry); WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ce, wControl); - RepositoryEntrySecurity reSecurity = new RepositoryEntrySecurity(false, false, false, false, false, false, false, false, false, false, true, false); + RepositoryEntrySecurity reSecurity = new RepositoryEntrySecurity(false, false, false, false, false, false, false, false, false, false, false, true, false); return new RunMainController(ureq, bwControl, null, course, entry, reSecurity, null); } } diff --git a/src/main/java/org/olat/course/assessment/ui/mode/AssessmentModeListController.java b/src/main/java/org/olat/course/assessment/ui/mode/AssessmentModeListController.java index 67083d899b53ba0e6b7f8611f5d09e5e27e201ec..384d743abe20a70f8a206ca26269e77974af978f 100644 --- a/src/main/java/org/olat/course/assessment/ui/mode/AssessmentModeListController.java +++ b/src/main/java/org/olat/course/assessment/ui/mode/AssessmentModeListController.java @@ -66,25 +66,28 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class AssessmentModeListController extends FormBasicController implements GenericEventListener { + private FormLink addLink; + private FormLink deleteLink; private FlexiTableElement tableEl; - private FormLink addLink, deleteLink; private AssessmentModeListModel model; private final TooledStackedPanel toolbarPanel; - private DialogBoxController startDialogBox, stopDialogBox,deleteDialogBox; + private DialogBoxController startDialogBox, stopDialogBox, deleteDialogBox; private AssessmentModeEditController editCtrl; private final RepositoryEntry entry; + private final AssessmentModeSecurityCallback secCallback; @Autowired private AssessmentModeManager assessmentModeMgr; @Autowired private AssessmentModeCoordinationService assessmentModeCoordinationService; - public AssessmentModeListController(UserRequest ureq, WindowControl wControl, - TooledStackedPanel toolbarPanel, RepositoryEntry entry) { + public AssessmentModeListController(UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbarPanel, + RepositoryEntry entry, AssessmentModeSecurityCallback secCallback) { super(ureq, wControl, "mode_list"); this.entry = entry; + this.secCallback = secCallback; this.toolbarPanel = toolbarPanel; toolbarPanel.addListener(this); @@ -105,13 +108,14 @@ public class AssessmentModeListController extends FormBasicController implements @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { - addLink = uifactory.addFormLink("add", "add", "add.mode", null, formLayout, Link.BUTTON); - addLink.setElementCssClass("o_sel_assessment_mode_add"); - addLink.setIconLeftCSS("o_icon o_icon_add"); - - - deleteLink = uifactory.addFormLink("delete", "delete", "delete.mode", null, formLayout, Link.BUTTON); - deleteLink.setIconLeftCSS("o_icon o_icon_delete"); + if(secCallback.canEditAssessmentMode()) { + addLink = uifactory.addFormLink("add", "add", "add.mode", null, formLayout, Link.BUTTON); + addLink.setElementCssClass("o_sel_assessment_mode_add"); + addLink.setIconLeftCSS("o_icon o_icon_add"); + + deleteLink = uifactory.addFormLink("delete", "delete", "delete.mode", null, formLayout, Link.BUTTON); + deleteLink.setIconLeftCSS("o_icon o_icon_delete"); + } //add the table FlexiTableColumnModel columnsModel = FlexiTableDataModelFactory.createFlexiTableColumnModel(); @@ -126,16 +130,21 @@ public class AssessmentModeListController extends FormBasicController implements true, Cols.followupTime.name(), new TimeCellRenderer(getTranslator()))); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(Cols.target.i18nKey(), Cols.target.ordinal(), true, Cols.target.name(), new TargetAudienceCellRenderer(getTranslator()))); - columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("start", Cols.start.ordinal(), "start", + + if(secCallback.canStartStopAssessment()) { + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("start", Cols.start.ordinal(), "start", new BooleanCellRenderer(new StaticFlexiCellRenderer(translate("start"), "start"), null))); - columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("stop", Cols.stop.ordinal(), "stop", + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("stop", Cols.stop.ordinal(), "stop", new BooleanCellRenderer(new StaticFlexiCellRenderer(translate("stop"), "stop"), null))); - columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("edit", translate("edit"), "edit")); + } + if(secCallback.canEditAssessmentMode()) { + columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("edit", translate("edit"), "edit")); + } model = new AssessmentModeListModel(columnsModel, getTranslator(), assessmentModeCoordinationService); tableEl = uifactory.addTableElement(getWindowControl(), "table", model, 20, false, getTranslator(), formLayout); - tableEl.setMultiSelect(true); - tableEl.setSelectAllEnable(true); + tableEl.setMultiSelect(secCallback.canEditAssessmentMode()); + tableEl.setSelectAllEnable(secCallback.canEditAssessmentMode()); } private void loadModel() { @@ -143,9 +152,10 @@ public class AssessmentModeListController extends FormBasicController implements model.setObjects(modes); tableEl.reloadData(); // don't show table and button if there is nothing - tableEl.setVisible(modes.size() > 0); - deleteLink.setVisible(modes.size() > 0); - + tableEl.setVisible(!modes.isEmpty()); + if(deleteLink != null) { + deleteLink.setVisible(!modes.isEmpty()); + } } @Override @@ -210,7 +220,7 @@ public class AssessmentModeListController extends FormBasicController implements if(index == null || index.isEmpty()) { showWarning("error.atleastone"); } else { - List<AssessmentMode> rows = new ArrayList<AssessmentMode>(index.size()); + List<AssessmentMode> rows = new ArrayList<>(index.size()); for(Integer i:index) { rows.add(model.getObject(i.intValue())); } diff --git a/src/main/java/org/olat/course/assessment/ui/mode/AssessmentModeSecurityCallback.java b/src/main/java/org/olat/course/assessment/ui/mode/AssessmentModeSecurityCallback.java new file mode 100644 index 0000000000000000000000000000000000000000..c6d18ed9839a389bb46a8fd1d4c803ca9e5d767c --- /dev/null +++ b/src/main/java/org/olat/course/assessment/ui/mode/AssessmentModeSecurityCallback.java @@ -0,0 +1,34 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.course.assessment.ui.mode; + +/** + * + * Initial date: 20 juil. 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public interface AssessmentModeSecurityCallback { + + public boolean canStartStopAssessment(); + + public boolean canEditAssessmentMode(); + +} diff --git a/src/main/java/org/olat/course/assessment/ui/mode/AssessmentModeSecurityCallbackFactory.java b/src/main/java/org/olat/course/assessment/ui/mode/AssessmentModeSecurityCallbackFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..c2bd2ec1f4bf4f7b9a42d6d7bd4542a071c2c539 --- /dev/null +++ b/src/main/java/org/olat/course/assessment/ui/mode/AssessmentModeSecurityCallbackFactory.java @@ -0,0 +1,52 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.course.assessment.ui.mode; + +/** + * + * Initial date: 20 juil. 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class AssessmentModeSecurityCallbackFactory { + + public static AssessmentModeSecurityCallback getSecurityCallback(boolean canModify) { + return new AssessmentModeSecurityCallbackImpl(canModify); + } + + private static class AssessmentModeSecurityCallbackImpl implements AssessmentModeSecurityCallback { + + private final boolean canModify; + + public AssessmentModeSecurityCallbackImpl(boolean canModify) { + this.canModify = canModify; + } + + @Override + public boolean canStartStopAssessment() { + return canModify; + } + + @Override + public boolean canEditAssessmentMode() { + return canModify; + } + } +} diff --git a/src/main/java/org/olat/course/assessment/ui/mode/_content/mode_list.html b/src/main/java/org/olat/course/assessment/ui/mode/_content/mode_list.html index 25e81e55c34617c409eeb345c76a4a28f0862b88..e5892a0f746957abc9b7cc57147e622629cbe964 100644 --- a/src/main/java/org/olat/course/assessment/ui/mode/_content/mode_list.html +++ b/src/main/java/org/olat/course/assessment/ui/mode/_content/mode_list.html @@ -1,7 +1,11 @@ <fieldset class="o_sel_assessment_mode_list"> <legend>$r.translate("modes.title")</legend> <div class="o_info">$r.translate("modes.description")</div> - <div class="o_button_group o_button_group_right">$r.render("add")</div> + #if($r.available("add")) + <div class="o_button_group o_button_group_right">$r.render("add")</div> + #end $r.render("table") - <div class="o_button_group">$r.render("delete")</div> + #if($r.available("delete")) + <div class="o_button_group">$r.render("delete")</div> + #end </fieldset> \ No newline at end of file diff --git a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentCourseOverviewController.java b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentCourseOverviewController.java index bc2528f4d804e0bd00a53bc944cd1fad3f9f1557..42092090f08a2b07c0d510de2cb134c6b21f1103 100644 --- a/src/main/java/org/olat/course/assessment/ui/tool/AssessmentCourseOverviewController.java +++ b/src/main/java/org/olat/course/assessment/ui/tool/AssessmentCourseOverviewController.java @@ -84,7 +84,7 @@ public class AssessmentCourseOverviewController extends BasicController { ICourse course = CourseFactory.loadCourse(courseEntry); boolean hasAssessableNodes = course.hasAssessableNodes(); - mainVC.contextPut("hasAssessableNodes", new Boolean(hasAssessableNodes)); + mainVC.contextPut("hasAssessableNodes", Boolean.valueOf(hasAssessableNodes)); // assessment changes subscription if (hasAssessableNodes) { diff --git a/src/main/java/org/olat/course/groupsandrights/PersistingCourseGroupManager.java b/src/main/java/org/olat/course/groupsandrights/PersistingCourseGroupManager.java index 7c2a960ec4a204cb0d43e35a9db367b3b06f246b..2f843be43bd0e58039f39db8e1487bfa00f9f040 100644 --- a/src/main/java/org/olat/course/groupsandrights/PersistingCourseGroupManager.java +++ b/src/main/java/org/olat/course/groupsandrights/PersistingCourseGroupManager.java @@ -278,7 +278,7 @@ public class PersistingCourseGroupManager implements CourseGroupManager { // not really a group management method, for your convenience we have a // shortcut here... return repositoryService.hasRoleExpanded(identity, getCourseEntry(), OrganisationRoles.administrator.name(), - OrganisationRoles.learnresourcemanager.name(), GroupRoles.owner.name()); + OrganisationRoles.principal.name(), OrganisationRoles.learnresourcemanager.name(), GroupRoles.owner.name()); } @Override diff --git a/src/main/java/org/olat/course/member/MemberListController.java b/src/main/java/org/olat/course/member/MemberListController.java index c9a2f2d2d36e29b35c2c69711eb69c897620ed1d..9975d05594645d1c7c94ccc2b38f0304b8592ac3 100644 --- a/src/main/java/org/olat/course/member/MemberListController.java +++ b/src/main/java/org/olat/course/member/MemberListController.java @@ -27,6 +27,7 @@ import org.olat.core.util.StringHelper; import org.olat.course.assessment.ui.tool.AssessmentIdentityCourseController; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.group.ui.main.AbstractMemberListController; +import org.olat.group.ui.main.MemberListSecurityCallback; import org.olat.group.ui.main.MemberRow; import org.olat.group.ui.main.SearchMembersParams; import org.olat.repository.RepositoryEntry; @@ -43,8 +44,9 @@ public class MemberListController extends AbstractMemberListController { private final UserCourseEnvironment coachCourseEnv; public MemberListController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel, - RepositoryEntry repoEntry, UserCourseEnvironment coachCourseEnv, SearchMembersParams searchParams, String infos) { - super(ureq, wControl, repoEntry, "all_member_list", coachCourseEnv.isCourseReadOnly(), stackPanel); + RepositoryEntry repoEntry, UserCourseEnvironment coachCourseEnv, MemberListSecurityCallback secCallback, + SearchMembersParams searchParams, String infos) { + super(ureq, wControl, repoEntry, "all_member_list", secCallback, stackPanel); this.searchParams = searchParams; this.coachCourseEnv = coachCourseEnv; diff --git a/src/main/java/org/olat/course/member/MemberListWithOriginFilterController.java b/src/main/java/org/olat/course/member/MemberListWithOriginFilterController.java index 6c0bb08ae71e32e1d4467b9f5f6ec9e9fcd76126..741fe2003c48e1228347d5d3f74c33244f09706e 100644 --- a/src/main/java/org/olat/course/member/MemberListWithOriginFilterController.java +++ b/src/main/java/org/olat/course/member/MemberListWithOriginFilterController.java @@ -32,6 +32,7 @@ import org.olat.core.util.StringHelper; import org.olat.course.assessment.ui.tool.AssessmentIdentityCourseController; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.group.ui.main.AbstractMemberListController; +import org.olat.group.ui.main.MemberListSecurityCallback; import org.olat.group.ui.main.MemberRow; import org.olat.group.ui.main.SearchMembersParams; import org.olat.group.ui.main.SearchMembersParams.Origin; @@ -53,8 +54,8 @@ public class MemberListWithOriginFilterController extends AbstractMemberListCont private final UserCourseEnvironment coachCourseEnv; public MemberListWithOriginFilterController(UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbarPanel, - RepositoryEntry repoEntry, UserCourseEnvironment coachCourseEnv, SearchMembersParams searchParams, String infos) { - super(ureq, wControl, repoEntry, "member_list_origin_filter", coachCourseEnv.isCourseReadOnly(), toolbarPanel); + RepositoryEntry repoEntry, UserCourseEnvironment coachCourseEnv, MemberListSecurityCallback secCallback, SearchMembersParams searchParams, String infos) { + super(ureq, wControl, repoEntry, "member_list_origin_filter", secCallback, toolbarPanel); this.searchParams = searchParams; this.coachCourseEnv = coachCourseEnv; diff --git a/src/main/java/org/olat/course/member/MemberSearchController.java b/src/main/java/org/olat/course/member/MemberSearchController.java index 1961cac53964906b470d9743dad4f468e363ae2b..cf897083f6875499641c8b7a0f61e7da18cdb77e 100644 --- a/src/main/java/org/olat/course/member/MemberSearchController.java +++ b/src/main/java/org/olat/course/member/MemberSearchController.java @@ -29,6 +29,7 @@ import org.olat.core.id.Identity; import org.olat.course.assessment.ui.tool.AssessmentIdentityCourseController; import org.olat.course.run.userview.UserCourseEnvironment; import org.olat.group.ui.main.AbstractMemberListController; +import org.olat.group.ui.main.MemberListSecurityCallback; import org.olat.group.ui.main.MemberRow; import org.olat.group.ui.main.SearchMembersParams; import org.olat.repository.RepositoryEntry; @@ -46,8 +47,8 @@ public class MemberSearchController extends AbstractMemberListController { private AssessmentIdentityCourseController identityAssessmentController; public MemberSearchController(UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbarPanel, - RepositoryEntry repoEntry, UserCourseEnvironment coachCourseEnv) { - super(ureq, wControl, repoEntry, "all_member_list", coachCourseEnv.isCourseReadOnly(), toolbarPanel); + RepositoryEntry repoEntry, UserCourseEnvironment coachCourseEnv, MemberListSecurityCallback secCallback) { + super(ureq, wControl, repoEntry, "all_member_list", secCallback, toolbarPanel); this.coachCourseEnv = coachCourseEnv; } diff --git a/src/main/java/org/olat/course/member/MembersManagementMainController.java b/src/main/java/org/olat/course/member/MembersManagementMainController.java index 610d9e1c8f04170df8bc512741944959a44718b2..7974490eaacafdfce7a5cda8df7f751f26e99f38 100644 --- a/src/main/java/org/olat/course/member/MembersManagementMainController.java +++ b/src/main/java/org/olat/course/member/MembersManagementMainController.java @@ -47,6 +47,8 @@ import org.olat.course.CourseFactory; import org.olat.course.ICourse; import org.olat.course.groupsandrights.GroupsAndRightsController; import org.olat.course.run.userview.UserCourseEnvironment; +import org.olat.group.ui.main.MemberListSecurityCallback; +import org.olat.group.ui.main.MemberListSecurityCallbackFactory; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryManagedFlag; import org.olat.resource.accesscontrol.ACService; @@ -84,7 +86,11 @@ public class MembersManagementMainController extends MainLayoutBasicController i private RepositoryEntry repoEntry; private final UserCourseEnvironment coachCourseEnv; - private final boolean entryAdmin, groupManagementRight, memberManagementRight; + private final boolean entryAdmin; + private final boolean principal; + private final boolean groupManagementRight; + private final boolean memberManagementRight; + private final MemberListSecurityCallback secCallback; @Autowired private ACService acService; @@ -92,15 +98,18 @@ public class MembersManagementMainController extends MainLayoutBasicController i private AccessControlModule acModule; public MembersManagementMainController(UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbarPanel, - RepositoryEntry re, UserCourseEnvironment coachCourseEnv, boolean entryAdmin, + RepositoryEntry re, UserCourseEnvironment coachCourseEnv, boolean entryAdmin, boolean principal, boolean groupManagementRight, boolean memberManagementRight) { super(ureq, wControl); this.repoEntry = re; this.toolbarPanel = toolbarPanel; this.entryAdmin = entryAdmin; + this.principal = principal; this.groupManagementRight = groupManagementRight; this.memberManagementRight = memberManagementRight; this.coachCourseEnv = coachCourseEnv; + secCallback = MemberListSecurityCallbackFactory.getSecurityCallback(coachCourseEnv.isCourseReadOnly(), + entryAdmin || groupManagementRight || memberManagementRight); //logging getUserActivityLogger().setStickyActionType(ActionType.admin); @@ -119,7 +128,7 @@ public class MembersManagementMainController extends MainLayoutBasicController i listenTo(columnLayoutCtr); putInitialPanel(columnLayoutCtr.getInitialComponent()); - if(entryAdmin || memberManagementRight) { + if(entryAdmin || principal || memberManagementRight) { selectMenuItem(ureq, CMD_MEMBERS); } else if(groupManagementRight) { selectMenuItem(ureq, CMD_GROUPS); @@ -133,21 +142,21 @@ public class MembersManagementMainController extends MainLayoutBasicController i root.setAltText(translate("menu.members.alt")); gtm.setRootNode(root); - if(entryAdmin || memberManagementRight) { + if(entryAdmin || principal || memberManagementRight) { GenericTreeNode node = new GenericTreeNode(translate("menu.members"), CMD_MEMBERS); node.setAltText(translate("menu.members.alt")); node.setCssClass("o_sel_membersmgt_members"); root.addChild(node); } - if(entryAdmin || memberManagementRight || groupManagementRight) { + if(entryAdmin || principal || memberManagementRight || groupManagementRight) { GenericTreeNode node = new GenericTreeNode(translate("menu.groups"), CMD_GROUPS); node.setAltText(translate("menu.groups.alt")); node.setCssClass("o_sel_membersmgt_groups"); root.addChild(node); } - if(acModule.isEnabled() && (entryAdmin || memberManagementRight)) { + if(acModule.isEnabled() && (entryAdmin || principal || memberManagementRight)) { //check if the course is managed and/or has offers if(!RepositoryEntryManagedFlag.isManaged(repoEntry, RepositoryEntryManagedFlag.bookings) || acService.isResourceAccessControled(repoEntry.getOlatResource(), null)) { @@ -158,7 +167,7 @@ public class MembersManagementMainController extends MainLayoutBasicController i } } - if(entryAdmin) { + if(entryAdmin || principal) { GenericTreeNode node = new GenericTreeNode(translate("menu.rights"), CMD_RIGHTS); node.setAltText(translate("menu.rights.alt")); node.setCssClass("o_sel_membersmgt_rights"); @@ -214,9 +223,9 @@ public class MembersManagementMainController extends MainLayoutBasicController i Controller selectedCtrl = null; if(CMD_MEMBERS.equals(cmd)) { - if(entryAdmin || memberManagementRight) { + if(entryAdmin || principal || memberManagementRight) { if(membersOverviewCtrl == null) { - membersOverviewCtrl = new MembersOverviewController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv); + membersOverviewCtrl = new MembersOverviewController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv, secCallback); listenTo(membersOverviewCtrl); } else if(membersDirty) { membersOverviewCtrl.reloadMembers(); @@ -225,7 +234,7 @@ public class MembersManagementMainController extends MainLayoutBasicController i selectedCtrl = membersOverviewCtrl; } } else if(CMD_GROUPS.equals(cmd)) { - if(entryAdmin || memberManagementRight || groupManagementRight) { + if(entryAdmin || principal || memberManagementRight || groupManagementRight) { if(groupsCtrl == null) { groupsCtrl = new CourseBusinessGroupListController(ureq, bwControl, repoEntry, entryAdmin || groupManagementRight, coachCourseEnv.isCourseReadOnly()); listenTo(groupsCtrl); @@ -235,7 +244,7 @@ public class MembersManagementMainController extends MainLayoutBasicController i selectedCtrl = groupsCtrl; } } else if(CMD_BOOKING.equals(cmd)) { - if(acModule.isEnabled() && (entryAdmin || memberManagementRight)) { + if(acModule.isEnabled() && (entryAdmin || principal || memberManagementRight)) { if(ordersController == null) { ordersController = new OrdersAdminController(ureq, bwControl, toolbarPanel, repoEntry.getOlatResource()); listenTo(ordersController); @@ -244,7 +253,7 @@ public class MembersManagementMainController extends MainLayoutBasicController i selectedCtrl = ordersController; } } else if(CMD_RIGHTS.equals(cmd)) { - if(entryAdmin) { + if(entryAdmin || principal) { if(rightsController == null) { rightsController = new GroupsAndRightsController(ureq, bwControl, repoEntry, coachCourseEnv.isCourseReadOnly()); listenTo(rightsController); diff --git a/src/main/java/org/olat/course/member/MembersOverviewController.java b/src/main/java/org/olat/course/member/MembersOverviewController.java index e98d3631797899e17abe9c328f7e9ea3e3c75a79..43522a2c71e5e434211d382b49879c65966af632 100644 --- a/src/main/java/org/olat/course/member/MembersOverviewController.java +++ b/src/main/java/org/olat/course/member/MembersOverviewController.java @@ -62,6 +62,7 @@ import org.olat.group.BusinessGroupService; import org.olat.group.model.BusinessGroupMembershipChange; import org.olat.group.ui.main.AbstractMemberListController; import org.olat.group.ui.main.DedupMembersConfirmationController; +import org.olat.group.ui.main.MemberListSecurityCallback; import org.olat.group.ui.main.MemberPermissionChangeEvent; import org.olat.group.ui.main.SearchMembersParams; import org.olat.modules.curriculum.CurriculumService; @@ -112,6 +113,7 @@ public class MembersOverviewController extends BasicController implements Activa private boolean overrideManaged = false; private final RepositoryEntry repoEntry; private final UserCourseEnvironment coachCourseEnv; + private final MemberListSecurityCallback secCallback; @Autowired private RepositoryManager repositoryManager; @@ -123,11 +125,12 @@ public class MembersOverviewController extends BasicController implements Activa private BusinessGroupService businessGroupService; public MembersOverviewController(UserRequest ureq, WindowControl wControl, TooledStackedPanel toolbarPanel, - RepositoryEntry repoEntry, UserCourseEnvironment coachCourseEnv) { + RepositoryEntry repoEntry, UserCourseEnvironment coachCourseEnv, MemberListSecurityCallback secCallback) { super(ureq, wControl); this.repoEntry = repoEntry; this.toolbarPanel = toolbarPanel; this.coachCourseEnv = coachCourseEnv; + this.secCallback = secCallback; mainVC = createVelocityContainer("members_overview"); segmentView = SegmentViewFactory.createSegmentView("segments", mainVC, this); @@ -352,12 +355,9 @@ public class MembersOverviewController extends BasicController implements Activa removeAsListenerAndDispose(importMembersWizard); Step start = new ImportMember_1b_ChooseMemberStep(ureq, repoEntry, null, overrideManaged); - StepRunnerCallback finish = new StepRunnerCallback() { - @Override - public Step execute(UserRequest uureq, WindowControl wControl, StepsRunContext runContext) { - addMembers(uureq, runContext); - return StepsMainRunController.DONE_MODIFIED; - } + StepRunnerCallback finish = (uureq, wControl, runContext) -> { + addMembers(uureq, runContext); + return StepsMainRunController.DONE_MODIFIED; }; importMembersWizard = new StepsMainRunController(ureq, getWindowControl(), start, finish, null, @@ -370,15 +370,12 @@ public class MembersOverviewController extends BasicController implements Activa removeAsListenerAndDispose(importMembersWizard); Step start = new ImportMember_1a_LoginListStep(ureq, repoEntry, null, overrideManaged); - StepRunnerCallback finish = new StepRunnerCallback() { - @Override - public Step execute(UserRequest uureq, WindowControl wControl, StepsRunContext runContext) { - addMembers(uureq, runContext); - if(runContext.containsKey("notFounds")) { - showWarning("user.notfound", runContext.get("notFounds").toString()); - } - return StepsMainRunController.DONE_MODIFIED; + StepRunnerCallback finish = (uureq, wControl, runContext) -> { + addMembers(uureq, runContext); + if(runContext.containsKey("notFounds")) { + showWarning("user.notfound", runContext.get("notFounds").toString()); } + return StepsMainRunController.DONE_MODIFIED; }; importMembersWizard = new StepsMainRunController(ureq, getWindowControl(), start, finish, null, @@ -457,7 +454,7 @@ public class MembersOverviewController extends BasicController implements Activa ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores)); WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl()); SearchMembersParams searchParams = new SearchMembersParams(true, GroupRoles.owner, GroupRoles.coach, GroupRoles.participant); - allMemberListCtrl = new MemberListWithOriginFilterController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv, searchParams, null); + allMemberListCtrl = new MemberListWithOriginFilterController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv, secCallback, searchParams, null); listenTo(allMemberListCtrl); } @@ -475,7 +472,7 @@ public class MembersOverviewController extends BasicController implements Activa WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl()); SearchMembersParams searchParams = new SearchMembersParams(false, GroupRoles.owner); String infos = translate("owners.infos"); - ownersCtrl = new MemberListController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv, searchParams, infos); + ownersCtrl = new MemberListController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv, secCallback, searchParams, infos); listenTo(ownersCtrl); } @@ -493,7 +490,7 @@ public class MembersOverviewController extends BasicController implements Activa WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl()); SearchMembersParams searchParams = new SearchMembersParams(false, GroupRoles.coach); String infos = translate("tutors.infos"); - tutorsCtrl = new MemberListWithOriginFilterController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv, searchParams, infos); + tutorsCtrl = new MemberListWithOriginFilterController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv, secCallback, searchParams, infos); listenTo(tutorsCtrl); } @@ -511,7 +508,7 @@ public class MembersOverviewController extends BasicController implements Activa WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl()); SearchMembersParams searchParams = new SearchMembersParams(false, GroupRoles.participant); String infos = translate("participants.infos"); - participantsCtrl = new MemberListWithOriginFilterController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv, searchParams, infos); + participantsCtrl = new MemberListWithOriginFilterController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv, secCallback, searchParams, infos); listenTo(participantsCtrl); } @@ -529,7 +526,7 @@ public class MembersOverviewController extends BasicController implements Activa WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl()); SearchMembersParams searchParams = new SearchMembersParams(false, GroupRoles.waiting); String infos = translate("waiting.infos"); - waitingCtrl = new MemberListController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv, searchParams, infos); + waitingCtrl = new MemberListController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv, secCallback, searchParams, infos); listenTo(waitingCtrl); } @@ -545,7 +542,7 @@ public class MembersOverviewController extends BasicController implements Activa OLATResourceable ores = OresHelper.createOLATResourceableInstance(SEG_SEARCH_MEMBERS, 0l); ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores)); WindowControl bwControl = BusinessControlFactory.getInstance().createBusinessWindowControl(ores, null, getWindowControl()); - searchCtrl = new MemberSearchController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv); + searchCtrl = new MemberSearchController(ureq, bwControl, toolbarPanel, repoEntry, coachCourseEnv, secCallback); listenTo(searchCtrl); } diff --git a/src/main/java/org/olat/course/nodes/GoToMeetingCourseNode.java b/src/main/java/org/olat/course/nodes/GoToMeetingCourseNode.java index 14c5d113eed4627514c312567e954fa0d653bf3c..b04b87fbdb965e5eb3d9746960b16f47fac2cdca 100644 --- a/src/main/java/org/olat/course/nodes/GoToMeetingCourseNode.java +++ b/src/main/java/org/olat/course/nodes/GoToMeetingCourseNode.java @@ -109,9 +109,8 @@ public class GoToMeetingCourseNode extends AbstractAccessableCourseNode { controller = MessageUIFactory.createInfoMessage(ureq, wControl, title, message); } else { // check if user is moderator of the virtual classroom - CourseGroupManager cgm = userCourseEnv.getCourseEnvironment().getCourseGroupManager(); - boolean admin = cgm.isIdentityCourseAdministrator(ureq.getIdentity()); - boolean moderator = admin || cgm.isIdentityCourseCoach(ureq.getIdentity()); + boolean admin = userCourseEnv.isAdmin(); + boolean moderator = admin || userCourseEnv.isCoach(); // create run controller RepositoryEntry courseEntry = userCourseEnv.getCourseEnvironment().getCourseGroupManager().getCourseEntry(); diff --git a/src/main/java/org/olat/course/nodes/OpenMeetingsCourseNode.java b/src/main/java/org/olat/course/nodes/OpenMeetingsCourseNode.java index 95dd323a9f733d8d0d8a9b2d5bb75df8f11b672f..24f0153e0ebd762424d0193630663a1c0961a6e2 100644 --- a/src/main/java/org/olat/course/nodes/OpenMeetingsCourseNode.java +++ b/src/main/java/org/olat/course/nodes/OpenMeetingsCourseNode.java @@ -102,9 +102,8 @@ public class OpenMeetingsCourseNode extends AbstractAccessableCourseNode { updateModuleConfigDefaults(false); // check if user is moderator of the virtual classroom - CourseGroupManager cgm = userCourseEnv.getCourseEnvironment().getCourseGroupManager(); - boolean admin = cgm.isIdentityCourseAdministrator(ureq.getIdentity()); - boolean moderator = admin || cgm.isIdentityAnyCourseCoach(ureq.getIdentity()); + boolean admin = userCourseEnv.isAdmin(); + boolean moderator = admin || userCourseEnv.isCoach(); // create run controller OLATResourceable ores = OresHelper.clone(userCourseEnv.getCourseEnvironment().getCourseGroupManager().getCourseResource()); diff --git a/src/main/java/org/olat/course/nodes/STCourseNode.java b/src/main/java/org/olat/course/nodes/STCourseNode.java index 7e6583749c6577bed5a0163a750d3c220a69f2d9..84667ef192b9d3ce8881ca8b5b909d19f7b28753 100644 --- a/src/main/java/org/olat/course/nodes/STCourseNode.java +++ b/src/main/java/org/olat/course/nodes/STCourseNode.java @@ -176,9 +176,8 @@ public class STCourseNode extends AbstractAccessableCourseNode implements Calcul userCourseEnv.getCourseEnvironment().isPreview()); // check if user is allowed to edit the page in the run view CourseGroupManager cgm = userCourseEnv.getCourseEnvironment().getCourseGroupManager(); - boolean hasEditRights = (cgm.isIdentityCourseAdministrator(ureq.getIdentity()) - || cgm.hasRight(ureq.getIdentity(),CourseRights.RIGHT_COURSEEDITOR)) - || (getModuleConfiguration().getBooleanSafe(SPEditController.CONFIG_KEY_ALLOW_COACH_EDIT, false) && cgm.isIdentityCourseCoach(ureq.getIdentity())); + boolean hasEditRights = userCourseEnv.isAdmin() || cgm.hasRight(ureq.getIdentity(),CourseRights.RIGHT_COURSEEDITOR) + || (getModuleConfiguration().getBooleanSafe(SPEditController.CONFIG_KEY_ALLOW_COACH_EDIT, false) && userCourseEnv.isCoach()); if (hasEditRights) { spCtr.allowPageEditing(); diff --git a/src/main/java/org/olat/course/nodes/ViteroCourseNode.java b/src/main/java/org/olat/course/nodes/ViteroCourseNode.java index 66da0fad1098caea3afc65be7d79b5f8c0e2961b..bed4f7e4d41bc3171514cb656b1e48ed617f1b4a 100644 --- a/src/main/java/org/olat/course/nodes/ViteroCourseNode.java +++ b/src/main/java/org/olat/course/nodes/ViteroCourseNode.java @@ -39,7 +39,6 @@ import org.olat.course.condition.ConditionEditController; import org.olat.course.editor.CourseEditorEnv; import org.olat.course.editor.NodeEditController; import org.olat.course.editor.StatusDescription; -import org.olat.course.groupsandrights.CourseGroupManager; import org.olat.course.nodes.vitero.ViteroEditController; import org.olat.course.nodes.vitero.ViteroPeekViewController; import org.olat.course.run.navigation.NodeRunConstructionResult; @@ -103,8 +102,7 @@ public class ViteroCourseNode extends AbstractAccessableCourseNode { runCtr = MessageUIFactory.createInfoMessage(ureq, wControl, title, message); } else { // check if user is moderator of the virtual classroom - CourseGroupManager cgm = userCourseEnv.getCourseEnvironment().getCourseGroupManager(); - boolean moderator = cgm.isIdentityCourseAdministrator(ureq.getIdentity()); + boolean moderator = userCourseEnv.isAdmin(); // create run controller Long resourceId = userCourseEnv.getCourseEnvironment().getCourseResourceableId(); OLATResourceable ores = OresHelper.createOLATResourceableInstance(CourseModule.class, resourceId); diff --git a/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java b/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java index d32bcbf7c3928ddfd03515fdc2a717d6d0069383..b7ce93d27d6af8f792ae809b0e0ee2d0346aca35 100644 --- a/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java +++ b/src/main/java/org/olat/course/nodes/basiclti/LTIRunController.java @@ -53,7 +53,6 @@ import org.olat.core.util.Encoder; import org.olat.core.util.SortedProperties; import org.olat.core.util.StringHelper; import org.olat.core.util.Util; -import org.olat.course.groupsandrights.CourseGroupManager; import org.olat.course.highscore.ui.HighScoreRunController; import org.olat.course.nodes.BasicLTICourseNode; import org.olat.course.nodes.CourseNode; @@ -477,8 +476,7 @@ public class LTIRunController extends BasicController { if (roles.isGuestOnly()) { return "Guest"; } - CourseGroupManager groupManager = courseEnv.getCourseGroupManager(); - boolean admin = groupManager.isIdentityCourseAdministrator(getIdentity()); + boolean admin = userCourseEnv.isAdmin(); if(admin) { String authorRole = config.getStringValue(BasicLTICourseNode.CONFIG_KEY_AUTHORROLE); if(StringHelper.containsNonWhitespace(authorRole)) { @@ -486,7 +484,7 @@ public class LTIRunController extends BasicController { } return "Instructor,Administrator"; } - boolean coach = groupManager.isIdentityCourseCoach(getIdentity()); + boolean coach = userCourseEnv.isCoach(); if(coach) { String coachRole = config.getStringValue(BasicLTICourseNode.CONFIG_KEY_COACHROLE); if(StringHelper.containsNonWhitespace(coachRole)) { diff --git a/src/main/java/org/olat/course/nodes/bc/BCCourseNodeRunController.java b/src/main/java/org/olat/course/nodes/bc/BCCourseNodeRunController.java index ef7729a5694eef33a52e0e08434059c556308a5b..6e8013eb18972a22aff68dee148340b60876b3f4 100644 --- a/src/main/java/org/olat/course/nodes/bc/BCCourseNodeRunController.java +++ b/src/main/java/org/olat/course/nodes/bc/BCCourseNodeRunController.java @@ -106,7 +106,7 @@ public class BCCourseNodeRunController extends BasicController implements Activa VFSSecurityCallback scallback; if(courseNode.getModuleConfiguration().getBooleanSafe(BCCourseNodeEditController.CONFIG_AUTO_FOLDER)) { OlatNamedContainerImpl directory = BCCourseNode.getNodeFolderContainer(courseNode, courseEnv); - boolean isAdministrator = cgm.isIdentityCourseAdministrator(getIdentity()); + boolean isAdministrator = userCourseEnv.isAdmin(); scallback = new FolderNodeCallback(directory.getRelPath(), ne, isAdministrator, isGuestOnly, nodefolderSubContext); target = directory; } else if(courseNode.isSharedFolder()) { @@ -152,7 +152,7 @@ public class BCCourseNodeRunController extends BasicController implements Activa } else { relPath = VFSManager.getRelativeItemPath(target, courseContainer, null); } - boolean isAdministrator = cgm.isIdentityCourseAdministrator(getIdentity()); + boolean isAdministrator = userCourseEnv.isAdmin(); scallback = new FolderNodeCallback(relPath, ne, isAdministrator, isGuestOnly, nodefolderSubContext); } } @@ -167,7 +167,7 @@ public class BCCourseNodeRunController extends BasicController implements Activa VFSContainer courseContainer = null; if(scallback.canWrite() && scallback.canCopy()) { - if (cgm.isIdentityCourseAdministrator(getIdentity()) || cgm.hasRight(getIdentity(), CourseRights.RIGHT_COURSEEDITOR)) { + if (userCourseEnv.isAdmin() || cgm.hasRight(getIdentity(), CourseRights.RIGHT_COURSEEDITOR)) { // use course folder as copy source courseContainer = courseEnv.getCourseFolderContainer(); } diff --git a/src/main/java/org/olat/course/nodes/cal/CourseCalendars.java b/src/main/java/org/olat/course/nodes/cal/CourseCalendars.java index 090ffc3e035751bd91642d16aff95a22597efd00..4e50870eb8bf876d3c032d436a3d280505b21cd8 100644 --- a/src/main/java/org/olat/course/nodes/cal/CourseCalendars.java +++ b/src/main/java/org/olat/course/nodes/cal/CourseCalendars.java @@ -90,23 +90,21 @@ public class CourseCalendars { * @param ne * @return */ - public static KalendarRenderWrapper getCourseCalendarWrapper(UserRequest ureq, UserCourseEnvironment courseEnv, NodeEvaluation ne) { + public static KalendarRenderWrapper getCourseCalendarWrapper(UserRequest ureq, UserCourseEnvironment userCourseEnv, NodeEvaluation ne) { CalendarManager calendarManager = CoreSpringFactory.getImpl(CalendarManager.class); // add course calendar - ICourse course = CourseFactory.loadCourse(courseEnv.getCourseEnvironment().getCourseResourceableId()); + ICourse course = CourseFactory.loadCourse(userCourseEnv.getCourseEnvironment().getCourseResourceableId()); KalendarRenderWrapper courseKalendarWrapper = calendarManager.getCourseCalendar(course); - CourseGroupManager cgm = course.getCourseEnvironment().getCourseGroupManager(); - boolean isPrivileged = !courseEnv.isCourseReadOnly() && - (courseEnv.isAdmin() - || (ne != null && ne.isCapabilityAccessible(CalCourseNode.EDIT_CONDITION_ID)) - || cgm.isIdentityCourseAdministrator(ureq.getIdentity())); + boolean isPrivileged = !userCourseEnv.isCourseReadOnly() && + (userCourseEnv.isAdmin() + || (ne != null && ne.isCapabilityAccessible(CalCourseNode.EDIT_CONDITION_ID))); if (isPrivileged) { courseKalendarWrapper.setAccess(KalendarRenderWrapper.ACCESS_READ_WRITE); courseKalendarWrapper.setPrivateEventsVisible(true); } else { courseKalendarWrapper.setAccess(KalendarRenderWrapper.ACCESS_READ_ONLY); - courseKalendarWrapper.setPrivateEventsVisible(courseEnv.isAdmin() || courseEnv.isCoach() || courseEnv.isParticipant()); + courseKalendarWrapper.setPrivateEventsVisible(userCourseEnv.isAdmin() || userCourseEnv.isCoach() || userCourseEnv.isParticipant()); } CalendarUserConfiguration config = calendarManager.findCalendarConfigForIdentity(courseKalendarWrapper.getKalendar(), ureq.getIdentity()); if (config != null) { @@ -115,10 +113,10 @@ public class CourseCalendars { return courseKalendarWrapper; } - public static CourseCalendars createCourseCalendarsWrapper(UserRequest ureq, WindowControl wControl, UserCourseEnvironment courseEnv, NodeEvaluation ne) { + public static CourseCalendars createCourseCalendarsWrapper(UserRequest ureq, WindowControl wControl, UserCourseEnvironment userCourseEnv, NodeEvaluation ne) { List<KalendarRenderWrapper> calendars = new ArrayList<>(); - ICourse course = CourseFactory.loadCourse(courseEnv.getCourseEnvironment().getCourseResourceableId()); - KalendarRenderWrapper courseKalendarWrapper = getCourseCalendarWrapper(ureq, courseEnv, ne); + ICourse course = CourseFactory.loadCourse(userCourseEnv.getCourseEnvironment().getCourseResourceableId()); + KalendarRenderWrapper courseKalendarWrapper = getCourseCalendarWrapper(ureq, userCourseEnv, ne); // add link provider CourseLinkProviderController clpc = new CourseLinkProviderController(course, Collections.singletonList(course), ureq, wControl); @@ -130,25 +128,25 @@ public class CourseCalendars { // add course group calendars Roles roles = ureq.getUserSession().getRoles(); - boolean isGroupManager = roles.isGroupManager() || cgm.isIdentityCourseAdministrator(identity) + boolean isGroupManager = roles.isGroupManager() || userCourseEnv.isAdmin() || cgm.hasRight(identity, CourseRights.RIGHT_GROUPMANAGEMENT); - boolean readOnly = courseEnv.isCourseReadOnly(); + boolean readOnly = userCourseEnv.isCourseReadOnly(); if (isGroupManager) { // learning groups List<BusinessGroup> allGroups = cgm.getAllBusinessGroups(); - addCalendars(ureq, courseEnv, allGroups, !readOnly, clpc, calendars); + addCalendars(ureq, userCourseEnv, allGroups, !readOnly, clpc, calendars); } else { // learning groups List<BusinessGroup> ownerGroups = cgm.getOwnedBusinessGroups(identity); - addCalendars(ureq, courseEnv, ownerGroups, !readOnly, clpc, calendars); + addCalendars(ureq, userCourseEnv, ownerGroups, !readOnly, clpc, calendars); List<BusinessGroup> attendedGroups = cgm.getParticipatingBusinessGroups(identity); for (BusinessGroup ownerGroup : ownerGroups) { if (attendedGroups.contains(ownerGroup)) { attendedGroups.remove(ownerGroup); } } - addCalendars(ureq, courseEnv, attendedGroups, false, clpc, calendars); + addCalendars(ureq, userCourseEnv, attendedGroups, false, clpc, calendars); } return new CourseCalendars(courseKalendarWrapper, calendars); } diff --git a/src/main/java/org/olat/course/nodes/cl/manager/CheckboxManagerImpl.java b/src/main/java/org/olat/course/nodes/cl/manager/CheckboxManagerImpl.java index 36740483440a5caf837a1fcee012374094f0a2b4..ff97eefb31a5385bc9da23c5a3debc6ef216eaf9 100644 --- a/src/main/java/org/olat/course/nodes/cl/manager/CheckboxManagerImpl.java +++ b/src/main/java/org/olat/course/nodes/cl/manager/CheckboxManagerImpl.java @@ -458,13 +458,12 @@ public class CheckboxManagerImpl implements CheckboxManager { if(admin) { sb.append(" and exists (select participant.key from bgroupmember as participant") - .append(" baseGroup.key=participant.group and participant.role='").append(GroupRoles.participant.name()).append("'") + .append(" where baseGroup.key=participant.group and participant.role='").append(GroupRoles.participant.name()).append("'") .append(" )"); } else { sb.append(" and exists (select participant.key from bgroupmember as participant, bgroupmember as coach") - .append(" where") - .append(" baseGroup.key=coach.group and coach.role='").append(GroupRoles.coach.name()).append("' and coach.identity.key=:coachKey") - .append(" and baseGroup.key=participant.group and participant.role='").append(GroupRoles.participant.name()).append("'") + .append(" where baseGroup.key=coach.group and coach.role='").append(GroupRoles.coach.name()).append("' and coach.identity.key=:coachKey") + .append(" and baseGroup.key=participant.group and participant.role='").append(GroupRoles.participant.name()).append("'") .append(" )"); } diff --git a/src/main/java/org/olat/course/nodes/dialog/ui/DialogCourseNodeRunController.java b/src/main/java/org/olat/course/nodes/dialog/ui/DialogCourseNodeRunController.java index 661183928f7737b2fb94c291f2ce5b62d93a4807..7a66858b498ddb68f9416815b7384f7173b48f44 100644 --- a/src/main/java/org/olat/course/nodes/dialog/ui/DialogCourseNodeRunController.java +++ b/src/main/java/org/olat/course/nodes/dialog/ui/DialogCourseNodeRunController.java @@ -151,9 +151,8 @@ public class DialogCourseNodeRunController extends BasicController implements Ac backButton = LinkFactory.createLinkBack(mainVC, this); - if (!userCourseEnv.isCourseReadOnly() && (isAdministrator - || cgm.isIdentityCourseAdministrator(getIdentity()) - || cgm.hasRight(getIdentity(), CourseRights.RIGHT_COURSEEDITOR))) { + if (!userCourseEnv.isCourseReadOnly() + && (isAdministrator || userCourseEnv.isAdmin() || cgm.hasRight(getIdentity(), CourseRights.RIGHT_COURSEEDITOR))) { copyButton = LinkFactory.createButton("dialog.copy.file", mainVC, this); } diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTAAssessmentDetailsController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTAAssessmentDetailsController.java index 298f3752ce9f91f9430b11ec917b9804ca57b9c9..8bdd3ea50300f53b01e20d91c29eca7da311b293 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTAAssessmentDetailsController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTAAssessmentDetailsController.java @@ -93,7 +93,7 @@ public class GTAAssessmentDetailsController extends BasicController implements A } CourseGroupManager cgm = courseEnv.getCourseGroupManager(); - if(!cgm.isIdentityCourseAdministrator(getIdentity())) { + if(!coachCourseEnv.isAdmin()) { RepositoryEntry courseRe = cgm.getCourseEntry(); List<String> reRoles = repositoryService.getRoles(getIdentity(), courseRe); if(reRoles.contains(GroupRoles.owner.name())) { diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedParticipantListController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedParticipantListController.java index 3d5006589876b9fb74d764b0f8499edce5d91f49..fa208a9284bbf6ee3ed820bd81eb11af5d760091 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedParticipantListController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTACoachedParticipantListController.java @@ -228,7 +228,7 @@ public class GTACoachedParticipantListController extends GTACoachedListControlle columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(CGCols.numOfSubmissionDocs.i18nKey(), CGCols.numOfSubmissionDocs.ordinal(), true, CGCols.numOfSubmissionDocs.name())); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("select", translate("select"), "select")); - if(gtaManager.isDueDateEnabled(gtaNode)) { + if(gtaManager.isDueDateEnabled(gtaNode) && !coachCourseEnv.isCourseReadOnly()) { columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("table.header.duedates", translate("duedates"), "duedates")); } tableModel = new CoachParticipantsTableModel(userPropertyHandlers, getLocale(), columnsModel); diff --git a/src/main/java/org/olat/course/nodes/info/InfoRunController.java b/src/main/java/org/olat/course/nodes/info/InfoRunController.java index a13c5ed76f389c67315f28807b262724c97c7c8c..0357267bb55727106864c4059c79448e6177a7b2 100644 --- a/src/main/java/org/olat/course/nodes/info/InfoRunController.java +++ b/src/main/java/org/olat/course/nodes/info/InfoRunController.java @@ -110,8 +110,7 @@ public class InfoRunController extends BasicController { canAdd = false; canAdmin = false; } else { - Identity identity = getIdentity(); - boolean isAdmin = cgm.isIdentityCourseAdministrator(identity); + boolean isAdmin = userCourseEnv.isAdmin(); canAdd = isAdmin || ne.isCapabilityAccessible(InfoCourseNode.EDIT_CONDITION_ID); canAdmin = isAdmin || ne.isCapabilityAccessible(InfoCourseNode.ADMIN_CONDITION_ID); } diff --git a/src/main/java/org/olat/course/nodes/projectbroker/ProjectListController.java b/src/main/java/org/olat/course/nodes/projectbroker/ProjectListController.java index c781f68db7dac183170310f1f4ba4c9918e707d7..345d24fa3705d7aaeb2bf86c2f0f6ce34cac8b61 100644 --- a/src/main/java/org/olat/course/nodes/projectbroker/ProjectListController.java +++ b/src/main/java/org/olat/course/nodes/projectbroker/ProjectListController.java @@ -155,7 +155,7 @@ public class ProjectListController extends BasicController implements GenericEve mainPanel = new SimpleStackedPanel("projectlist_panel"); CoursePropertyManager cpm = userCourseEnv.getCourseEnvironment().getCoursePropertyManager(); if ((projectGroupManager.isAccountManager(ureq.getIdentity(), cpm, courseNode ) && !previewMode) - || userCourseEnv.getCourseEnvironment().getCourseGroupManager().isIdentityCourseAdministrator(ureq.getIdentity())) { + || userCourseEnv.isAdmin()) { contentVC.contextPut("isAccountManager", true); createNewProjectButton = LinkFactory.createButtonSmall("create.new.project.button", contentVC, this); createNewProjectButton.setIconLeftCSS("o_icon o_icon_add"); diff --git a/src/main/java/org/olat/course/nodes/sp/SPRunController.java b/src/main/java/org/olat/course/nodes/sp/SPRunController.java index 9d02ff49d38cbf6827cbc2b3c0735ae32af4ed27..2c2a2d5d61dcc7d09d676697b5eb26706e85295d 100644 --- a/src/main/java/org/olat/course/nodes/sp/SPRunController.java +++ b/src/main/java/org/olat/course/nodes/sp/SPRunController.java @@ -114,7 +114,7 @@ public class SPRunController extends BasicController implements Activateable2 { if (fileName == null) throw new AssertException("bad configuration at lauchtime: fileName cannot be null in SinglePage!"); this.courseFolderContainer = courseFolderContainer; - hasEditRights = hasEditRights(ureq); + hasEditRights = hasEditRights(); if (hasEditRights) { linkTreeModel = new CourseInternalLinkTreeModel(userCourseEnv.getCourseEnvironment().getRunStructure().getRootNode()); @@ -126,7 +126,7 @@ public class SPRunController extends BasicController implements Activateable2 { putInitialPanel(main); } - private boolean hasEditRights(UserRequest ureq) { + private boolean hasEditRights() { if(userCourseEnv.isCourseReadOnly()) return false; if(fileName != null && fileName.startsWith("/_sharedfolder")) { @@ -137,9 +137,8 @@ public class SPRunController extends BasicController implements Activateable2 { if(isFileTypeEditable(fileName)) { CourseGroupManager cgm = userCourseEnv.getCourseEnvironment().getCourseGroupManager(); - return config.getBooleanSafe(SPEditController.CONFIG_KEY_ALLOW_COACH_EDIT, false) && cgm.isIdentityCourseCoach(ureq.getIdentity()) - || cgm.isIdentityCourseAdministrator(getIdentity()) - || cgm.hasRight(getIdentity(), CourseRights.RIGHT_COURSEEDITOR); + return (config.getBooleanSafe(SPEditController.CONFIG_KEY_ALLOW_COACH_EDIT, false) && userCourseEnv.isCoach()) + || userCourseEnv.isAdmin() || cgm.hasRight(getIdentity(), CourseRights.RIGHT_COURSEEDITOR); } return false; diff --git a/src/main/java/org/olat/course/nodes/ta/DropboxController.java b/src/main/java/org/olat/course/nodes/ta/DropboxController.java index 08cd0d4ca9d2bea0fc0d54bdec1212038f12c0e2..761733a9678147b3888dde0d9682091d5f44ccba 100644 --- a/src/main/java/org/olat/course/nodes/ta/DropboxController.java +++ b/src/main/java/org/olat/course/nodes/ta/DropboxController.java @@ -129,9 +129,7 @@ public class DropboxController extends BasicController { this.config = config; this.node = node; this.userCourseEnv = userCourseEnv; - boolean isCourseAdmin = userCourseEnv.getCourseEnvironment().getCourseGroupManager().isIdentityCourseAdministrator(ureq.getIdentity()); - boolean isCourseCoach = userCourseEnv.getCourseEnvironment().getCourseGroupManager().isIdentityCourseCoach(ureq.getIdentity()); - boolean hasNotification = (isCourseAdmin || isCourseCoach); + boolean hasNotification = userCourseEnv.isAdmin() || userCourseEnv.isCoach(); init(ureq, wControl, previewMode, hasNotification); } diff --git a/src/main/java/org/olat/course/nodes/ta/DropboxScoringViewController.java b/src/main/java/org/olat/course/nodes/ta/DropboxScoringViewController.java index cb7693951a945109a7c84435d90971d433534917..6885027bd39d1bea72f22b97823901fa20ff3157 100644 --- a/src/main/java/org/olat/course/nodes/ta/DropboxScoringViewController.java +++ b/src/main/java/org/olat/course/nodes/ta/DropboxScoringViewController.java @@ -209,7 +209,7 @@ public class DropboxScoringViewController extends BasicController { // insert Status Pull-Down Menu depending on user role == author boolean isAuthor = ureq.getUserSession().getRoles().isAuthor(); - boolean isTutor = userCourseEnv.getCourseEnvironment().getCourseGroupManager().isIdentityCourseCoach(ureq.getIdentity()); + boolean isTutor = userCourseEnv.isCoach(); if ( ((AssessableCourseNode)node).hasStatusConfigured() && (isAuthor || isTutor)) { myContent.contextPut("hasStatusPullDown", Boolean.TRUE); statusForm = new StatusForm(ureq, getWindowControl(), userCourseEnv.isCourseReadOnly()); diff --git a/src/main/java/org/olat/course/run/CourseRuntimeController.java b/src/main/java/org/olat/course/run/CourseRuntimeController.java index 1eb82378a687497263e23df2993bc4bb1f3ab9eb..b1a8a60acb851d4529cf827af864d9dcee2b7f3c 100644 --- a/src/main/java/org/olat/course/run/CourseRuntimeController.java +++ b/src/main/java/org/olat/course/run/CourseRuntimeController.java @@ -90,6 +90,8 @@ import org.olat.course.area.CourseAreasController; import org.olat.course.assessment.AssessmentChangedEvent; import org.olat.course.assessment.AssessmentModule; import org.olat.course.assessment.ui.mode.AssessmentModeListController; +import org.olat.course.assessment.ui.mode.AssessmentModeSecurityCallback; +import org.olat.course.assessment.ui.mode.AssessmentModeSecurityCallbackFactory; import org.olat.course.assessment.ui.tool.AssessmentToolController; import org.olat.course.certificate.ui.CertificateAndEfficiencyStatementController; import org.olat.course.certificate.ui.CertificatesOptionsController; @@ -126,6 +128,8 @@ import org.olat.modules.assessment.ui.AssessmentToolSecurityCallback; import org.olat.modules.lecture.LectureModule; import org.olat.modules.lecture.LectureService; import org.olat.modules.lecture.ui.LectureRepositoryAdminController; +import org.olat.modules.lecture.ui.LecturesSecurityCallback; +import org.olat.modules.lecture.ui.LecturesSecurityCallbackFactory; import org.olat.modules.lecture.ui.TeacherOverviewController; import org.olat.modules.reminder.ReminderModule; import org.olat.note.NoteController; @@ -271,8 +275,10 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im // group rights UserCourseEnvironmentImpl uce = getUserCourseEnvironment(); if(uce != null) { - uce.setUserRoles(security.isEntryAdmin(), security.isCoach(), security.isParticipant()); - if(security.isReadOnly()) { + uce.setUserRoles(security.isEntryAdmin() || security.isPrincipal(), security.isCoach(), security.isParticipant()); + if(security.isOnlyPrincipal()) { + uce.setCourseReadOnly(Boolean.TRUE); + } else if(security.isReadOnly()) { if(overrideReadOnly) { uce.setCourseReadOnly(Boolean.FALSE); } else { @@ -300,7 +306,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im private boolean hasCourseRight(String right) { Boolean bool = courseRightsCache.get(right); - return bool == null ? false : bool.booleanValue(); + return bool != null && bool.booleanValue(); } private UserCourseEnvironmentImpl getUserCourseEnvironment() { @@ -447,7 +453,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im } private void setCourseClosedMessage(UserCourseEnvironment uce) { - if(uce != null && uce.isCourseReadOnly()) { + if(uce != null && getRepositoryEntry().getRepositoryEntryStatus().isClosed()) { toolbarPanel.setMessage(translate("course.closed")); toolbarPanel.setMessageCssClass("o_warning"); } else { @@ -457,7 +463,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im private void initTools(Dropdown tools, ICourse course, final UserCourseEnvironmentImpl uce) { // 1) administrative tools - if (reSecurity.isEntryAdmin() || reSecurity.isCoach() + if (reSecurity.isEntryAdmin() || reSecurity.isPrincipal() || reSecurity.isCoach() || hasCourseRight(CourseRights.RIGHT_COURSEEDITOR) || hasCourseRight(CourseRights.RIGHT_MEMBERMANAGEMENT) || hasCourseRight(CourseRights.RIGHT_GROUPMANAGEMENT) || hasCourseRight(CourseRights.RIGHT_ARCHIVING) || hasCourseRight(CourseRights.RIGHT_STATISTICS) || hasCourseRight(CourseRights.RIGHT_DB) @@ -474,19 +480,21 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im editLink.setEnabled(!corrupted && !managed); editLink.setVisible(!readOnly); tools.addComponent(editLink); + } + if (uce != null && (reSecurity.isEntryAdmin() || reSecurity.isPrincipal() || hasCourseRight(CourseRights.RIGHT_COURSEEDITOR))) { folderLink = LinkFactory.createToolLink("cfd", translate("command.coursefolder"), this, "o_icon_coursefolder"); folderLink.setElementCssClass("o_sel_course_folder"); tools.addComponent(folderLink); tools.addComponent(new Spacer("")); } - if (reSecurity.isEntryAdmin() || hasCourseRight(CourseRights.RIGHT_GROUPMANAGEMENT) || hasCourseRight(CourseRights.RIGHT_MEMBERMANAGEMENT)) { + if (reSecurity.isEntryAdmin() || reSecurity.isPrincipal() || hasCourseRight(CourseRights.RIGHT_GROUPMANAGEMENT) || hasCourseRight(CourseRights.RIGHT_MEMBERMANAGEMENT)) { membersLink = LinkFactory.createToolLink("unifiedusermngt", translate("command.opensimplegroupmngt"), this, "o_icon_membersmanagement"); membersLink.setElementCssClass("o_sel_course_members"); tools.addComponent(membersLink); } - if (reSecurity.isEntryAdmin() || reSecurity.isCoach() || hasCourseRight(CourseRights.RIGHT_ASSESSMENT)) { + if (reSecurity.isEntryAdmin() || reSecurity.isPrincipal() || reSecurity.isCoach() || hasCourseRight(CourseRights.RIGHT_ASSESSMENT)) { assessmentLink = LinkFactory.createToolLink("assessment", translate("command.openassessment"), this, "o_icon_assessment_tool"); assessmentLink.setElementCssClass("o_sel_course_assessment_tool"); tools.addComponent(assessmentLink); @@ -498,11 +506,11 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im tools.addComponent(new Spacer("")); - if (reSecurity.isEntryAdmin() || hasCourseRight(CourseRights.RIGHT_STATISTICS)) { + if (reSecurity.isEntryAdmin() || reSecurity.isPrincipal() || hasCourseRight(CourseRights.RIGHT_STATISTICS)) { courseStatisticLink = LinkFactory.createToolLink("statistic",translate("command.openstatistic"), this, "o_icon_statistics_tool"); tools.addComponent(courseStatisticLink); } - if (uce != null && (reSecurity.isEntryAdmin() || reSecurity.isCoach() || hasCourseRight(CourseRights.RIGHT_STATISTICS))) { + if (uce != null && (reSecurity.isEntryAdmin() || reSecurity.isPrincipal() || reSecurity.isCoach() || hasCourseRight(CourseRights.RIGHT_STATISTICS))) { final AtomicInteger testNodes = new AtomicInteger(); final AtomicInteger surveyNodes = new AtomicInteger(); new TreeVisitor(new Visitor() { @@ -549,7 +557,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im @Override protected void initSettingsTools(Dropdown settings) { boolean courseAuthorRight = reSecurity.isEntryAdmin() || hasCourseRight(CourseRights.RIGHT_COURSEEDITOR); - if (courseAuthorRight || hasCourseRight(CourseRights.RIGHT_ASSESSMENT_MODE)) { + if (courseAuthorRight || reSecurity.isPrincipal() || hasCourseRight(CourseRights.RIGHT_ASSESSMENT_MODE)) { boolean managed = RepositoryEntryManagedFlag.isManaged(getRepositoryEntry(), RepositoryEntryManagedFlag.editcontent); UserCourseEnvironment uce = getUserCourseEnvironment(); if(uce == null) { @@ -611,7 +619,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im settings.addComponent(reminderLink); } - if(courseAuthorRight && lectureModule.isEnabled()) { + if((courseAuthorRight || reSecurity.isPrincipal()) && lectureModule.isEnabled()) { lecturesAdminLink = LinkFactory.createToolLink("lectures.admin.cmd", translate("command.options.lectures.admin"), this, "o_icon_lecture"); lecturesAdminLink.setElementCssClass("o_sel_course_lectures_admin"); lecturesAdminLink.setVisible(!uce.isCourseReadOnly()); @@ -781,6 +789,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im private void initGeneralTools(ICourse course) { boolean assessmentLock = isAssessmentLock(); + UserCourseEnvironment userCourseEnv = getUserCourseEnvironment(); CourseConfig cc = course.getCourseConfig(); if (!assessmentLock && showInfos) { @@ -790,7 +799,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im boolean calendarIsEnabled = !assessmentLock && !isGuestOnly && calendarModule.isEnabled() && calendarModule.isEnableCourseToolCalendar() && reSecurity.canLaunch(); - if (calendarIsEnabled && getUserCourseEnvironment() != null) { + if (calendarIsEnabled && userCourseEnv != null) { calendarLink = LinkFactory.createToolLink("calendar",translate("command.calendar"), this, "o_icon_calendar"); calendarLink.setPopup(new LinkPopupSettings(950, 750, "cal")); calendarLink.setVisible(cc.isCalendarEnabled()); @@ -819,7 +828,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im //add group chat to toolbox boolean chatIsEnabled = !assessmentLock && !isGuestOnly && imModule.isEnabled() && imModule.isCourseEnabled() && reSecurity.canLaunch(); - if(chatIsEnabled && getUserCourseEnvironment() != null && !getUserCourseEnvironment().isCourseReadOnly()) { + if(chatIsEnabled && userCourseEnv != null && !userCourseEnv.isCourseReadOnly()) { chatLink = LinkFactory.createToolLink("chat",translate("command.coursechat"), this, "o_icon_chat"); chatLink.setVisible(imModule.isCourseEnabled() && cc.isChatEnabled()); toolbarPanel.addTool(chatLink); @@ -1113,7 +1122,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im } entries = removeRepositoryEntry(entries); - if(entries != null && entries.size() > 0) { + if(entries != null && !entries.isEmpty()) { String type = entries.get(0).getOLATResourceable().getResourceableTypeName(); if("Payment".equalsIgnoreCase(type)) { doPostSuccessfullAccess(ureq); @@ -1164,7 +1173,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im } } else if ("assessmentTool".equalsIgnoreCase(type) || "assessmentToolv2".equalsIgnoreCase(type)) { //check the security before, the link is perhaps in the wrong hands - if(reSecurity.isEntryAdmin() || reSecurity.isCoach() || hasCourseRight(CourseRights.RIGHT_ASSESSMENT)) { + if(reSecurity.isEntryAdmin() || reSecurity.isPrincipal() || reSecurity.isCoach() || hasCourseRight(CourseRights.RIGHT_ASSESSMENT)) { try { Activateable2 assessmentCtrl = doAssessmentTool(ureq); if(assessmentCtrl != null) { @@ -1182,7 +1191,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im } } else if ("TestStatistics".equalsIgnoreCase(type) || "SurveyStatistics".equalsIgnoreCase(type)) { //check the security before, the link is perhaps in the wrong hands - if(reSecurity.isEntryAdmin() || reSecurity.isCoach() || hasCourseRight(CourseRights.RIGHT_ASSESSMENT)) { + if(reSecurity.isEntryAdmin() || reSecurity.isPrincipal() || reSecurity.isCoach() || hasCourseRight(CourseRights.RIGHT_ASSESSMENT)) { try { Activateable2 assessmentCtrl = null; if("TestStatistics".equalsIgnoreCase(type)) { @@ -1268,15 +1277,15 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im @Override protected Activateable2 doMembers(UserRequest ureq) { if(delayedClose == Delayed.members || requestForClose(ureq)) { - if (reSecurity.isEntryAdmin() || hasCourseRight(CourseRights.RIGHT_GROUPMANAGEMENT) || hasCourseRight(CourseRights.RIGHT_MEMBERMANAGEMENT)) { + if (reSecurity.isEntryAdmin() || reSecurity.isPrincipal() || hasCourseRight(CourseRights.RIGHT_GROUPMANAGEMENT) || hasCourseRight(CourseRights.RIGHT_MEMBERMANAGEMENT)) { removeCustomCSS(); if(currentToolCtr instanceof MembersManagementMainController) { ((MembersManagementMainController)currentToolCtr).activate(ureq, null, null); } else { WindowControl bwControl = getSubWindowControl("MembersMgmt"); MembersManagementMainController ctrl = new MembersManagementMainController(ureq, addToHistory(ureq, bwControl), toolbarPanel, - getRepositoryEntry(), getUserCourseEnvironment(), reSecurity.isEntryAdmin(), hasCourseRight(CourseRights.RIGHT_GROUPMANAGEMENT), - hasCourseRight(CourseRights.RIGHT_MEMBERMANAGEMENT)); + getRepositoryEntry(), getUserCourseEnvironment(), reSecurity.isEntryAdmin(), reSecurity.isPrincipal(), + hasCourseRight(CourseRights.RIGHT_GROUPMANAGEMENT), hasCourseRight(CourseRights.RIGHT_MEMBERMANAGEMENT)); listenTo(ctrl); membersCtrl = pushController(ureq, translate("command.opensimplegroupmngt"), ctrl); setActiveTool(membersLink); @@ -1303,7 +1312,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im private void doConfirmLeave(UserRequest ureq) { String title = translate("sign.out"); - leaveDialogBox = new ConfirmLeaveController(ureq, getWindowControl(), this.getRepositoryEntry()); + leaveDialogBox = new ConfirmLeaveController(ureq, getWindowControl(), getRepositoryEntry()); listenTo(leaveDialogBox); cmc = new CloseableModalController(getWindowControl(), "close", leaveDialogBox.getInitialComponent(), true, title); listenTo(cmc); @@ -1339,7 +1348,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im private void doLifeCycleChange(UserRequest ureq) { List<Link> breadCrumbs = toolbarPanel.getBreadCrumbs(); BreadCrumb lastCrumb = null; - if (breadCrumbs.size() > 0) { + if (!breadCrumbs.isEmpty()) { lastCrumb = (BreadCrumb) breadCrumbs.get(breadCrumbs.size()-1).getUserObject(); } if (lastCrumb == null || lastCrumb.getController() != lifeCycleChangeCtr) { @@ -1389,10 +1398,13 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im private void doAssessmentMode(UserRequest ureq) { if(delayedClose == Delayed.assessmentMode || requestForClose(ureq)) { - if (reSecurity.isEntryAdmin() || hasCourseRight(CourseRights.RIGHT_COURSEEDITOR) || hasCourseRight(CourseRights.RIGHT_ASSESSMENT_MODE)) { + if (reSecurity.isEntryAdmin() || reSecurity.isPrincipal() || hasCourseRight(CourseRights.RIGHT_COURSEEDITOR) || hasCourseRight(CourseRights.RIGHT_ASSESSMENT_MODE)) { removeCustomCSS(); + + boolean canManage = reSecurity.isEntryAdmin() || hasCourseRight(CourseRights.RIGHT_COURSEEDITOR) || hasCourseRight(CourseRights.RIGHT_ASSESSMENT_MODE); + AssessmentModeSecurityCallback secCallback = AssessmentModeSecurityCallbackFactory.getSecurityCallback(canManage); AssessmentModeListController ctrl = new AssessmentModeListController(ureq, getWindowControl(), - toolbarPanel, getRepositoryEntry()); + toolbarPanel, getRepositoryEntry(), secCallback); assessmentModeCtrl = pushController(ureq, translate("command.assessment.mode"), ctrl); setActiveTool(assessmentModeLink); currentToolCtr = assessmentModeCtrl; @@ -1437,12 +1449,14 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im private LectureRepositoryAdminController doLecturesAdmin(UserRequest ureq) { if(delayedClose == Delayed.lecturesAdmin || requestForClose(ureq)) { - if (reSecurity.isEntryAdmin() || hasCourseRight(CourseRights.RIGHT_COURSEEDITOR)) { + if (reSecurity.isEntryAdmin() || reSecurity.isPrincipal() || hasCourseRight(CourseRights.RIGHT_COURSEEDITOR)) { removeCustomCSS(); OLATResourceable ores = OresHelper.createOLATResourceableType("LecturesAdmin"); WindowControl swControl = addToHistory(ureq, ores, null); - LectureRepositoryAdminController ctrl = new LectureRepositoryAdminController(ureq, swControl, toolbarPanel, getRepositoryEntry()); + LecturesSecurityCallback secCallback = LecturesSecurityCallbackFactory + .getSecurityCallback(reSecurity.isEntryAdmin() || hasCourseRight(CourseRights.RIGHT_COURSEEDITOR)); + LectureRepositoryAdminController ctrl = new LectureRepositoryAdminController(ureq, swControl, toolbarPanel, getRepositoryEntry(), secCallback); listenTo(ctrl); lecturesAdminCtrl = pushController(ureq, translate("command.options.lectures.admin"), ctrl); setActiveTool(lecturesAdminLink); @@ -1550,7 +1564,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im private void doCourseStatistics(UserRequest ureq) { if(delayedClose == Delayed.courseStatistics || requestForClose(ureq)) { - if (reSecurity.isEntryAdmin() || hasCourseRight(CourseRights.RIGHT_STATISTICS)) { + if (reSecurity.isEntryAdmin() || reSecurity.isPrincipal()|| hasCourseRight(CourseRights.RIGHT_STATISTICS)) { removeCustomCSS(); ICourse course = CourseFactory.loadCourse(getRepositoryEntry()); StatisticMainController ctrl = new StatisticMainController(ureq, getWindowControl(), course); @@ -1598,7 +1612,7 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im OLATResourceable ores = OresHelper.createOLATResourceableType(typeName); ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores)); WindowControl swControl = addToHistory(ureq, ores, null); - if (reSecurity.isEntryAdmin() || reSecurity.isCoach() || hasCourseRight(CourseRights.RIGHT_STATISTICS)) { + if (reSecurity.isEntryAdmin() || reSecurity.isPrincipal() || reSecurity.isCoach() || hasCourseRight(CourseRights.RIGHT_STATISTICS)) { removeCustomCSS(); UserCourseEnvironmentImpl uce = getUserCourseEnvironment(); StatisticCourseNodesController ctrl = new StatisticCourseNodesController(ureq, swControl, toolbarPanel, reSecurity, uce, type); @@ -1617,17 +1631,18 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im ThreadLocalUserActivityLogger.addLoggingResourceInfo(LoggingResourceable.wrapBusinessPath(ores)); WindowControl swControl = addToHistory(ureq, ores, null); - boolean admin = reSecurity.isEntryAdmin() || hasCourseRight(CourseRights.RIGHT_ASSESSMENT); + boolean admin = reSecurity.isEntryAdmin() || reSecurity.isPrincipal() || hasCourseRight(CourseRights.RIGHT_ASSESSMENT); boolean nonMembers = reSecurity.isEntryAdmin(); List<BusinessGroup> coachedGroups = null; + UserCourseEnvironment userCourseEnv = getUserCourseEnvironment(); if(reSecurity.isGroupCoach()) { - coachedGroups = getUserCourseEnvironment().getCoachedGroups(); + coachedGroups = userCourseEnv.getCoachedGroups(); } AssessmentToolSecurityCallback secCallBack = new AssessmentToolSecurityCallback(admin, nonMembers, reSecurity.isCourseCoach(), reSecurity.isGroupCoach(), reSecurity.isCurriculumCoach(), coachedGroups); removeCustomCSS(); - AssessmentToolController ctrl = new AssessmentToolController(ureq, swControl, toolbarPanel, getRepositoryEntry(), getUserCourseEnvironment(), secCallBack); + AssessmentToolController ctrl = new AssessmentToolController(ureq, swControl, toolbarPanel, getRepositoryEntry(), userCourseEnv, secCallBack); ctrl.activate(ureq, null, null); listenTo(ctrl); assessmentToolCtr = pushController(ureq, translate("command.openassessment"), ctrl); @@ -1795,30 +1810,27 @@ public class CourseRuntimeController extends RepositoryEntryRuntimeController im List<ContextEntry> entries = BusinessControlFactory.getInstance().createCEListFromResourceType(allowGlossaryEditing ? "true" : "false"); dts.activate(ureq, dt, entries); } else { - ControllerCreator ctrlCreator = new ControllerCreator() { - public Controller createController(UserRequest lureq, WindowControl lwControl) { - GlossaryMainController glossaryController = CourseGlossaryFactory.createCourseGlossaryMainRunController(lwControl, lureq, cc, allowGlossaryEditing); - listenTo(glossaryController); - if (glossaryController == null) { - // happens in the unlikely event of a user who is in a course and - // now - // tries to access the glossary - String text = translate("error.noglossary"); - return MessageUIFactory.createInfoMessage(lureq, lwControl, null, text); - } else { - // use a one-column main layout - LayoutMain3ColsController layoutCtr = new LayoutMain3ColsController(lureq, lwControl, glossaryController); - // dispose glossary on layout dispose - layoutCtr.addDisposableChildController(glossaryController); - return layoutCtr; - } + ControllerCreator ctrlCreator = (lureq, lwControl) -> { + GlossaryMainController glossaryController = CourseGlossaryFactory.createCourseGlossaryMainRunController(lwControl, lureq, cc, allowGlossaryEditing); + listenTo(glossaryController); + if (glossaryController == null) { + // happens in the unlikely event of a user who is in a course and + // now + // tries to access the glossary + String text = translate("error.noglossary"); + return MessageUIFactory.createInfoMessage(lureq, lwControl, null, text); + } else { + // use a one-column main layout + LayoutMain3ColsController layoutCtr = new LayoutMain3ColsController(lureq, lwControl, glossaryController); + // dispose glossary on layout dispose + layoutCtr.addDisposableChildController(glossaryController); + return layoutCtr; } }; ControllerCreator layoutCtrlr = BaseFullWebappPopupLayoutFactory.createAuthMinimalPopupLayout(ureq, ctrlCreator); // open in new browser window openInNewBrowserWindow(ureq, layoutCtrlr); - return;// immediate return after opening new browser window! } } diff --git a/src/main/java/org/olat/course/run/RunMainController.java b/src/main/java/org/olat/course/run/RunMainController.java index 40b43c56026cb78ff5f68fcd65d6ee13f333bb0a..19fb3aadf27a30c88b5de0bc06b0844fd7717690 100644 --- a/src/main/java/org/olat/course/run/RunMainController.java +++ b/src/main/java/org/olat/course/run/RunMainController.java @@ -94,7 +94,6 @@ import org.olat.group.BusinessGroup; import org.olat.group.ui.edit.BusinessGroupModifiedEvent; import org.olat.modules.cp.TreeNodeEvent; import org.olat.repository.RepositoryEntry; -import org.olat.repository.RepositoryManager; import org.olat.repository.RepositoryService; import org.olat.repository.model.RepositoryEntrySecurity; import org.olat.util.logging.activity.LoggingResourceable; @@ -137,9 +136,7 @@ public class RunMainController extends MainLayoutBasicController implements Gene private String courseTitle; private Link nextLink, previousLink; private GlossaryMarkupItemController glossaryMarkerCtr; - - @Autowired - private RepositoryManager repositoryManager; + @Autowired private RepositoryService repositoryService; @@ -206,7 +203,7 @@ public class RunMainController extends MainLayoutBasicController implements Gene currentCourseNode = updateTreeAndContent(ureq, currentCourseNode, null); - if (courseRepositoryEntry != null && repositoryManager.createRepositoryEntryStatus(courseRepositoryEntry.getStatusCode()).isClosed()) { + if (courseRepositoryEntry != null && courseRepositoryEntry.getRepositoryEntryStatus().isClosed()) { wControl.setWarning(translate("course.closed")); } @@ -319,8 +316,8 @@ public class RunMainController extends MainLayoutBasicController implements Gene return new UserCourseEnvironmentImpl(ureq.getUserSession().getIdentityEnvironment(), course.getCourseEnvironment(), getWindowControl(), coachedGroups, participatedGroups, waitingLists, - reSecurity.isCoach(), reSecurity.isEntryAdmin(), reSecurity.isParticipant(), - reSecurity.isReadOnly()); + reSecurity.isCoach(), reSecurity.isEntryAdmin() || reSecurity.isPrincipal(), reSecurity.isParticipant(), + reSecurity.isReadOnly() || reSecurity.isOnlyPrincipal()); } /** diff --git a/src/main/java/org/olat/course/run/calendar/CourseCalendarController.java b/src/main/java/org/olat/course/run/calendar/CourseCalendarController.java index 8318e999ffdff091ebcebfa4e3c826a6a26c209a..3dc4ccb89f6e3795f46a3c3abc51a3a9afad5a18 100644 --- a/src/main/java/org/olat/course/run/calendar/CourseCalendarController.java +++ b/src/main/java/org/olat/course/run/calendar/CourseCalendarController.java @@ -88,7 +88,7 @@ public class CourseCalendarController extends BasicController { ICourse course = CourseFactory.loadCourse(userCourseEnv.getCourseEnvironment().getCourseGroupManager().getCourseEntry()); KalendarRenderWrapper courseKalendarWrapper = calendarManager.getCourseCalendar(course); CourseGroupManager cgm = course.getCourseEnvironment().getCourseGroupManager(); - boolean isPrivileged = isPrivileged(cgm); + boolean isPrivileged = isPrivileged(); if (isPrivileged) { courseKalendarWrapper.setAccess(KalendarRenderWrapper.ACCESS_READ_WRITE); courseKalendarWrapper.setPrivateEventsVisible(true); @@ -121,9 +121,8 @@ public class CourseCalendarController extends BasicController { return calendars; } - private boolean isPrivileged(CourseGroupManager cgm) { - return !userCourseEnv.isCourseReadOnly() - && (userCourseEnv.isAdmin() || cgm.isIdentityCourseAdministrator(getIdentity())); + private boolean isPrivileged() { + return !userCourseEnv.isCourseReadOnly() && userCourseEnv.isAdmin(); } private void addCalendars(List<BusinessGroup> groups, boolean isOwner, LinkProvider linkProvider, diff --git a/src/main/java/org/olat/course/run/userview/UserCourseEnvironment.java b/src/main/java/org/olat/course/run/userview/UserCourseEnvironment.java index 8e20e55f14a85b26a6d702bb4f47e9ab26f8c659..4d05f0d429e26580cc86fca9d375e1d5a74478d8 100644 --- a/src/main/java/org/olat/course/run/userview/UserCourseEnvironment.java +++ b/src/main/java/org/olat/course/run/userview/UserCourseEnvironment.java @@ -67,8 +67,8 @@ public interface UserCourseEnvironment { public ScoreAccounting getScoreAccounting(); /** - * Is admin of the course, as administrator in OpenOLAT, resource manager - * or owner of the course. + * Is admin of a course an administrator, learn resource manager or principal + * of an organization linked to the course or an owner of the course. * @return */ public boolean isAdmin(); diff --git a/src/main/java/org/olat/group/ui/edit/MemberListController.java b/src/main/java/org/olat/group/ui/edit/MemberListController.java index 472a6ed9423f6df9ae0fbc81e6e071d03fbfaa9e..3edde1ce6e7c9efd81ca48bd970e496cd3b566f8 100644 --- a/src/main/java/org/olat/group/ui/edit/MemberListController.java +++ b/src/main/java/org/olat/group/ui/edit/MemberListController.java @@ -24,10 +24,12 @@ import org.olat.core.gui.components.stack.TooledStackedPanel; import org.olat.core.gui.control.WindowControl; import org.olat.group.BusinessGroup; import org.olat.group.ui.main.AbstractMemberListController; +import org.olat.group.ui.main.MemberListSecurityCallbackFactory; import org.olat.group.ui.main.MemberRow; import org.olat.group.ui.main.SearchMembersParams; /** + * The list of members specific to the business groups. * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ @@ -37,7 +39,7 @@ public class MemberListController extends AbstractMemberListController { public MemberListController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel, BusinessGroup group, SearchMembersParams searchParams) { - super(ureq, wControl, group, "all_member_list", false, stackPanel); + super(ureq, wControl, group, "all_member_list", MemberListSecurityCallbackFactory.adminRights(), stackPanel); this.searchParams = searchParams; } diff --git a/src/main/java/org/olat/group/ui/main/AbstractMemberListController.java b/src/main/java/org/olat/group/ui/main/AbstractMemberListController.java index 41c022a784e36392cf0b37f219cd7bfa68b5a111..7b96bb073f8955c3709cf20b681443d55d760f96 100644 --- a/src/main/java/org/olat/group/ui/main/AbstractMemberListController.java +++ b/src/main/java/org/olat/group/ui/main/AbstractMemberListController.java @@ -151,9 +151,9 @@ public abstract class AbstractMemberListController extends FormBasicController i private final boolean isAdministrativeUser; private final boolean chatEnabled; - private final boolean readOnly; private boolean overrideManaged = false; private final boolean globallyManaged; + private final MemberListSecurityCallback secCallback; @Autowired private MemberViewQueries memberQueries; @@ -183,28 +183,28 @@ public abstract class AbstractMemberListController extends FormBasicController i private UserSessionManager sessionManager; public AbstractMemberListController(UserRequest ureq, WindowControl wControl, RepositoryEntry repoEntry, - String page,boolean readOnly, TooledStackedPanel stackPanel) { - this(ureq, wControl, repoEntry, null, page, readOnly, stackPanel, Util.createPackageTranslator(AbstractMemberListController.class, ureq.getLocale())); + String page, MemberListSecurityCallback secCallback, TooledStackedPanel stackPanel) { + this(ureq, wControl, repoEntry, null, page, secCallback, stackPanel, Util.createPackageTranslator(AbstractMemberListController.class, ureq.getLocale())); } public AbstractMemberListController(UserRequest ureq, WindowControl wControl, BusinessGroup group, - String page, boolean readOnly, TooledStackedPanel stackPanel) { - this(ureq, wControl, null, group, page, readOnly, stackPanel, Util.createPackageTranslator(AbstractMemberListController.class, ureq.getLocale())); + String page, MemberListSecurityCallback secCallback, TooledStackedPanel stackPanel) { + this(ureq, wControl, null, group, page, secCallback, stackPanel, Util.createPackageTranslator(AbstractMemberListController.class, ureq.getLocale())); } protected AbstractMemberListController(UserRequest ureq, WindowControl wControl, RepositoryEntry repoEntry, BusinessGroup group, - String page, boolean readOnly, TooledStackedPanel stackPanel, Translator translator) { + String page, MemberListSecurityCallback secCallback, TooledStackedPanel stackPanel, Translator translator) { super(ureq, wControl, page, Util.createPackageTranslator(UserPropertyHandler.class, ureq.getLocale(), translator)); this.businessGroup = group; this.repoEntry = repoEntry; this.toolbarPanel = stackPanel; - this.readOnly = readOnly; + this.secCallback = secCallback; globallyManaged = calcGloballyManaged(); Roles roles = ureq.getUserSession().getRoles(); - chatEnabled = imModule.isEnabled() && imModule.isPrivateEnabled() && !readOnly; + chatEnabled = imModule.isEnabled() && imModule.isPrivateEnabled() && !secCallback.isReadonly(); isAdministrativeUser = securityModule.isUserAllowedAdminProps(roles); isLastVisitVisible = securityModule.isUserLastVisitVisible(roles); userPropertyHandlers = userManager.getUserPropertyHandlersFor(USER_PROPS_ID, isAdministrativeUser); @@ -215,8 +215,8 @@ public abstract class AbstractMemberListController extends FormBasicController i public void overrideManaged(UserRequest ureq, boolean override) { if(isAllowedToOverrideManaged(ureq)) { overrideManaged = override; - editButton.setVisible((!globallyManaged || overrideManaged) && !readOnly); - removeButton.setVisible((!globallyManaged || overrideManaged) && !readOnly); + editButton.setVisible((!globallyManaged || overrideManaged) && !secCallback.isReadonly()); + removeButton.setVisible((!globallyManaged || overrideManaged) && !secCallback.isReadonly()); flc.setDirty(true); } } @@ -253,10 +253,10 @@ public abstract class AbstractMemberListController extends FormBasicController i } editButton = uifactory.addFormLink("edit.members", formLayout, Link.BUTTON); - editButton.setVisible((!globallyManaged || overrideManaged) && !readOnly); + editButton.setVisible((!globallyManaged || overrideManaged) && !secCallback.isReadonly()); mailButton = uifactory.addFormLink("table.header.mail", formLayout, Link.BUTTON); removeButton = uifactory.addFormLink("table.header.remove", formLayout, Link.BUTTON); - removeButton.setVisible((!globallyManaged || overrideManaged) && !readOnly); + removeButton.setVisible((!globallyManaged || overrideManaged) && !secCallback.isReadonly()); } private boolean calcGloballyManaged() { @@ -288,7 +288,7 @@ public abstract class AbstractMemberListController extends FormBasicController i private SortKey initColumns(FlexiTableColumnModel columnsModel) { SortKey defaultSortKey = null; - String editAction = readOnly ? null : TABLE_ACTION_EDIT; + String editAction = secCallback.isReadonly() ? null : TABLE_ACTION_EDIT; if(chatEnabled) { DefaultFlexiColumnModel chatCol = new DefaultFlexiColumnModel(Cols.online.i18n(), Cols.online.ordinal()); @@ -691,7 +691,7 @@ public abstract class AbstractMemberListController extends FormBasicController i Map<BusinessGroup, List<Identity>> graduatesMap = new HashMap<>(); for(MemberRow member:members) { List<BusinessGroupShort> groups = member.getGroups(); - if(groups != null && groups.size() > 0) { + if(groups != null && !groups.isEmpty()) { Identity memberIdentity = securityManager.loadIdentityByKey(member.getIdentityKey()); for(BusinessGroupShort group:groups) { if(businessGroupService.hasRoles(memberIdentity, group, GroupRoles.waiting.name())) { @@ -881,15 +881,15 @@ public abstract class AbstractMemberListController extends FormBasicController i links.add("-"); - if(row.getMembership().isBusinessGroupWaiting() && !readOnly) { + if(row.getMembership().isBusinessGroupWaiting() && !secCallback.isReadonly()) { addLink("table.header.graduate", TABLE_ACTION_GRADUATE, "o_icon o_icon_graduate", links); } - if(!readOnly) { + if(!secCallback.isReadonly()) { addLink("edit.member", TABLE_ACTION_EDIT, "o_icon o_icon_edit", links); } - if(!globallyManaged || overrideManaged) { + if((!globallyManaged || overrideManaged) && secCallback.canRemoveMembers()) { addLink("table.header.remove", TABLE_ACTION_REMOVE, "o_icon o_icon_remove", links); } cleanSeparator(links); diff --git a/src/main/java/org/olat/group/ui/main/MemberListSecurityCallback.java b/src/main/java/org/olat/group/ui/main/MemberListSecurityCallback.java new file mode 100644 index 0000000000000000000000000000000000000000..2a24d2676ce6e9aac54aeafd6e6083d587354e76 --- /dev/null +++ b/src/main/java/org/olat/group/ui/main/MemberListSecurityCallback.java @@ -0,0 +1,34 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.group.ui.main; + +/** + * + * Initial date: 20 juil. 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public interface MemberListSecurityCallback { + + public boolean isReadonly(); + + public boolean canRemoveMembers(); + +} diff --git a/src/main/java/org/olat/group/ui/main/MemberListSecurityCallbackFactory.java b/src/main/java/org/olat/group/ui/main/MemberListSecurityCallbackFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..127ea10393a8b5e67e4454b3fde64a22243830b0 --- /dev/null +++ b/src/main/java/org/olat/group/ui/main/MemberListSecurityCallbackFactory.java @@ -0,0 +1,59 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.group.ui.main; + +/** + * + * Initial date: 20 juil. 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class MemberListSecurityCallbackFactory { + + public static MemberListSecurityCallback adminRights() { + return new MemberListSecurityCallbackImpl(false, true); + } + + public static MemberListSecurityCallback getSecurityCallback(boolean readOnly, boolean canRemoveMembers) { + return new MemberListSecurityCallbackImpl(readOnly, canRemoveMembers); + } + + private static class MemberListSecurityCallbackImpl implements MemberListSecurityCallback { + + private final boolean readOnly; + private final boolean canRemoveMembers; + + public MemberListSecurityCallbackImpl(boolean readOnly, boolean canRemoveMembers) { + this.readOnly = readOnly; + this.canRemoveMembers = canRemoveMembers; + } + + @Override + public boolean isReadonly() { + return readOnly; + } + + @Override + public boolean canRemoveMembers() { + return canRemoveMembers; + } + } + +} diff --git a/src/main/java/org/olat/modules/coach/ui/UserDetailsController.java b/src/main/java/org/olat/modules/coach/ui/UserDetailsController.java index 40d42a2a71a8ccaaeb893dd145d6a89b29d09834..e85982c001bcbe480543a5695b32ca36a14f9b2c 100644 --- a/src/main/java/org/olat/modules/coach/ui/UserDetailsController.java +++ b/src/main/java/org/olat/modules/coach/ui/UserDetailsController.java @@ -159,8 +159,8 @@ public class UserDetailsController extends BasicController implements Activateab RepositoryEntrySecurity reSecurity = repositoryManager.isAllowed(ureq, entry); return new UserCourseEnvironmentImpl(ureq.getUserSession().getIdentityEnvironment(), null, getWindowControl(), null, null, null, - reSecurity.isCoach(), reSecurity.isEntryAdmin(), reSecurity.isParticipant(), - reSecurity.isReadOnly()); + reSecurity.isCoach(), reSecurity.isEntryAdmin() || reSecurity.isPrincipal(), reSecurity.isParticipant(), + reSecurity.isReadOnly() || reSecurity.isOnlyPrincipal()); } @Override diff --git a/src/main/java/org/olat/modules/lecture/ui/AppealListRepositoryController.java b/src/main/java/org/olat/modules/lecture/ui/AppealListRepositoryController.java index ae32c92df8760f33cbc63c3ee11703a4ce482204..7b1ebd81c46319e0ec202b7b21a133c703007bac 100644 --- a/src/main/java/org/olat/modules/lecture/ui/AppealListRepositoryController.java +++ b/src/main/java/org/olat/modules/lecture/ui/AppealListRepositoryController.java @@ -77,6 +77,7 @@ public class AppealListRepositoryController extends FormBasicController { private final boolean absenceDefaultAuthorized; private final RepositoryEntry entry; + private final LecturesSecurityCallback secCallback; private final boolean isAdministrativeUser; private List<UserPropertyHandler> userPropertyHandlers; @@ -89,9 +90,11 @@ public class AppealListRepositoryController extends FormBasicController { @Autowired private BaseSecurityModule securityModule; - public AppealListRepositoryController(UserRequest ureq, WindowControl wControl, RepositoryEntry entry) { + public AppealListRepositoryController(UserRequest ureq, WindowControl wControl, RepositoryEntry entry, + LecturesSecurityCallback secCallback) { super(ureq, wControl, "appeal_table"); this.entry = entry; + this.secCallback = secCallback; setTranslator(userManager.getPropertyHandlerTranslator(getTranslator())); Roles roles = ureq.getUserSession().getRoles(); @@ -140,9 +143,12 @@ public class AppealListRepositoryController extends FormBasicController { new LectureBlockRollCallStatusCellRenderer(authorizedAbsenceEnabled, absenceDefaultAuthorized, getTranslator()))); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(AppealCols.appealStatus, new LectureBlockAppealStatusCellRenderer(getTranslator()))); - DefaultFlexiColumnModel editColumn = new DefaultFlexiColumnModel("table.header.edit", translate("table.header.edit"), "edit"); - editColumn.setExportable(false); - columnsModel.addFlexiColumnModel(editColumn); + + if(secCallback.canApproveAppeal()) { + DefaultFlexiColumnModel editColumn = new DefaultFlexiColumnModel("table.header.edit", translate("table.header.edit"), "edit"); + editColumn.setExportable(false); + columnsModel.addFlexiColumnModel(editColumn); + } tableModel = new AppealListRepositoryDataModel(columnsModel,authorizedAbsenceEnabled, absenceDefaultAuthorized, getLocale()); tableEl = uifactory.addTableElement(getWindowControl(), "table", tableModel, 20, false, getTranslator(), formLayout); @@ -225,7 +231,7 @@ public class AppealListRepositoryController extends FormBasicController { } private void doEditAppeal(UserRequest ureq, LectureBlockRollCall rollCall) { - if(appealCtrl != null) return; + if(appealCtrl != null || !secCallback.canApproveAppeal()) return; appealCtrl = new EditAppealController(ureq, getWindowControl(), rollCall); listenTo(appealCtrl); diff --git a/src/main/java/org/olat/modules/lecture/ui/EditLectureBlockController.java b/src/main/java/org/olat/modules/lecture/ui/EditLectureBlockController.java index 9797e25918714ec46e409c0d9b66c6a3aabf9703..0aa76fb495266476cd40967d0429b375d0262414 100644 --- a/src/main/java/org/olat/modules/lecture/ui/EditLectureBlockController.java +++ b/src/main/java/org/olat/modules/lecture/ui/EditLectureBlockController.java @@ -93,6 +93,7 @@ public class EditLectureBlockController extends FormBasicController { private TextElement startHourEl, startMinuteEl; private MultipleSelectionElement groupsEl, teacherEl, compulsoryEl; + private final boolean readOnly; private RepositoryEntry entry; private LectureBlock lectureBlock; @@ -116,12 +117,14 @@ public class EditLectureBlockController extends FormBasicController { private BusinessGroupService businessGroupService; public EditLectureBlockController(UserRequest ureq, WindowControl wControl, RepositoryEntry entry) { - this(ureq, wControl, entry, null); + this(ureq, wControl, entry, null, false); } - public EditLectureBlockController(UserRequest ureq, WindowControl wControl, RepositoryEntry entry, LectureBlock lectureBlock) { + public EditLectureBlockController(UserRequest ureq, WindowControl wControl, + RepositoryEntry entry, LectureBlock lectureBlock, boolean readOnly) { super(ureq, wControl); this.entry = entry; + this.readOnly = readOnly; this.lectureBlock = lectureBlock; locations = getLocations(ureq); lectureManagementManaged = RepositoryEntryManagedFlag.isManaged(entry, RepositoryEntryManagedFlag.lecturemanagement); @@ -144,7 +147,7 @@ public class EditLectureBlockController extends FormBasicController { String title = lectureBlock == null ? null : lectureBlock.getTitle(); titleEl = uifactory.addTextElement("title", "lecture.title", 128, title, formLayout); titleEl.setElementCssClass("o_sel_repo_lecture_title"); - titleEl.setEnabled(!lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.title)); + titleEl.setEnabled(!readOnly && !lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.title)); titleEl.setMandatory(true); plannedLecturesEl = uifactory.addDropdownSingleselect("planned.lectures", "planned.lectures", formLayout, @@ -164,12 +167,12 @@ public class EditLectureBlockController extends FormBasicController { && lectureBlock.getRollCallStatus() != LectureRollCallStatus.autoclosed)) && !lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.plannedLectures); - plannedLecturesEl.setEnabled(plannedLecturesEditable); + plannedLecturesEl.setEnabled(!readOnly && plannedLecturesEditable); String[] onValues = new String[]{ "" }; boolean compulsory = lectureBlock == null ? true : lectureBlock.isCompulsory(); compulsoryEl = uifactory.addCheckboxesVertical("compulsory", "lecture.compulsory", formLayout, onKeys, onValues, 1); - compulsoryEl.setEnabled(!lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.compulsory)); + compulsoryEl.setEnabled(!readOnly && !lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.compulsory)); compulsoryEl.addActionListener(FormEvent.ONCHANGE); if(compulsory) { compulsoryEl.select(onKeys[0], true); @@ -188,7 +191,7 @@ public class EditLectureBlockController extends FormBasicController { teacherEl = uifactory.addCheckboxesVertical("teacher", "lecture.teacher", formLayout, teacherKeys, teacherValues, 2); teacherEl.setElementCssClass("o_sel_repo_lecture_teachers"); teacherEl.setMandatory(true); - teacherEl.setEnabled(!lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.teachers)); + teacherEl.setEnabled(!readOnly && !lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.teachers)); boolean found = false; if(teachers != null && teachers.size() > 0) { @@ -221,7 +224,7 @@ public class EditLectureBlockController extends FormBasicController { groupValues[i] = groupBox.get(i).getName(); } groupsEl = uifactory.addCheckboxesVertical("lecture.groups", "lecture.groups", formLayout, groupKeys, groupValues, 2); - groupsEl.setEnabled(!lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.groups)); + groupsEl.setEnabled(!readOnly && !lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.groups)); groupsEl.setMandatory(true); if(lectureBlock != null) { List<Group> selectedGroups = lectureService.getLectureBlockToGroups(lectureBlock); @@ -247,22 +250,22 @@ public class EditLectureBlockController extends FormBasicController { String description = lectureBlock == null ? "" : lectureBlock.getDescription(); descriptionEl = uifactory.addTextAreaElement("lecture.descr", 4, 72, description, formLayout); descriptionEl.setElementCssClass("o_sel_repo_lecture_description"); - descriptionEl.setEnabled(!lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.description)); + descriptionEl.setEnabled(!readOnly && !lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.description)); String preparation = lectureBlock == null ? "" : lectureBlock.getPreparation(); preparationEl = uifactory.addTextAreaElement("lecture.preparation", 4, 72, preparation, formLayout); preparationEl.setElementCssClass("o_sel_repo_lecture_preparation"); - preparationEl.setEnabled(!lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.preparation)); + preparationEl.setEnabled(!readOnly && !lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.preparation)); String location = lectureBlock == null ? "" : lectureBlock.getLocation(); locationEl = uifactory.addTextElementWithAutoCompleter("location", "lecture.location", 128, location, formLayout); locationEl.setElementCssClass("o_sel_repo_lecture_location"); - locationEl.setEnabled(!lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.location)); + locationEl.setEnabled(!readOnly && !lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.location)); locationEl.setListProvider(new LocationListProvider(), ureq.getUserSession()); locationEl.setMinLength(1); Date startDate = lectureBlock == null ? null : lectureBlock.getStartDate(); dateEl = uifactory.addDateChooser("lecture.date", startDate, formLayout); dateEl.setElementCssClass("o_sel_repo_lecture_date"); - dateEl.setEnabled(!lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.dates)); + dateEl.setEnabled(!readOnly && !lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.dates)); dateEl.setDomReplacementWrapperRequired(false); dateEl.setMandatory(true); @@ -272,22 +275,22 @@ public class EditLectureBlockController extends FormBasicController { formLayout.add(dateCont); startHourEl = uifactory.addTextElement("lecture.start.hour", null, 2, "", dateCont); - startHourEl.setEnabled(!lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.dates)); + startHourEl.setEnabled(!readOnly && !lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.dates)); startHourEl.setDomReplacementWrapperRequired(false); startHourEl.setDisplaySize(2); startHourEl.setMandatory(true); startMinuteEl = uifactory.addTextElement("lecture.start.minute", null, 2, "", dateCont); - startMinuteEl.setEnabled(!lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.dates)); + startMinuteEl.setEnabled(!readOnly && !lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.dates)); startMinuteEl.setDomReplacementWrapperRequired(false); startMinuteEl.setDisplaySize(2); endHourEl = uifactory.addTextElement("lecture.end.hour", null, 2, "", dateCont); - endHourEl.setEnabled(!lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.dates)); + endHourEl.setEnabled(!readOnly && !lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.dates)); endHourEl.setDomReplacementWrapperRequired(false); endHourEl.setDisplaySize(2); endHourEl.setMandatory(true); endMinuteEl = uifactory.addTextElement("lecture.end.minute", null, 2, "", dateCont); - endMinuteEl.setEnabled(!lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.dates)); + endMinuteEl.setEnabled(!readOnly && !lectureManagementManaged && !LectureBlockManagedFlag.isManaged(lectureBlock, LectureBlockManagedFlag.dates)); endMinuteEl.setDomReplacementWrapperRequired(false); endMinuteEl.setDisplaySize(2); @@ -312,7 +315,9 @@ public class EditLectureBlockController extends FormBasicController { FormLayoutContainer buttonsCont = FormLayoutContainer.createButtonLayout("buttons", getTranslator()); formLayout.add(buttonsCont); uifactory.addFormCancelButton("cancel", buttonsCont, ureq, getWindowControl()); - uifactory.addFormSubmitButton("save", buttonsCont); + if(!readOnly) { + uifactory.addFormSubmitButton("save", buttonsCont); + } } private String formatMinute(int minute) { diff --git a/src/main/java/org/olat/modules/lecture/ui/LectureListRepositoryController.java b/src/main/java/org/olat/modules/lecture/ui/LectureListRepositoryController.java index cc87b8ff5ffe8af9efbd1444f80667dffb49daa4..c0a9b291235ff3bfe1279bb0851ecf76f9c271a5 100644 --- a/src/main/java/org/olat/modules/lecture/ui/LectureListRepositoryController.java +++ b/src/main/java/org/olat/modules/lecture/ui/LectureListRepositoryController.java @@ -91,9 +91,9 @@ public class LectureListRepositoryController extends FormBasicController { private CloseableCalloutWindowController toolsCalloutCtrl; private int counter = 0; - private RepositoryEntry entry; - + private final RepositoryEntry entry; private final boolean lectureManagementManaged; + private final LecturesSecurityCallback secCallback; @Autowired private UserManager userManager; @@ -102,9 +102,10 @@ public class LectureListRepositoryController extends FormBasicController { @Autowired private LectureService lectureService; - public LectureListRepositoryController(UserRequest ureq, WindowControl wControl, RepositoryEntry entry) { + public LectureListRepositoryController(UserRequest ureq, WindowControl wControl, RepositoryEntry entry, LecturesSecurityCallback secCallback) { super(ureq, wControl, "admin_repository_lectures"); this.entry = entry; + this.secCallback = secCallback; lectureManagementManaged = RepositoryEntryManagedFlag.isManaged(entry, RepositoryEntryManagedFlag.lecturemanagement); initForm(ureq); @@ -113,7 +114,7 @@ public class LectureListRepositoryController extends FormBasicController { @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { - if(!lectureManagementManaged) { + if(!lectureManagementManaged && secCallback.canNewLectureBlock()) { addLectureButton = uifactory.addFormLink("add.lecture", formLayout, Link.BUTTON); addLectureButton.setIconLeftCSS("o_icon o_icon_add"); addLectureButton.setElementCssClass("o_sel_repo_add_lecture"); @@ -129,21 +130,17 @@ public class LectureListRepositoryController extends FormBasicController { columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BlockCols.startTime, new TimeFlexiCellRenderer(getLocale()))); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BlockCols.endTime, new TimeFlexiCellRenderer(getLocale()))); columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel(BlockCols.teachers)); - - if(lectureManagementManaged) { - columnsModel.addFlexiColumnModel(new DefaultFlexiColumnModel("details", translate("details"), "edit"));//edit check it - } else { - DefaultFlexiColumnModel editColumn = new DefaultFlexiColumnModel("table.header.edit", -1, "edit", - new StaticFlexiCellRenderer("", "edit", "o_icon o_icon-lg o_icon_edit", translate("edit"), null)); - editColumn.setExportable(false); - editColumn.setAlwaysVisible(true); - columnsModel.addFlexiColumnModel(editColumn); + + DefaultFlexiColumnModel editColumn = new DefaultFlexiColumnModel("table.header.edit", -1, "edit", + new StaticFlexiCellRenderer("", "edit", "o_icon o_icon-lg o_icon_edit", translate("edit"), null)); + editColumn.setExportable(false); + editColumn.setAlwaysVisible(true); + columnsModel.addFlexiColumnModel(editColumn); - DefaultFlexiColumnModel toolsColumn = new DefaultFlexiColumnModel(BlockCols.tools); - toolsColumn.setExportable(false); - toolsColumn.setAlwaysVisible(true); - columnsModel.addFlexiColumnModel(toolsColumn); - } + DefaultFlexiColumnModel toolsColumn = new DefaultFlexiColumnModel(BlockCols.tools); + toolsColumn.setExportable(false); + toolsColumn.setAlwaysVisible(true); + columnsModel.addFlexiColumnModel(toolsColumn); tableModel = new LectureListRepositoryDataModel(columnsModel, getLocale()); tableEl = uifactory.addTableElement(getWindowControl(), "table", tableModel, 20, false, getTranslator(), formLayout); @@ -182,8 +179,10 @@ public class LectureListRepositoryController extends FormBasicController { } tableModel.setObjects(rows); tableEl.reset(true, true, true); - - deleteLecturesButton.setVisible(!rows.isEmpty()); + + if(deleteLecturesButton != null) { + deleteLecturesButton.setVisible(!rows.isEmpty()); + } } @Override @@ -279,7 +278,8 @@ public class LectureListRepositoryController extends FormBasicController { if(editLectureCtrl != null) return; LectureBlock block = lectureService.getLectureBlock(row); - editLectureCtrl = new EditLectureBlockController(ureq, getWindowControl(), entry, block); + boolean readOnly = lectureManagementManaged || !secCallback.canNewLectureBlock(); + editLectureCtrl = new EditLectureBlockController(ureq, getWindowControl(), entry, block, readOnly); listenTo(editLectureCtrl); cmc = new CloseableModalController(getWindowControl(), "close", editLectureCtrl.getInitialComponent(), true, translate("add.lecture")); @@ -288,7 +288,7 @@ public class LectureListRepositoryController extends FormBasicController { } private void doAddLectureBlock(UserRequest ureq) { - if(editLectureCtrl != null) return; + if(editLectureCtrl != null || !secCallback.canNewLectureBlock()) return; editLectureCtrl = new EditLectureBlockController(ureq, getWindowControl(), entry); listenTo(editLectureCtrl); @@ -392,11 +392,13 @@ public class LectureListRepositoryController extends FormBasicController { VelocityContainer mainVC = createVelocityContainer("lectures_tools"); - copyLink = LinkFactory.createLink("copy", "copy", getTranslator(), mainVC, this, Link.LINK); - copyLink.setIconLeftCSS("o_icon o_icon-fw o_icon_copy"); - if(!LectureBlockManagedFlag.isManaged(row.getLectureBlock(), LectureBlockManagedFlag.delete)) { - deleteLink = LinkFactory.createLink("delete", "delete", getTranslator(), mainVC, this, Link.LINK); - deleteLink.setIconLeftCSS("o_icon o_icon-fw o_icon_delete_item"); + if(secCallback.canNewLectureBlock()) { + copyLink = LinkFactory.createLink("copy", "copy", getTranslator(), mainVC, this, Link.LINK); + copyLink.setIconLeftCSS("o_icon o_icon-fw o_icon_copy"); + if(!LectureBlockManagedFlag.isManaged(row.getLectureBlock(), LectureBlockManagedFlag.delete)) { + deleteLink = LinkFactory.createLink("delete", "delete", getTranslator(), mainVC, this, Link.LINK); + deleteLink.setIconLeftCSS("o_icon o_icon-fw o_icon_delete_item"); + } } logLink = LinkFactory.createLink("log", "log", getTranslator(), mainVC, this, Link.LINK); logLink.setIconLeftCSS("o_icon o_icon-fw o_icon_log"); diff --git a/src/main/java/org/olat/modules/lecture/ui/LectureRepositoryAdminController.java b/src/main/java/org/olat/modules/lecture/ui/LectureRepositoryAdminController.java index 3a95ee690a5a9de91bdb393795a4b79d64f2c6b0..0ff1265d8cfc8d7e657a7d828d939334bdad2fbb 100644 --- a/src/main/java/org/olat/modules/lecture/ui/LectureRepositoryAdminController.java +++ b/src/main/java/org/olat/modules/lecture/ui/LectureRepositoryAdminController.java @@ -59,12 +59,16 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class LectureRepositoryAdminController extends BasicController implements TooledController, Activateable2 { - private Link archiveLink, logLink; + private Link logLink; + private Link archiveLink; + private Link settingsLink; + private final Link appealsLink; + private final Link lecturesLink; + private final Link participantsLink; private final VelocityContainer mainVC; private final SegmentViewComponent segmentView; private final TooledStackedPanel stackPanel; - private final Link lecturesLink, appealsLink, settingsLink, participantsLink; - + private AppealListRepositoryController appealsCtrl; private LectureListRepositoryController lecturesCtrl; private final LectureRepositorySettingsController settingsCtrl; @@ -74,6 +78,7 @@ public class LectureRepositoryAdminController extends BasicController implements private boolean configurationChanges = false; private final boolean isAdministrativeUser; private final boolean authorizedAbsenceEnabled; + private final LecturesSecurityCallback secCallback; @Autowired private LectureModule lectureModule; @@ -83,10 +88,11 @@ public class LectureRepositoryAdminController extends BasicController implements private BaseSecurityModule securityModule; public LectureRepositoryAdminController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel, - RepositoryEntry entry) { + RepositoryEntry entry, LecturesSecurityCallback secCallback) { super(ureq, wControl); this.entry = entry; this.stackPanel = stackPanel; + this.secCallback = secCallback; Roles roles = ureq.getUserSession().getRoles(); isAdministrativeUser = securityModule.isUserAllowedAdminProps(roles); @@ -100,12 +106,10 @@ public class LectureRepositoryAdminController extends BasicController implements lecturesLink = LinkFactory.createLink("repo.lectures.block", mainVC, this); participantsLink = LinkFactory.createLink("repo.participants", mainVC, this); appealsLink = LinkFactory.createLink("repo.lectures.appeals", mainVC, this); - settingsLink = LinkFactory.createLink("repo.settings", mainVC, this); - + WindowControl swControl = addToHistory(ureq, OresHelper.createOLATResourceableType("Settings"), null); settingsCtrl = new LectureRepositorySettingsController(ureq, swControl, entry); listenTo(settingsCtrl); - if(settingsCtrl.isLectureEnabled()) { segmentView.addSegment(lecturesLink, true); segmentView.addSegment(participantsLink, false); @@ -116,7 +120,11 @@ public class LectureRepositoryAdminController extends BasicController implements } else { doOpenSettings(ureq); } - segmentView.addSegment(settingsLink, !settingsCtrl.isLectureEnabled()); + + if(secCallback.canEditConfiguration()) { + settingsLink = LinkFactory.createLink("repo.settings", mainVC, this); + segmentView.addSegment(settingsLink, !settingsCtrl.isLectureEnabled()); + } putInitialPanel(mainVC); } @@ -158,7 +166,7 @@ public class LectureRepositoryAdminController extends BasicController implements } else if("Participants".equalsIgnoreCase(name)) { doOpenParticipants(ureq); segmentView.select(participantsLink); - } else if("Settings".equalsIgnoreCase(name)) { + } else if("Settings".equalsIgnoreCase(name) && settingsLink != null) { doOpenSettings(ureq); segmentView.select(settingsLink); } else if("Appeals".equalsIgnoreCase(name)) { @@ -227,7 +235,7 @@ public class LectureRepositoryAdminController extends BasicController implements if(lecturesCtrl == null) { OLATResourceable ores = OresHelper.createOLATResourceableType("LectureBlocks"); WindowControl swControl = addToHistory(ureq, ores, null); - lecturesCtrl = new LectureListRepositoryController(ureq, swControl, entry); + lecturesCtrl = new LectureListRepositoryController(ureq, swControl, entry, secCallback); listenTo(lecturesCtrl); } else { addToHistory(ureq, lecturesCtrl); @@ -244,7 +252,7 @@ public class LectureRepositoryAdminController extends BasicController implements if(participantsCtrl == null) { OLATResourceable ores = OresHelper.createOLATResourceableType("Participants"); WindowControl swControl = addToHistory(ureq, ores, null); - participantsCtrl = new ParticipantListRepositoryController(ureq, swControl, entry, false, true); + participantsCtrl = new ParticipantListRepositoryController(ureq, swControl, entry, secCallback, false); listenTo(participantsCtrl); } else { addToHistory(ureq, participantsCtrl); @@ -256,7 +264,7 @@ public class LectureRepositoryAdminController extends BasicController implements if(appealsCtrl == null) { OLATResourceable ores = OresHelper.createOLATResourceableType("Appeals"); WindowControl swControl = addToHistory(ureq, ores, null); - appealsCtrl = new AppealListRepositoryController(ureq, swControl, entry); + appealsCtrl = new AppealListRepositoryController(ureq, swControl, entry, secCallback); listenTo(appealsCtrl); } else { addToHistory(ureq, appealsCtrl); diff --git a/src/main/java/org/olat/modules/lecture/ui/LecturesSecurityCallback.java b/src/main/java/org/olat/modules/lecture/ui/LecturesSecurityCallback.java new file mode 100644 index 0000000000000000000000000000000000000000..902ec3c5d04166986f4b5db1f27da4ef19bdb131 --- /dev/null +++ b/src/main/java/org/olat/modules/lecture/ui/LecturesSecurityCallback.java @@ -0,0 +1,40 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.lecture.ui; + +/** + * Very simple security callback for the principals + * + * + * Initial date: 20 juil. 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public interface LecturesSecurityCallback { + + public boolean canNewLectureBlock(); + + public boolean canChangeRates(); + + public boolean canApproveAppeal(); + + public boolean canEditConfiguration(); + +} diff --git a/src/main/java/org/olat/modules/lecture/ui/LecturesSecurityCallbackFactory.java b/src/main/java/org/olat/modules/lecture/ui/LecturesSecurityCallbackFactory.java new file mode 100644 index 0000000000000000000000000000000000000000..e008072d85065816b6e0f46ec9eafe47fba08fe3 --- /dev/null +++ b/src/main/java/org/olat/modules/lecture/ui/LecturesSecurityCallbackFactory.java @@ -0,0 +1,62 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.modules.lecture.ui; + +/** + * + * Initial date: 20 juil. 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class LecturesSecurityCallbackFactory { + + public static LecturesSecurityCallback getSecurityCallback(boolean canModify) { + return new LecturesSecurityCallbackImpl(canModify); + } + + private static class LecturesSecurityCallbackImpl implements LecturesSecurityCallback { + + private final boolean canModify; + + public LecturesSecurityCallbackImpl(boolean canModify) { + this.canModify = canModify; + } + + @Override + public boolean canNewLectureBlock() { + return canModify; + } + + @Override + public boolean canChangeRates() { + return canModify; + } + + @Override + public boolean canApproveAppeal() { + return canModify; + } + + @Override + public boolean canEditConfiguration() { + return canModify; + } + } +} diff --git a/src/main/java/org/olat/modules/lecture/ui/ParticipantListRepositoryController.java b/src/main/java/org/olat/modules/lecture/ui/ParticipantListRepositoryController.java index 0000b5986f706885526177e79222cc0b6b0a97fb..9e1701b13016b711ddbf7c3052bbc69fdf77bcc9 100644 --- a/src/main/java/org/olat/modules/lecture/ui/ParticipantListRepositoryController.java +++ b/src/main/java/org/olat/modules/lecture/ui/ParticipantListRepositoryController.java @@ -94,9 +94,9 @@ public class ParticipantListRepositoryController extends FormBasicController { private final boolean rollCallEnabled; private final boolean authorizedAbsenceEnabled; - private final boolean admin; private final boolean printView; private final RepositoryEntry entry; + private final LecturesSecurityCallback secCallback; private RepositoryEntryLectureConfiguration lectureConfig; @Autowired @@ -111,13 +111,13 @@ public class ParticipantListRepositoryController extends FormBasicController { private BaseSecurity securityManager; public ParticipantListRepositoryController(UserRequest ureq, WindowControl wControl, - RepositoryEntry entry, boolean printView, boolean admin) { + RepositoryEntry entry, LecturesSecurityCallback secCallback, boolean printView) { super(ureq, wControl, "participant_list_overview"); this.entry = entry; setTranslator(userManager.getPropertyHandlerTranslator(getTranslator())); - this.admin = admin; this.printView = printView; + this.secCallback = secCallback; Roles roles = ureq.getUserSession().getRoles(); isAdministrativeUser = securityModule.isUserAllowedAdminProps(roles); @@ -200,7 +200,7 @@ public class ParticipantListRepositoryController extends FormBasicController { infoCol.setExportable(false); columnsModel.addFlexiColumnModel(infoCol); - if(!printView) { + if(!printView && secCallback.canChangeRates()) { DefaultFlexiColumnModel editColumn = new DefaultFlexiColumnModel("table.header.edit", -1, "edit", new StaticFlexiCellRenderer("", "edit", "o_icon o_icon-lg o_icon_edit", translate("edit"), null)); editColumn.setExportable(false); @@ -217,15 +217,10 @@ public class ParticipantListRepositoryController extends FormBasicController { } private void loadModel() { - List<Identity> participants; - if(admin) { - participants = lectureService.getParticipants(entry); - } else { - participants = lectureService.getParticipants(entry, getIdentity()); - } - + List<Identity> participants = lectureService.getParticipants(entry); List<LectureBlockStatistics> statistics = lectureService.getParticipantsLecturesStatistics(entry); - Map<Long, LectureBlockStatistics> identityToStatisticsMap = statistics.stream().collect(Collectors.toMap(s -> s.getIdentityKey(), s -> s)); + Map<Long, LectureBlockStatistics> identityToStatisticsMap = statistics.stream() + .collect(Collectors.toMap(LectureBlockStatistics::getIdentityKey, s -> s)); List<ParticipantRow> rows = new ArrayList<>(participants.size()); for(Identity participant:participants) { @@ -304,14 +299,11 @@ public class ParticipantListRepositoryController extends FormBasicController { } private void doPrint(UserRequest ureq) { - ControllerCreator printControllerCreator = new ControllerCreator() { - @Override - public Controller createController(UserRequest lureq, WindowControl lwControl) { - lwControl.getWindowBackOffice().getChiefController().addBodyCssClass("o_lectures_print"); - Controller printCtrl = new ParticipantListRepositoryController(lureq, lwControl, entry, true, admin); - listenTo(printCtrl); - return printCtrl; - } + ControllerCreator printControllerCreator = (lureq, lwControl) -> { + lwControl.getWindowBackOffice().getChiefController().addBodyCssClass("o_lectures_print"); + Controller printCtrl = new ParticipantListRepositoryController(lureq, lwControl, entry, secCallback, true); + listenTo(printCtrl); + return printCtrl; }; ControllerCreator layoutCtrlr = BaseFullWebappPopupLayoutFactory.createPrintPopupLayout(printControllerCreator); openInNewBrowserWindow(ureq, layoutCtrlr); diff --git a/src/main/java/org/olat/modules/lecture/ui/_content/admin_repository_lectures.html b/src/main/java/org/olat/modules/lecture/ui/_content/admin_repository_lectures.html index 0d70ba3886d58e745302263ebd464df68206cc91..c3fb1d715d81cafbc91370804401ce9125c164fb 100644 --- a/src/main/java/org/olat/modules/lecture/ui/_content/admin_repository_lectures.html +++ b/src/main/java/org/olat/modules/lecture/ui/_content/admin_repository_lectures.html @@ -1,10 +1,12 @@ <div class="o_sel_repo_lectures_list"> +#if($r.available("add.lecture")) <div class="o_button_group o_button_group_right"> #if($r.available("add.lecture")) $r.render("add.lecture") #end $r.contextHelpWithWrapper("Lectures and absences") </div> +#end $r.render("table") #if($r.available("delete")) <div class="o_button_group"> diff --git a/src/main/java/org/olat/repository/RepositoryManager.java b/src/main/java/org/olat/repository/RepositoryManager.java index c2332be2d41714f6277493b1c6a12291c108bd4d..e09a76f9503d2048a87d1af015b1e9b79eb1df7d 100644 --- a/src/main/java/org/olat/repository/RepositoryManager.java +++ b/src/main/java/org/olat/repository/RepositoryManager.java @@ -575,6 +575,7 @@ public class RepositoryManager { boolean isAuthor = false; boolean isEntryAdmin = false; + boolean isPrincipal = false; boolean isAdministrator = false; boolean isLearnRessourceManager = false; @@ -638,6 +639,9 @@ public class RepositoryManager { case learnresourcemanager: isLearnRessourceManager = true; break; + case principal: + isPrincipal = true; + break; default: break; } } @@ -649,6 +653,8 @@ public class RepositoryManager { if(isOwner || isAdministrator || isLearnRessourceManager) { canLaunch = true; isEntryAdmin = true; + } else if(isPrincipal) { + canLaunch = true; } if (isAuthor && re.getAccess() >= RepositoryEntry.ACC_OWNERS_AUTHORS) { // allow for authors if access granted at least for authors @@ -670,7 +676,7 @@ public class RepositoryManager { isCourseParticipant, isCourseCoach, isGroupParticipant, isGroupCoach, isGroupWaiting, isCurriculumParticipant, isCurriculumCoach, - isAuthor, canLaunch, readOnly); + isAuthor, isPrincipal, canLaunch, readOnly); } public RepositoryEntry setAccess(final RepositoryEntry re, int access, boolean membersOnly) { diff --git a/src/main/java/org/olat/repository/manager/RepositoryEntryAuthorQueries.java b/src/main/java/org/olat/repository/manager/RepositoryEntryAuthorQueries.java index 25c08c170754e975ff79c756b0149e1f8c831fa3..8961dc3afb16875dcba9c5e0d3297a03aca0b23f 100644 --- a/src/main/java/org/olat/repository/manager/RepositoryEntryAuthorQueries.java +++ b/src/main/java/org/olat/repository/manager/RepositoryEntryAuthorQueries.java @@ -340,6 +340,10 @@ public class RepositoryEntryAuthorQueries { } return false; } + if(roles.isPrincipal()) {//TODO roles repo + sb.append(" v.access>=").append(RepositoryEntry.ACC_OWNERS); + return false; + } sb.append(" (v.access>=").append(RepositoryEntry.ACC_USERS); if(roles.isAuthor()) { diff --git a/src/main/java/org/olat/repository/model/RepositoryEntrySecurity.java b/src/main/java/org/olat/repository/model/RepositoryEntrySecurity.java index 3800e01284b97352f6bfa2b9994c6e7517235254..68f9bb262a0f73651fe430259a044b11aac2fbd2 100644 --- a/src/main/java/org/olat/repository/model/RepositoryEntrySecurity.java +++ b/src/main/java/org/olat/repository/model/RepositoryEntrySecurity.java @@ -32,6 +32,7 @@ public class RepositoryEntrySecurity { private final boolean entryAdmin; private final boolean readOnly; private final boolean author; + private final boolean principal; private final boolean courseParticipant; private final boolean courseCoach; @@ -46,12 +47,13 @@ public class RepositoryEntrySecurity { boolean courseParticipant, boolean courseCoach, boolean groupParticipant, boolean groupCoach, boolean groupWaiting, boolean curriculumParticipant, boolean curriculumCoach, - boolean author, + boolean author, boolean principal, boolean canLaunch, boolean readOnly) { this.owner = owner; this.canLaunch = canLaunch; this.entryAdmin = entryAdmin; this.author = author; + this.principal = principal; this.courseParticipant = courseParticipant; this.courseCoach = courseCoach; @@ -129,7 +131,27 @@ public class RepositoryEntrySecurity { return owner || courseParticipant || courseCoach || groupParticipant || groupCoach || curriculumParticipant || curriculumCoach; } + /** + * @return true if the user has the role author in an organization + * linked by the repository entry + */ public boolean isAuthor() { return author; } + + /** + * @return true if the user has the role principal + */ + public boolean isPrincipal() { + return principal; + } + + /** + * @return true if the user has the role principal but + * is not a member or an administrator of the repository + * entry. + */ + public boolean isOnlyPrincipal() { + return principal && !isMember() && !isEntryAdmin(); + } } diff --git a/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java b/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java index 752a5328a70f61a7f88d9d6bfdaf7e469bf88407..0a096dc2a309f24e3b277cd7c8ccfce62ec8e6c6 100644 --- a/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java +++ b/src/main/java/org/olat/repository/ui/RepositoryEntryRuntimeController.java @@ -770,7 +770,7 @@ public class RepositoryEntryRuntimeController extends MainLayoutBasicController if(!reSecurity.isEntryAdmin()) return null; WindowControl bwControl = getSubWindowControl("MembersMgmt"); - RepositoryMembersController ctrl = new RepositoryMembersController(ureq, addToHistory(ureq, bwControl), toolbarPanel ,re); + RepositoryMembersController ctrl = new RepositoryMembersController(ureq, addToHistory(ureq, bwControl), toolbarPanel, re); listenTo(ctrl); membersEditController = pushController(ureq, translate("details.members"), ctrl); currentToolCtr = membersEditController; @@ -790,7 +790,7 @@ public class RepositoryEntryRuntimeController extends MainLayoutBasicController } private void doRun(UserRequest ureq, RepositoryEntrySecurity security) { - if(security.isEntryAdmin()) { + if(security.isEntryAdmin() || security.isPrincipal()) { launchContent(ureq, security); } else { // guest are allowed to see resource with BARG @@ -803,7 +803,7 @@ public class RepositoryEntryRuntimeController extends MainLayoutBasicController } else if (re != null && !re.getRepositoryEntryStatus().isUnpublished() && !re.getRepositoryEntryStatus().isClosed() - && acResult.getAvailableMethods().size() > 0) { + && !acResult.getAvailableMethods().isEmpty()) { //try auto booking ACResultAndSecurity autoResult = tryAutoBooking(ureq, acResult, security); acResult = autoResult.getAcResult(); diff --git a/src/main/java/org/olat/repository/ui/author/RepositoryMembersController.java b/src/main/java/org/olat/repository/ui/author/RepositoryMembersController.java index 7da44088c15fdf928e4c6f74a45bbd3a308a7ec5..8b7be9bf8b24010be58c9aaa36bd6c6c948bd390 100644 --- a/src/main/java/org/olat/repository/ui/author/RepositoryMembersController.java +++ b/src/main/java/org/olat/repository/ui/author/RepositoryMembersController.java @@ -48,6 +48,7 @@ import org.olat.course.member.wizard.ImportMember_1b_ChooseMemberStep; import org.olat.group.BusinessGroupService; import org.olat.group.model.BusinessGroupMembershipChange; import org.olat.group.ui.main.AbstractMemberListController; +import org.olat.group.ui.main.MemberListSecurityCallbackFactory; import org.olat.group.ui.main.MemberPermissionChangeEvent; import org.olat.group.ui.main.MemberRow; import org.olat.group.ui.main.SearchMembersParams; @@ -61,6 +62,8 @@ import org.olat.repository.model.RepositoryEntryPermissionChangeEvent; import org.springframework.beans.factory.annotation.Autowired; /** + * The members list specific to the repository entries (except courses which + * have a specialized one). * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * @@ -79,7 +82,7 @@ public class RepositoryMembersController extends AbstractMemberListController { private BusinessGroupService businessGroupService; public RepositoryMembersController(UserRequest ureq, WindowControl wControl, TooledStackedPanel stackPanel, RepositoryEntry repoEntry) { - super(ureq, wControl, repoEntry, null, "all_member_list", false, stackPanel, + super(ureq, wControl, repoEntry, null, "all_member_list", MemberListSecurityCallbackFactory.adminRights(), stackPanel, Util.createPackageTranslator(RepositoryService.class, ureq.getLocale(), Util.createPackageTranslator(AbstractMemberListController.class, ureq.getLocale())));