1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  * KIND, either express or implied.  See the License for the
16  * specific language governing permissions and limitations
17  * under the License.
18  */
19 module hunt.shiro.session.Session;
20 
21 import hunt.util.Common;
22 import hunt.collection;
23 import hunt.shiro.util.Common;
24 // import java.util.Date;
25 
26 import hunt.String;
27 
28 alias Date = long;
29 
30 alias ShiroSession = Session;
31 
32 /**
33  * A {@code Session} is a stateful data context associated with a single Subject (user, daemon process,
34  * etc) who interacts with a software system over a period of time.
35  * <p/>
36  * A {@code Session} is intended to be managed by the business tier and accessible via other
37  * tiers without being tied to any given client technology.  This is a <em>great</em> benefit to Java
38  * systems, since until now, the only viable session mechanisms were the
39  * {@code javax.servlet.http.HttpSession} or Stateful Session EJB's, which many times
40  * unnecessarily coupled applications to web or ejb technologies.
41  *
42  */
43 interface Session {
44 
45     /**
46      * Returns the unique identifier assigned by the system upon session creation.
47      * <p/>
48      * All return values from this method are expected to have proper {@code toString()},
49      * {@code equals()}, and {@code hashCode()} implementations. Good candidates for such
50      * an identifier are {@link java.util.UUID UUID}s, {@link java.lang.Integer Integer}s, and
51      * {@link java.lang.string string}s.
52      *
53      * @return The unique identifier assigned to the session upon creation.
54      */
55     string getId();
56 
57     /**
58      * Returns the time the session was started; that is, the time the system created the instance.
59      *
60      * @return The time the system created the session.
61      */
62     Date getStartTimestamp();
63 
64     /**
65      * Returns the last time the application received a request or method invocation from the user associated
66      * with this session.  Application calls to this method do not affect this access time.
67      *
68      * @return The time the user last interacted with the system.
69      * @see #touch()
70      */
71     Date getLastAccessTime();
72 
73     /**
74      * Returns the time in milliseconds that the session session may remain idle before expiring.
75      * <ul>
76      * <li>A negative return value means the session will never expire.</li>
77      * <li>A non-negative return value (0 or greater) means the session expiration will occur if idle for that
78      * length of time.</li>
79      * </ul>
80      * <b>*Note:</b> if you are used to the {@code HttpSession}'s {@code getMaxInactiveInterval()} method, the scale on
81      * this method is different: Shiro Sessions use millisecond values for timeout whereas
82      * {@code HttpSession.getMaxInactiveInterval} uses seconds.  Always use millisecond values with Shiro sessions.
83      *
84      * @return the time in milliseconds the session may remain idle before expiring.
85      * @throws InvalidSessionException if the session has been stopped or expired prior to calling this method.
86      */
87     long getTimeout();
88 
89     /**
90      * Sets the time in milliseconds that the session may remain idle before expiring.
91      * <ul>
92      * <li>A negative value means the session will never expire.</li>
93      * <li>A non-negative value (0 or greater) means the session expiration will occur if idle for that
94      * length of time.</li>
95      * </ul>
96      * <p/>
97      * <b>*Note:</b> if you are used to the {@code HttpSession}'s {@code getMaxInactiveInterval()} method, the scale on
98      * this method is different: Shiro Sessions use millisecond values for timeout whereas
99      * {@code HttpSession.getMaxInactiveInterval} uses seconds.  Always use millisecond values with Shiro sessions.
100      *
101      * @param maxIdleTimeInMillis the time in milliseconds that the session may remain idle before expiring.
102      * @throws InvalidSessionException if the session has been stopped or expired prior to calling this method.
103      */
104     void setTimeout(long maxIdleTimeInMillis);
105 
106     /**
107      * Returns the host name or IP string of the host that originated this session, or {@code null}
108      * if the host is unknown.
109      *
110      * @return the host name or IP string of the host that originated this session, or {@code null}
111      *         if the host address is unknown.
112      */
113     string getHost();
114 
115     /**
116      * Explicitly updates the {@link #getLastAccessTime() lastAccessTime} of this session to the current time when
117      * this method is invoked.  This method can be used to ensure a session does not time out.
118      * <p/>
119      * Most programmers won't use this method directly and will instead rely on the last access time to be updated
120      * automatically as a result of an incoming web request or remote procedure call/method invocation.
121      * <p/>
122      * However, this method is particularly useful when supporting rich-client applications such as
123      * Java Web Start app, Java or Flash applets, etc.  Although rare, it is possible in a rich-client
124      * environment that a user continuously interacts with the client-side application without a
125      * server-side method call ever being invoked.  If this happens over a long enough period of
126      * time, the user's server-side session could time-out.  Again, such cases are rare since most
127      * rich-clients frequently require server-side method invocations.
128      * <p/>
129      * In this example though, the user's session might still be considered valid because
130      * the user is actively &quot;using&quot; the application, just not communicating with the
131      * server. But because no server-side method calls are invoked, there is no way for the server
132      * to know if the user is sitting idle or not, so it must assume so to maintain session
133      * integrity.  This {@code touch()} method could be invoked by the rich-client application code during those
134      * times to ensure that the next time a server-side method is invoked, the invocation will not
135      * throw an {@link ExpiredSessionException ExpiredSessionException}.  In short terms, it could be used periodically
136      * to ensure a session does not time out.
137      * <p/>
138      * How often this rich-client &quot;maintenance&quot; might occur is entirely dependent upon
139      * the application and would be based on variables such as session timeout configuration,
140      * usage characteristics of the client application, network utilization and application server
141      * performance.
142      *
143      * @throws InvalidSessionException if this session has stopped or expired prior to calling this method.
144      */
145     void touch();
146 
147     /**
148      * Explicitly stops (invalidates) this session and releases all associated resources.
149      * <p/>
150      * If this session has already been authenticated (i.e. the {@code Subject} that
151      * owns this session has logged-in), calling this method explicitly might have undesired side effects:
152      * <p/>
153      * It is common for a {@code Subject} implementation to retain authentication state in the
154      * {@code Session}.  If the session
155      * is explicitly stopped by application code by calling this method directly, it could clear out any
156      * authentication state that might exist, thereby effectively &quot;unauthenticating&quot; the {@code Subject}.
157      * <p/>
158      * As such, you might consider {@link hunt.shiro.subject.Subject#logout logging-out} the 'owning'
159      * {@code Subject} instead of manually calling this method, as a log out is expected to stop the
160      * corresponding session automatically, and also allows framework code to execute additional cleanup logic.
161      *
162      * @throws InvalidSessionException if this session has stopped or expired prior to calling this method.
163      */
164     void stop();
165 
166     /**
167      * Returns the keys of all the attributes stored under this session.  If there are no
168      * attributes, this returns an empty collection.
169      *
170      * @return the keys of all attributes stored under this session, or an empty collection if
171      *         there are no session attributes.
172      * @throws InvalidSessionException if this session has stopped or expired prior to calling this method.
173      */
174     Object[] getAttributeKeys();
175 
176     /**
177      * Returns the object bound to this session identified by the specified key.  If there is no
178      * object bound under the key, {@code null} is returned.
179      *
180      * @param key the unique name of the object bound to this session
181      * @return the object bound under the specified {@code key} name or {@code null} if there is
182      *         no object bound under that name.
183      * @throws InvalidSessionException if this session has stopped or expired prior to calling
184      *                                 this method.
185      */
186     Object getAttribute(Object key);
187 
188     
189     final Object getAttribute(string key) {
190         return getAttribute(new String(key));
191     }
192 
193     /**
194      * Binds the specified {@code value} to this session, uniquely identified by the specified
195      * {@code key} name.  If there is already an object bound under the {@code key} name, that
196      * existing object will be replaced by the new {@code value}.
197      * <p/>
198      * If the {@code value} parameter is null, it has the same effect as if
199      * {@link #removeAttribute(Object) removeAttribute} was called.
200      *
201      * @param key   the name under which the {@code value} object will be bound in this session
202      * @param value the object to bind in this session.
203      * @throws InvalidSessionException if this session has stopped or expired prior to calling
204      *                                 this method.
205      */
206     void setAttribute(Object key, Object value);
207 
208     final void setAttribute(string key, Object value) {
209         setAttribute(new String(key), value);
210     }
211 
212     final void setAttribute(string key, string value) {
213         setAttribute(new String(key), new String(value));
214     }
215 
216     /**
217      * Removes (unbinds) the object bound to this session under the specified {@code key} name.
218      *
219      * @param key the name uniquely identifying the object to remove
220      * @return the object removed or {@code null} if there was no object bound under the name
221      *         {@code key}.
222      * @throws InvalidSessionException if this session has stopped or expired prior to calling
223      *                                 this method.
224      */
225     Object removeAttribute(Object key);
226 
227     final Object removeAttribute(string key) {
228         return removeAttribute(new String(key));
229     }
230 }