Merge pull request #1458 from BrzVlad/feature-fat-cas
[mono.git] / mcs / class / System.Web / System.Web.UI.WebControls / LoginStatus.cs
1 //
2 // System.Web.UI.WebControls.LoginStatus class
3 //
4 // Author:
5 //      Sebastien Pouliot  <sebastien@ximian.com>
6 //
7 // Copyright (C) 2005 Novell, Inc (http://www.novell.com)
8 //
9 // Permission is hereby granted, free of charge, to any person obtaining
10 // a copy of this software and associated documentation files (the
11 // "Software"), to deal in the Software without restriction, including
12 // without limitation the rights to use, copy, modify, merge, publish,
13 // distribute, sublicense, and/or sell copies of the Software, and to
14 // permit persons to whom the Software is furnished to do so, subject to
15 // the following conditions:
16 // 
17 // The above copyright notice and this permission notice shall be
18 // included in all copies or substantial portions of the Software.
19 // 
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 //
28
29
30 using System.Collections;
31 using System.ComponentModel;
32 using System.Globalization;
33 using System.Security.Permissions;
34 using System.Web.Security;
35
36 namespace System.Web.UI.WebControls {
37
38         // CAS
39         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
40         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
41         [Bindable (false)]
42         [DefaultEvent ("LoggingOut")]
43         [Designer ("System.Web.UI.Design.WebControls.LoginStatusDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
44         public class LoginStatus : CompositeControl 
45         {
46                 static readonly object loggedOutEvent = new object ();
47                 static readonly object loggingOutEvent = new object ();
48
49                 LinkButton logoutLinkButton;
50                 ImageButton logoutImageButton;
51                 LinkButton loginLinkButton;
52                 ImageButton loginImageButton;
53
54                 public LoginStatus ()
55                 {
56                 }
57
58                 [DefaultValue ("")]
59                 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
60                 [UrlProperty]
61                 public virtual string LoginImageUrl {
62                         get {
63                                 object o = ViewState ["LoginImageUrl"];
64                                 return (o == null) ? String.Empty : (string) o;
65                         }
66                         set {
67                                 if (value == null)
68                                         ViewState.Remove ("LoginImageUrl");
69                                 else
70                                         ViewState ["LoginImageUrl"] = value;
71                         }
72                 }
73
74                 [Localizable (true)]
75                 public virtual string LoginText {
76                         get {
77                                 object o = ViewState ["LoginText"];
78                                 return (o == null) ? Locale.GetText ("Login") : (string) o;
79                         }
80                         set {
81                                 if (value == null)
82                                         ViewState.Remove ("LoginText");
83                                 else
84                                         ViewState ["LoginText"] = value;
85                         }
86                 }
87
88                 [DefaultValue (LogoutAction.Refresh)]
89                 [Themeable (false)]
90                 public virtual LogoutAction LogoutAction {
91                         get {
92                                 object o = ViewState ["LogoutAction"];
93                                 return (o == null) ? LogoutAction.Refresh : (LogoutAction) o;
94                         }
95                         set {
96                                 if ((value < LogoutAction.Refresh) || (value > LogoutAction.RedirectToLoginPage))
97                                         throw new ArgumentOutOfRangeException ("LogoutAction");
98                                 ViewState ["LogoutAction"] = (int) value;
99                         }
100                 }
101
102                 [DefaultValue ("")]
103                 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
104                 [UrlProperty]
105                 public virtual string LogoutImageUrl {
106                         get {
107                                 object o = ViewState ["LogoutImageUrl"];
108                                 return (o == null) ? String.Empty : (string) o;
109                         }
110                         set {
111                                 if (value == null)
112                                         ViewState.Remove ("LogoutImageUrl");
113                                 else
114                                         ViewState ["LogoutImageUrl"] = value;
115                         }
116                 }
117
118
119                 [DefaultValue ("")]
120                 [Editor ("System.Web.UI.Design.UrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
121                 [Themeable (false)]
122                 [UrlProperty]
123                 public virtual string LogoutPageUrl {
124                         get {
125                                 object o = ViewState ["LogoutPageUrl"];
126                                 return (o == null) ? String.Empty : (string) o;
127                         }
128                         set {
129                                 if (value == null)
130                                         ViewState.Remove ("LogoutPageUrl");
131                                 else
132                                         ViewState ["LogoutPageUrl"] = value;
133                         }
134                 }
135
136                 [Localizable (true)]
137                 public virtual string LogoutText {
138                         get {
139                                 object o = ViewState ["LogoutText"];
140                                 return (o == null) ? Locale.GetText ("Logout") : (string) o;
141                         }
142                         set {
143                                 if (value == null)
144                                         ViewState.Remove ("LogoutText");
145                                 else
146                                         ViewState ["LogoutText"] = value;
147                         }
148                 }
149
150                 protected override HtmlTextWriterTag TagKey {
151                         get { return HtmlTextWriterTag.A; }
152                 }
153
154                 // methods
155                 protected internal override void CreateChildControls ()
156                 {
157                         Controls.Clear ();
158
159                         // we create controls for all possibilities
160                         logoutLinkButton = new LinkButton ();
161                         logoutLinkButton.CausesValidation = false;
162                         logoutLinkButton.Command += new CommandEventHandler (LogoutClick);
163                         logoutImageButton = new ImageButton ();
164                         logoutImageButton.CausesValidation = false;
165                         logoutImageButton.Command += new CommandEventHandler (LogoutClick);
166                         loginLinkButton = new LinkButton ();
167                         loginLinkButton.CausesValidation = false;
168                         loginLinkButton.Command += new CommandEventHandler (LoginClick);
169                         loginImageButton = new ImageButton ();
170                         loginImageButton.CausesValidation = false;
171                         loginImageButton.Command += new CommandEventHandler (LoginClick);
172
173                         // adds controls at the end (after setting their properties)
174                         Controls.Add (logoutLinkButton);
175                         Controls.Add (logoutImageButton);
176                         Controls.Add (loginLinkButton);
177                         Controls.Add (loginImageButton);
178                 }
179
180                 protected virtual void OnLoggedOut (EventArgs e)
181                 {
182                         // this gets called only if the authentication was successful
183                         EventHandler loggedOut = (EventHandler) Events [loggedOutEvent];
184                         if (loggedOut != null)
185                                 loggedOut (this, e);
186                 }
187
188                 protected virtual void OnLoggingOut (LoginCancelEventArgs e)
189                 {
190                         // this gets called before OnAuthenticate so we can abort the authentication process
191                         LoginCancelEventHandler loggingOut = (LoginCancelEventHandler) Events [loggingOutEvent];
192                         if (loggingOut != null)
193                                 loggingOut (this, e);
194                 }
195
196                 protected internal override void OnPreRender (EventArgs e)
197                 {
198                         base.OnPreRender (e);
199                         // documentation says we select Login*|Logout* here
200                         // but tests shows that the selection is done even 
201                         // if OnPreRender is never called
202                 }
203
204                 protected internal override void Render (HtmlTextWriter writer)
205                 {
206                         if (writer == null)
207                                 return;
208
209                         RenderContents (writer);
210                 }
211
212                 protected internal override void RenderContents (HtmlTextWriter writer)
213                 {
214                         if (writer == null)
215                                 return;
216
217                         EnsureChildControls ();
218
219                         bool authenticated = false;
220                         if (Page != null) {
221                                 Page.VerifyRenderingInServerForm (this);
222                                 authenticated = Page.Request.IsAuthenticated;
223                         }
224
225                         bool logoutImage = (LogoutImageUrl.Length > 0);
226                         logoutLinkButton.Visible = authenticated && !logoutImage;
227                         logoutImageButton.Visible = authenticated && logoutImage;
228
229                         bool loginImage = (LoginImageUrl.Length > 0);
230                         loginLinkButton.Visible = !authenticated && !loginImage;
231                         loginImageButton.Visible = !authenticated && loginImage;
232
233                         if (logoutLinkButton.Visible) {
234                                 logoutLinkButton.Text = LogoutText;
235                                 logoutLinkButton.CssClass = this.CssClass;
236                                 logoutLinkButton.Render (writer);
237                         } else if (logoutImageButton.Visible) {
238                                 logoutImageButton.AlternateText = LogoutText;
239                                 logoutImageButton.CssClass = this.CssClass;
240                                 logoutImageButton.ImageUrl = LogoutImageUrl;
241                                 writer.AddAttribute(HtmlTextWriterAttribute.Name, logoutImageButton.UniqueID);
242                                 logoutImageButton.Render (writer);
243                         } else if (loginLinkButton.Visible) {
244                                 loginLinkButton.Text = LoginText;
245                                 loginLinkButton.CssClass = this.CssClass;
246                                 loginLinkButton.Render (writer);
247                         } else if (loginImageButton.Visible) {
248                                 loginImageButton.AlternateText = LoginText;
249                                 loginImageButton.CssClass = this.CssClass;
250                                 loginImageButton.ImageUrl = LoginImageUrl;
251                                 writer.AddAttribute(HtmlTextWriterAttribute.Name, loginImageButton.UniqueID);
252                                 loginImageButton.Render (writer);
253                         }
254                 }
255
256                 [MonoTODO ("for design-time usage - no more details available")]
257                 protected override void SetDesignModeState (IDictionary data)
258                 {
259                         base.SetDesignModeState (data);
260                 }
261
262                 // events
263                 public event EventHandler LoggedOut {
264                         add { Events.AddHandler (loggedOutEvent, value); }
265                         remove { Events.RemoveHandler (loggedOutEvent, value); }
266                 }
267
268                 public event LoginCancelEventHandler LoggingOut {
269                         add { Events.AddHandler (loggingOutEvent, value); }
270                         remove { Events.RemoveHandler (loggingOutEvent, value); }
271                 }
272
273                 // private stuff
274                 void LogoutClick (object sender, CommandEventArgs e)
275                 {
276                         LoginCancelEventArgs lcea = new LoginCancelEventArgs (false);
277                         OnLoggingOut (lcea);
278                         if (lcea.Cancel)
279                                 return;
280
281                         FormsAuthentication.SignOut ();
282                         OnLoggedOut (e);
283
284                         switch (LogoutAction) {
285                         case LogoutAction.Refresh:
286                                 HttpContext.Current.Response.Redirect (Page.Request.Url.AbsoluteUri);
287                                 break;
288                         case LogoutAction.RedirectToLoginPage:
289                                 FormsAuthentication.RedirectToLoginPage ();
290                                 break;
291                         case LogoutAction.Redirect:
292                                 string url = LogoutPageUrl;
293                                 if (url.Length == 0)
294                                         url = Page.Request.Url.AbsoluteUri;
295                                 HttpContext.Current.Response.Redirect (url);
296                                 break;
297                         }
298                 }
299
300                 void LoginClick (object sender, CommandEventArgs e)
301                 {
302                         FormsAuthentication.RedirectToLoginPage ();
303                 }
304         }
305 }
306