2008-11-28 Marek Habersack <mhabersack@novell.com>
[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 #if NET_2_0
30
31 using System.Collections;
32 using System.ComponentModel;
33 using System.Globalization;
34 using System.Security.Permissions;
35 using System.Web.Security;
36
37 namespace System.Web.UI.WebControls {
38
39         // CAS
40         [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
41         [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
42         [Bindable (false)]
43         [DefaultEvent ("LoggingOut")]
44         [Designer ("System.Web.UI.Design.WebControls.LoginStatusDesigner, " + Consts.AssemblySystem_Design, "System.ComponentModel.Design.IDesigner")]
45         public class LoginStatus : CompositeControl 
46         {
47                 static readonly object loggedOutEvent = new object ();
48                 static readonly object loggingOutEvent = new object ();
49
50                 LinkButton logoutLinkButton;
51                 ImageButton logoutImageButton;
52                 LinkButton loginLinkButton;
53                 ImageButton loginImageButton;
54
55                 public LoginStatus ()
56                 {
57                 }
58
59                 [DefaultValue ("")]
60                 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
61                 [UrlProperty]
62                 public virtual string LoginImageUrl {
63                         get {
64                                 object o = ViewState ["LoginImageUrl"];
65                                 return (o == null) ? String.Empty : (string) o;
66                         }
67                         set {
68                                 if (value == null)
69                                         ViewState.Remove ("LoginImageUrl");
70                                 else
71                                         ViewState ["LoginImageUrl"] = value;
72                         }
73                 }
74
75                 [Localizable (true)]
76                 public virtual string LoginText {
77                         get {
78                                 object o = ViewState ["LoginText"];
79                                 return (o == null) ? Locale.GetText ("Login") : (string) o;
80                         }
81                         set {
82                                 if (value == null)
83                                         ViewState.Remove ("LoginText");
84                                 else
85                                         ViewState ["LoginText"] = value;
86                         }
87                 }
88
89                 [DefaultValue (LogoutAction.Refresh)]
90                 [Themeable (false)]
91                 public virtual LogoutAction LogoutAction {
92                         get {
93                                 object o = ViewState ["LogoutAction"];
94                                 return (o == null) ? LogoutAction.Refresh : (LogoutAction) o;
95                         }
96                         set {
97                                 if ((value < LogoutAction.Refresh) || (value > LogoutAction.RedirectToLoginPage))
98                                         throw new ArgumentOutOfRangeException ("LogoutAction");
99                                 ViewState ["LogoutAction"] = (int) value;
100                         }
101                 }
102
103                 [DefaultValue ("")]
104                 [Editor ("System.Web.UI.Design.ImageUrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
105                 [UrlProperty]
106                 public virtual string LogoutImageUrl {
107                         get {
108                                 object o = ViewState ["LogoutImageUrl"];
109                                 return (o == null) ? String.Empty : (string) o;
110                         }
111                         set {
112                                 if (value == null)
113                                         ViewState.Remove ("LogoutImageUrl");
114                                 else
115                                         ViewState ["LogoutImageUrl"] = value;
116                         }
117                 }
118
119
120                 [DefaultValue ("")]
121                 [Editor ("System.Web.UI.Design.UrlEditor, " + Consts.AssemblySystem_Design, "System.Drawing.Design.UITypeEditor, " + Consts.AssemblySystem_Drawing)]
122                 [Themeable (false)]
123                 [UrlProperty]
124                 public virtual string LogoutPageUrl {
125                         get {
126                                 object o = ViewState ["LogoutPageUrl"];
127                                 return (o == null) ? String.Empty : (string) o;
128                         }
129                         set {
130                                 if (value == null)
131                                         ViewState.Remove ("LogoutPageUrl");
132                                 else
133                                         ViewState ["LogoutPageUrl"] = value;
134                         }
135                 }
136
137                 [Localizable (true)]
138                 public virtual string LogoutText {
139                         get {
140                                 object o = ViewState ["LogoutText"];
141                                 return (o == null) ? Locale.GetText ("Logout") : (string) o;
142                         }
143                         set {
144                                 if (value == null)
145                                         ViewState.Remove ("LogoutText");
146                                 else
147                                         ViewState ["LogoutText"] = value;
148                         }
149                 }
150
151                 protected override HtmlTextWriterTag TagKey {
152                         get { return HtmlTextWriterTag.A; }
153                 }
154
155                 // methods
156                 protected internal override void CreateChildControls ()
157                 {
158                         Controls.Clear ();
159
160                         // we create controls for all possibilities
161                         logoutLinkButton = new LinkButton ();
162                         logoutLinkButton.CausesValidation = false;
163                         logoutLinkButton.Command += new CommandEventHandler (LogoutClick);
164                         logoutImageButton = new ImageButton ();
165                         logoutImageButton.CausesValidation = false;
166                         logoutImageButton.Command += new CommandEventHandler (LogoutClick);
167                         loginLinkButton = new LinkButton ();
168                         loginLinkButton.CausesValidation = false;
169                         loginLinkButton.Command += new CommandEventHandler (LoginClick);
170                         loginImageButton = new ImageButton ();
171                         loginImageButton.CausesValidation = false;
172                         loginImageButton.Command += new CommandEventHandler (LoginClick);
173
174                         // adds controls at the end (after setting their properties)
175                         Controls.Add (logoutLinkButton);
176                         Controls.Add (logoutImageButton);
177                         Controls.Add (loginLinkButton);
178                         Controls.Add (loginImageButton);
179                 }
180
181                 protected virtual void OnLoggedOut (EventArgs e)
182                 {
183                         // this gets called only if the authentication was successful
184                         EventHandler loggedOut = (EventHandler) Events [loggedOutEvent];
185                         if (loggedOut != null)
186                                 loggedOut (this, e);
187                 }
188
189                 protected virtual void OnLoggingOut (LoginCancelEventArgs e)
190                 {
191                         // this gets called before OnAuthenticate so we can abort the authentication process
192                         LoginCancelEventHandler loggingOut = (LoginCancelEventHandler) Events [loggingOutEvent];
193                         if (loggingOut != null)
194                                 loggingOut (this, e);
195                 }
196
197                 protected internal override void OnPreRender (EventArgs e)
198                 {
199                         base.OnPreRender (e);
200                         // documentation says we select Login*|Logout* here
201                         // but tests shows that the selection is done even 
202                         // if OnPreRender is never called
203                 }
204
205                 protected internal override void Render (HtmlTextWriter writer)
206                 {
207                         if (writer == null)
208                                 return;
209
210                         RenderContents (writer);
211                 }
212
213                 protected internal override void RenderContents (HtmlTextWriter writer)
214                 {
215                         if (writer == null)
216                                 return;
217
218                         EnsureChildControls ();
219
220                         bool authenticated = false;
221                         if (Page != null) {
222                                 Page.VerifyRenderingInServerForm (this);
223                                 authenticated = Page.Request.IsAuthenticated;
224                         }
225
226                         bool logoutImage = (LogoutImageUrl.Length > 0);
227                         logoutLinkButton.Visible = authenticated && !logoutImage;
228                         logoutImageButton.Visible = authenticated && logoutImage;
229
230                         bool loginImage = (LoginImageUrl.Length > 0);
231                         loginLinkButton.Visible = !authenticated && !loginImage;
232                         loginImageButton.Visible = !authenticated && loginImage;
233
234                         if (logoutLinkButton.Visible) {
235                                 logoutLinkButton.Text = LogoutText;
236                                 logoutLinkButton.CssClass = this.CssClass;
237                                 logoutLinkButton.Render (writer);
238                         } else if (logoutImageButton.Visible) {
239                                 logoutImageButton.AlternateText = LogoutText;
240                                 logoutImageButton.CssClass = this.CssClass;
241                                 logoutImageButton.ImageUrl = LogoutImageUrl;
242                                 writer.AddAttribute(HtmlTextWriterAttribute.Name, logoutImageButton.UniqueID);
243                                 logoutImageButton.Render (writer);
244                         } else if (loginLinkButton.Visible) {
245                                 loginLinkButton.Text = LoginText;
246                                 loginLinkButton.CssClass = this.CssClass;
247                                 loginLinkButton.Render (writer);
248                         } else if (loginImageButton.Visible) {
249                                 loginImageButton.AlternateText = LoginText;
250                                 loginImageButton.CssClass = this.CssClass;
251                                 loginImageButton.ImageUrl = LoginImageUrl;
252                                 writer.AddAttribute(HtmlTextWriterAttribute.Name, loginImageButton.UniqueID);
253                                 loginImageButton.Render (writer);
254                         }
255                 }
256
257                 [MonoTODO ("for design-time usage - no more details available")]
258                 protected override void SetDesignModeState (IDictionary data)
259                 {
260                         base.SetDesignModeState (data);
261                 }
262
263                 // events
264                 public event EventHandler LoggedOut {
265                         add { Events.AddHandler (loggedOutEvent, value); }
266                         remove { Events.RemoveHandler (loggedOutEvent, value); }
267                 }
268
269                 public event LoginCancelEventHandler LoggingOut {
270                         add { Events.AddHandler (loggingOutEvent, value); }
271                         remove { Events.RemoveHandler (loggingOutEvent, value); }
272                 }
273
274                 // private stuff
275                 void LogoutClick (object sender, CommandEventArgs e)
276                 {
277                         LoginCancelEventArgs lcea = new LoginCancelEventArgs (false);
278                         OnLoggingOut (lcea);
279                         if (lcea.Cancel)
280                                 return;
281
282                         FormsAuthentication.SignOut ();
283                         OnLoggedOut (e);
284
285                         switch (LogoutAction) {
286                         case LogoutAction.Refresh:
287                                 HttpContext.Current.Response.Redirect (Page.Request.Url.AbsoluteUri);
288                                 break;
289                         case LogoutAction.RedirectToLoginPage:
290                                 FormsAuthentication.RedirectToLoginPage ();
291                                 break;
292                         case LogoutAction.Redirect:
293                                 string url = LogoutPageUrl;
294                                 if (url.Length == 0)
295                                         url = Page.Request.Url.AbsoluteUri;
296                                 HttpContext.Current.Response.Redirect (url);
297                                 break;
298                         }
299                 }
300
301                 void LoginClick (object sender, CommandEventArgs e)
302                 {
303                         FormsAuthentication.RedirectToLoginPage ();
304                 }
305         }
306 }
307
308 #endif