Skip to content

Commit 29afd94

Browse files
authored
Merge pull request #22 from mendrika261/sprint15
sprint15: resolve session bugs
2 parents f848ba6 + 6704100 commit 29afd94

11 files changed

Lines changed: 214 additions & 61 deletions

File tree

.framework/dev_files/etu2024/framework/core/ModelView.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import etu2024.framework.utility.Conf;
44
import etu2024.framework.utility.User;
55

6+
import java.util.ArrayList;
67
import java.util.HashMap;
8+
import java.util.List;
79

810

911
// This class is used to store the view and the data to be sent to the view
@@ -13,6 +15,8 @@ public class ModelView {
1315
HashMap<String, Object> session = new HashMap<>();
1416
boolean isJson = false;
1517
boolean isRedirect = false;
18+
boolean invalidateSession = false; // Remove all session items if true
19+
List<String> removeSessions = new ArrayList<>(); // Remove specific session items
1620

1721
// Constructor
1822
public ModelView() {}
@@ -105,7 +109,7 @@ public void addSessionItem(String key, Object value) {
105109
}
106110

107111
public void removeSessionItem(String key) {
108-
getSession().put(key, null);
112+
getRemoveSessions().add(key);
109113
}
110114

111115
public boolean isJson() {
@@ -123,4 +127,20 @@ public boolean isRedirect() {
123127
public void setRedirect(boolean isRedirect) {
124128
this.isRedirect = isRedirect;
125129
}
130+
131+
public List<String> getRemoveSessions() {
132+
return removeSessions;
133+
}
134+
135+
public void setRemoveSessions(List<String> removeSessions) {
136+
this.removeSessions = removeSessions;
137+
}
138+
139+
public boolean isInvalidateSession() {
140+
return invalidateSession;
141+
}
142+
143+
public void setInvalidateSession(boolean invalidateSession) {
144+
this.invalidateSession = invalidateSession;
145+
}
126146
}

.framework/dev_files/etu2024/framework/servlet/FrontServlet.java

Lines changed: 75 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.lang.reflect.InvocationTargetException;
2222
import java.lang.reflect.Method;
2323
import java.lang.reflect.Parameter;
24+
import java.net.http.HttpRequest;
2425
import java.util.*;
2526

2627
@MultipartConfig
@@ -73,38 +74,46 @@ private void processRequest(HttpServletRequest request, HttpServletResponse resp
7374
Method method = Tools.getMethodByName(objectClass, mapping.getMethod());
7475
List<Object> parameters = setMethodParameters(method, request);
7576

76-
// 3. Call the method from the mapping
77-
// Check if client authorized to call the method (if the method is annotated with @Auth)
78-
HttpSession session = request.getSession();
79-
Object profile = session.getAttribute(Conf.getAuthSessionName());
80-
if(!User.isAuthorized(method, profile)) {
81-
response.sendRedirect(getServletContext().getContextPath()+Conf.getAuthRedirections().get("AUTH_REDIRECT_LOGOUT"));
82-
return;
83-
}
8477

8578
// @RestAPI function directly return JSON
8679
if(method.isAnnotationPresent(RestAPI.class)) {
8780
printJson(method.invoke(object, parameters.toArray()), response);
8881
return;
8982
}
9083

84+
// Check if the method return a ModelView object
9185
Object functionReturn = method.invoke(object, parameters.toArray());
9286
if(functionReturn == null || functionReturn.getClass() != ModelView.class) {
9387
response.sendError(500, "FRAMEWORK ERROR - The method \"" + method.getName() + "\" in the class \"" +
9488
objectClass.getName() + "\" make errors, make sure it return a ModelView object or use @RestAPI" +
9589
" to return all types");
9690
return;
9791
}
92+
93+
// Get the modelView object
9894
ModelView modelView = (ModelView) functionReturn;
9995

100-
// 4. Set the session attributes if the method or the class is annotated with @Session
101-
if(method.isAnnotationPresent(Session.class) || objectClass.isAnnotationPresent(Session.class) ||
102-
method.isAnnotationPresent(Auth.class)) {
103-
setSessions(modelView, session);
104-
} else {
105-
if(!modelView.getSession().isEmpty())
106-
throw new RuntimeException("FRAMEWORK ERROR - You can't set or get session attributes if the method" +
107-
" or the class is not annotated with @Session");
96+
97+
// Handle session
98+
HttpSession session = request.getSession();
99+
100+
// Set the session attributes from modelView to the request
101+
setSessionsToTheRequest(modelView, session);
102+
103+
// Set the session attributes from request to controller if the method or the class is annotated with @Session
104+
if(method.isAnnotationPresent(Session.class) || objectClass.isAnnotationPresent(Session.class)) {
105+
setSessionsFromRequest(object, request, response);
106+
}
107+
108+
// Re-get the modelView with the new session attributes
109+
modelView = (ModelView) method.invoke(object, parameters.toArray());
110+
111+
112+
// Check if client authorized to call the method (if the method is annotated with @Auth)
113+
Object profile = session.getAttribute(Conf.getAuthSessionName());
114+
if(!User.isAuthorized(method, profile)) {
115+
response.sendRedirect(getServletContext().getContextPath()+Conf.getAuthRedirections().get("AUTH_REDIRECT_LOGOUT"));
116+
return;
108117
}
109118

110119
// Set the attributes from the modelView to the request
@@ -195,21 +204,60 @@ public Object constructObject(Class<?> objectClass) throws NoSuchMethodException
195204
return objectClass.getDeclaredConstructor().newInstance();
196205
}
197206

198-
// Set session attributes from the modelView to the session and vice versa
199-
public void setSessions(ModelView modelView, HttpSession session) {
200-
// Set session attributes from the modelView to the request
201-
for (String key : modelView.getSession().keySet()) {
202-
// If the value is null, remove the attribute from the session
203-
if (modelView.getSession().get(key) == null)
207+
// Set session attributes from the modelView to the session
208+
public void setSessionsToTheRequest(ModelView modelView, HttpSession session) {
209+
/* Removing session */
210+
// If invalidateSession is true, invalidate the session
211+
if(modelView.isInvalidateSession()) {
212+
// Iterate over the session attributes and remove them
213+
Enumeration<String> sessionAttributes = session.getAttributeNames();
214+
while(sessionAttributes.hasMoreElements())
215+
session.removeAttribute(sessionAttributes.nextElement());
216+
}
217+
// If the removeSession list is not empty
218+
if(!modelView.getRemoveSessions().isEmpty()) {
219+
for(String key : modelView.getRemoveSessions())
204220
session.removeAttribute(key);
205-
else
206-
session.setAttribute(key, modelView.getSession().get(key));
207221
}
208222

209-
// Set session from the request to the modelView
210-
for (Enumeration<String> e = session.getAttributeNames(); e.hasMoreElements(); ) {
223+
/* Adding session */
224+
for (String key : modelView.getSession().keySet()) {
225+
session.setAttribute(key, modelView.getSession().get(key));
226+
}
227+
}
228+
229+
// Set session from the request to the modelView
230+
public void setSessionsFromRequest(Object object, HttpServletRequest request, HttpServletResponse response) throws IOException {
231+
// Check if the session is new or invalidated
232+
HttpSession existingSession = request.getSession(false);
233+
if(existingSession == null || existingSession.isNew()) {
234+
return;
235+
}
236+
237+
// Get the field where sessions attributes are stored
238+
Field field;
239+
try {
240+
field = object.getClass().getDeclaredField("sessions");
241+
} catch (NoSuchFieldException ex) {
242+
throw new RuntimeException("FRAMEWORK ERROR - You can't get session attributes if the class `"+ object.getClass().getName()
243+
+"` does not have " +
244+
"`Hashmap<String, Object> sessions` as a field");
245+
}
246+
// Set the field accessible
247+
field.setAccessible(true);
248+
249+
// Iterate over the session attributes and add them to the HashMap
250+
HashMap<String, Object> sessions = new HashMap<>();
251+
for (Enumeration<String> e = request.getSession().getAttributeNames(); e.hasMoreElements(); ) {
211252
String key = e.nextElement();
212-
modelView.addSessionItem(key, session.getAttribute(key));
253+
sessions.put(key, request.getSession().getAttribute(key));
254+
}
255+
256+
try {
257+
field.set(object, sessions);
258+
} catch (IllegalAccessException ex) {
259+
throw new RuntimeException("FRAMEWORK ERROR - Cannot have access to the field sessions, be sure that the " +
260+
"field is public");
213261
}
214262
}
215263

.framework/framework.jar

1.35 KB
Binary file not shown.

LICENSE

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,4 +198,4 @@
198198
distributed under the License is distributed on an "AS IS" BASIS,
199199
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200200
See the License for the specific language governing permissions and
201-
limitations under the License.
201+
limitations under the License.

framework/src/main/java/etu2024/framework/core/ModelView.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import etu2024.framework.utility.Conf;
44
import etu2024.framework.utility.User;
55

6+
import java.util.ArrayList;
67
import java.util.HashMap;
8+
import java.util.List;
79

810

911
// This class is used to store the view and the data to be sent to the view
@@ -13,6 +15,8 @@ public class ModelView {
1315
HashMap<String, Object> session = new HashMap<>();
1416
boolean isJson = false;
1517
boolean isRedirect = false;
18+
boolean invalidateSession = false; // Remove all session items if true
19+
List<String> removeSessions = new ArrayList<>(); // Remove specific session items
1620

1721
// Constructor
1822
public ModelView() {}
@@ -105,7 +109,7 @@ public void addSessionItem(String key, Object value) {
105109
}
106110

107111
public void removeSessionItem(String key) {
108-
getSession().put(key, null);
112+
getRemoveSessions().add(key);
109113
}
110114

111115
public boolean isJson() {
@@ -123,4 +127,20 @@ public boolean isRedirect() {
123127
public void setRedirect(boolean isRedirect) {
124128
this.isRedirect = isRedirect;
125129
}
130+
131+
public List<String> getRemoveSessions() {
132+
return removeSessions;
133+
}
134+
135+
public void setRemoveSessions(List<String> removeSessions) {
136+
this.removeSessions = removeSessions;
137+
}
138+
139+
public boolean isInvalidateSession() {
140+
return invalidateSession;
141+
}
142+
143+
public void setInvalidateSession(boolean invalidateSession) {
144+
this.invalidateSession = invalidateSession;
145+
}
126146
}

framework/src/main/java/etu2024/framework/servlet/FrontServlet.java

Lines changed: 75 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import java.lang.reflect.InvocationTargetException;
2222
import java.lang.reflect.Method;
2323
import java.lang.reflect.Parameter;
24+
import java.net.http.HttpRequest;
2425
import java.util.*;
2526

2627
@MultipartConfig
@@ -73,38 +74,46 @@ private void processRequest(HttpServletRequest request, HttpServletResponse resp
7374
Method method = Tools.getMethodByName(objectClass, mapping.getMethod());
7475
List<Object> parameters = setMethodParameters(method, request);
7576

76-
// 3. Call the method from the mapping
77-
// Check if client authorized to call the method (if the method is annotated with @Auth)
78-
HttpSession session = request.getSession();
79-
Object profile = session.getAttribute(Conf.getAuthSessionName());
80-
if(!User.isAuthorized(method, profile)) {
81-
response.sendRedirect(getServletContext().getContextPath()+Conf.getAuthRedirections().get("AUTH_REDIRECT_LOGOUT"));
82-
return;
83-
}
8477

8578
// @RestAPI function directly return JSON
8679
if(method.isAnnotationPresent(RestAPI.class)) {
8780
printJson(method.invoke(object, parameters.toArray()), response);
8881
return;
8982
}
9083

84+
// Check if the method return a ModelView object
9185
Object functionReturn = method.invoke(object, parameters.toArray());
9286
if(functionReturn == null || functionReturn.getClass() != ModelView.class) {
9387
response.sendError(500, "FRAMEWORK ERROR - The method \"" + method.getName() + "\" in the class \"" +
9488
objectClass.getName() + "\" make errors, make sure it return a ModelView object or use @RestAPI" +
9589
" to return all types");
9690
return;
9791
}
92+
93+
// Get the modelView object
9894
ModelView modelView = (ModelView) functionReturn;
9995

100-
// 4. Set the session attributes if the method or the class is annotated with @Session
101-
if(method.isAnnotationPresent(Session.class) || objectClass.isAnnotationPresent(Session.class) ||
102-
method.isAnnotationPresent(Auth.class)) {
103-
setSessions(modelView, session);
104-
} else {
105-
if(!modelView.getSession().isEmpty())
106-
throw new RuntimeException("FRAMEWORK ERROR - You can't set or get session attributes if the method" +
107-
" or the class is not annotated with @Session");
96+
97+
// Handle session
98+
HttpSession session = request.getSession();
99+
100+
// Set the session attributes from modelView to the request
101+
setSessionsToTheRequest(modelView, session);
102+
103+
// Set the session attributes from request to controller if the method or the class is annotated with @Session
104+
if(method.isAnnotationPresent(Session.class) || objectClass.isAnnotationPresent(Session.class)) {
105+
setSessionsFromRequest(object, request, response);
106+
}
107+
108+
// Re-get the modelView with the new session attributes
109+
modelView = (ModelView) method.invoke(object, parameters.toArray());
110+
111+
112+
// Check if client authorized to call the method (if the method is annotated with @Auth)
113+
Object profile = session.getAttribute(Conf.getAuthSessionName());
114+
if(!User.isAuthorized(method, profile)) {
115+
response.sendRedirect(getServletContext().getContextPath()+Conf.getAuthRedirections().get("AUTH_REDIRECT_LOGOUT"));
116+
return;
108117
}
109118

110119
// Set the attributes from the modelView to the request
@@ -195,21 +204,60 @@ public Object constructObject(Class<?> objectClass) throws NoSuchMethodException
195204
return objectClass.getDeclaredConstructor().newInstance();
196205
}
197206

198-
// Set session attributes from the modelView to the session and vice versa
199-
public void setSessions(ModelView modelView, HttpSession session) {
200-
// Set session attributes from the modelView to the request
201-
for (String key : modelView.getSession().keySet()) {
202-
// If the value is null, remove the attribute from the session
203-
if (modelView.getSession().get(key) == null)
207+
// Set session attributes from the modelView to the session
208+
public void setSessionsToTheRequest(ModelView modelView, HttpSession session) {
209+
/* Removing session */
210+
// If invalidateSession is true, invalidate the session
211+
if(modelView.isInvalidateSession()) {
212+
// Iterate over the session attributes and remove them
213+
Enumeration<String> sessionAttributes = session.getAttributeNames();
214+
while(sessionAttributes.hasMoreElements())
215+
session.removeAttribute(sessionAttributes.nextElement());
216+
}
217+
// If the removeSession list is not empty
218+
if(!modelView.getRemoveSessions().isEmpty()) {
219+
for(String key : modelView.getRemoveSessions())
204220
session.removeAttribute(key);
205-
else
206-
session.setAttribute(key, modelView.getSession().get(key));
207221
}
208222

209-
// Set session from the request to the modelView
210-
for (Enumeration<String> e = session.getAttributeNames(); e.hasMoreElements(); ) {
223+
/* Adding session */
224+
for (String key : modelView.getSession().keySet()) {
225+
session.setAttribute(key, modelView.getSession().get(key));
226+
}
227+
}
228+
229+
// Set session from the request to the modelView
230+
public void setSessionsFromRequest(Object object, HttpServletRequest request, HttpServletResponse response) throws IOException {
231+
// Check if the session is new or invalidated
232+
HttpSession existingSession = request.getSession(false);
233+
if(existingSession == null || existingSession.isNew()) {
234+
return;
235+
}
236+
237+
// Get the field where sessions attributes are stored
238+
Field field;
239+
try {
240+
field = object.getClass().getDeclaredField("sessions");
241+
} catch (NoSuchFieldException ex) {
242+
throw new RuntimeException("FRAMEWORK ERROR - You can't get session attributes if the class `"+ object.getClass().getName()
243+
+"` does not have " +
244+
"`Hashmap<String, Object> sessions` as a field");
245+
}
246+
// Set the field accessible
247+
field.setAccessible(true);
248+
249+
// Iterate over the session attributes and add them to the HashMap
250+
HashMap<String, Object> sessions = new HashMap<>();
251+
for (Enumeration<String> e = request.getSession().getAttributeNames(); e.hasMoreElements(); ) {
211252
String key = e.nextElement();
212-
modelView.addSessionItem(key, session.getAttribute(key));
253+
sessions.put(key, request.getSession().getAttribute(key));
254+
}
255+
256+
try {
257+
field.set(object, sessions);
258+
} catch (IllegalAccessException ex) {
259+
throw new RuntimeException("FRAMEWORK ERROR - Cannot have access to the field sessions, be sure that the " +
260+
"field is public");
213261
}
214262
}
215263

1.69 KB
Binary file not shown.

0 commit comments

Comments
 (0)