Loginn
For å hjelpe brukeren dersom han glemmer passordet, får han tilbud om å spare tre verdier: fødselsår, postnummer og lykketall. Hva dette er, tekst eller tall, er det samme.
Passordene lagres i en enkel XML-struktur:
<?xml version="1.0" encoding="utf-8"?> <users> <user name="ole" pwd="olsen" tag1="46" tag2="1784" tag3="7" /> <user name="kari" pwd="karlsen07" tag1="23" tag2="2090" tag3="12" /> </users>
Alle de aktuelle dialogfragmentene er laget som Views innenfor en MultiView. Vi kan si at hvert View beskriver en tilstand i logginnsekvensen, og vi kan lage et tilstandsdiagram som planleggings- og dokumentsajonshjelpemiddel.
Webside
<%@ Page Language="C#" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Registrering</title>
<link rel="Stylesheet" type="text/css" href="StyleSheet.css" />
<script language="javascript" type="text/javascript">
// <!CDATA[
function Button5_onclick() {
document.getElementById('show_password').innerHTML=
document.getElementById('hidden_password').innerHTML;
return false;
}
// ]]>
</script>
</head>
<body>
<asp:Label ID="LabelHeader" runat="server"
Text="Velkommen til dette vevstedet"
CssClass="mainheader"></asp:Label>
<form id="form1" runat="server">
<div>
<asp:MultiView ID="MultiView1" runat="server">
<!-- ******************** introduction *********************** -->
<asp:View ID="View1" runat="server">
<fieldset>
<legend>Du må registrere deg</legend>
<div>
<br />
Jeg er allerede registrert:<br />
</div>
<div>
<br />
Navn: <input id="Text1" type="text"
runat="server" style="width: 168px; height: 16px" />
<asp:Label ID="BadNameIntro"
runat="server" CssClass="errormsg" Width="226px">
</asp:Label>
</div>
<div>
<br />
Passord: <input id="Password1" type="password"
runat="server" style="width: 167px" />
<asp:Label ID="BadPwdIntro"
runat="server" CssClass="errormsg" Width="226px">
</asp:Label><br />
<br />
<input style="margin-left:200px" id="Button1"
runat="server" type="button" value="Slipp meg inn"
onserverclick="Button1_ServerClick" /><br />
</div>
<br />
<hr />
<br />
<input id="Button2" type="button"
runat="server" value="Jeg er ny, registrer meg"
onserverclick="Button2_ServerClick" />
<br />
<br />
<input id="Button3" type="button"
runat="server" value="Jeg har glemt passordet"
onserverclick="Button3_ServerClick" />
</fieldset>
</asp:View>
<!-- ******************** handle new user ***************** -->
<asp:View ID="View2" runat="server">
<fieldset>
<legend>Registrering av ny bruker</legend>
<br />
Navn:
<input id="Text2" type="text"
runat="server" style="width: 145px" />
<asp:Label ID="BadName" runat="server"
CssClass="errormsg" Width="226px"></asp:Label><br />
Passord:
<input id="Password2" style="width: 147px" type="password"
runat="server" />
<asp:Label ID="BadPwd" runat="server"
CssClass="errormsg" Width="229px"></asp:Label><br />
Gjenta passord: <input id="Password3"
style="width: 148px" type="password" /><br />
<div class="msg">Hvis du fyller ut de 3
feltene nedenfor kan du få hjelp
hvis du glemmer passordet</div>
Fødselsår:
<input id="Text3" style="width: 52px" type="text"
runat="server"/><br />
Postnummer:
<input id="Text4" style="width: 54px" type="text"
runat="server" /><br />
Lykketall:
<input id="Text5" style="width: 53px" type="text"
runat="server"/><br />
<input id="Submit1" type="submit"
value="Registrer meg" runat="server"
onserverclick="Submit1_ServerClick"/><br />
</fieldset>
</asp:View>
<!-- *************** handle forgetfull user ********** -->
<asp:View ID="View3" runat="server">
<fieldset>
<legend>Hjelp for å komme inn</legend>
<br />
Fødselsår:
<input id="Text6" style="width: 52px" type="text"
runat="server"/><br />
Postnummer:
<input id="Text7" style="width: 54px" type="text"
runat="server" /><br />
Lykketall:
<input id="Text8" style="width: 53px" type="text"
runat="server"/><br />
<input style="margin-left:200px" id="Submit2"
type="submit" value="Finn meg" runat="server"
onserverclick="Submit2_ServerClick"/>
<br />
</fieldset>
</asp:View>
<!-- ************ You are inside ************* -->
<asp:View ID="View4" runat="server">
<fieldset>
<legend>Du er registrert og logget inn</legend>
<br />
<asp:Label ID="SuccessName" runat="server" Text="Label">
</asp:Label><br />
<br />
<asp:Button ID="Button6" runat="server" Text="Logg ut"
OnClick="Button6_Click" /></fieldset>
</asp:View>
<!-- ************* log in failed ************ -->
<asp:View ID="View5" runat="server">
<fieldset>
<legend>Beklager</legend> <br />
Finner deg ikke
<asp:Label ID="userName" runat="server"
Text="Label"></asp:Label><br />
<br />
<input id="Button4" type="button"
runat="server" value="OK"
onserverclick="Button4_ServerClick" />
</fieldset>
</asp:View>
<!-- *************** already exist *************** -->
<asp:View ID="View6" runat="server">
<fieldset>
<legend>Finnes allerede</legend>
<br />
<span style="color: #0046d5">
En bruker med dette navnet finnes allerede:<br />
<br />
</span>
<input id="Submit3" type="submit" value="Prøv igjen"
runat="server" onserverclick="Submit3_ServerClick" />
<input id="Submit4" type="submit" value="Gir opp"
runat="server" onserverclick="Submit4_ServerClick" />
<br />
</fieldset>
<!-- ************ confirmed help ************* -->
</asp:View>
<asp:View ID="View7" runat="server">
<fieldset>
<legend>Du er funnet</legend>
<asp:label style="display:none" ID="hidden_password"
runat="server"></asp:label>
<asp:Label ID="username2" runat="server" Text="Label">
</asp:Label>
Passordet ditt er:
<span id="show_password">
<input id="Button5" type="button" value="Vis"
onclick="return Button5_onclick()" />
</span>
<br /><br />
<input id="Submit5" type="submit" runat="server" value="OK"
onserverclick="Submit5_ServerClick" />
</fieldset>
</asp:View>
</asp:MultiView>
</div>
</form>
</body>
</html>
Programkode
Default.aspx.cs
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
MultiView1.SetActiveView(View1);
// reset all errormessages
BadNameIntro.Text = "";
BadPwdIntro.Text = "";
BadName.Text = "";
BadPwd.Text = "";
// set filepath for passwordadmin
pasadmin.setFileName( String.Format(@"{0}\App_Data\users.xml",
Path.GetDirectoryName(Request.PhysicalPath)));
// check cookies
HttpCookie c=Request.Cookies["user"];
if(c!=null)
{
SuccessName.Text = c.Value;
MultiView1.SetActiveView(View4);
return;
}
}
protected void setCookie(String name)
{
HttpCookie cook = new HttpCookie("user");
cook["Navn"] = name;
Response.Cookies.Add(cook);
}
protected void killCookie()
{
HttpCookie cook = new HttpCookie("user");
cook.Expires = DateTime.Now.AddDays(-1d);
Response.Cookies.Add(cook);
}
protected void Button1_ServerClick(object sender, EventArgs e)
{
// slipp meg inn
String name = Text1.Value;
String pwd = Password1.Value;
// control
if (name.Length == 0)
{
BadNameIntro.Text = "mangler navn";
return;
}
if (pwd.Length == 0)
{
BadPwdIntro.Text = "mangler passord";
return;
}
if (pasadmin.OldUserOk(name, pwd))
{
// du er inne:
SuccessName.Text = name;
setCookie(SuccessName.Text);
MultiView1.SetActiveView(View4);
}
else
{
// sorry
MultiView1.SetActiveView(View5);
}
}
protected void Button2_ServerClick(object sender, EventArgs e)
{
// new user, register me
MultiView1.SetActiveView(View2);
}
protected void Button3_ServerClick(object sender, EventArgs e)
{
// forgotten the password, help him
MultiView1.SetActiveView(View3);
}
protected void Button4_ServerClick(object sender, EventArgs e)
{
// user did not get inn and has received a message
MultiView1.SetActiveView(View1);
}
protected void Submit1_ServerClick(object sender, EventArgs e)
{
// user submit application as new user
String Name = Text2.Value;
String Pwd1 = Password2.Value;
String Pwd2 = Password2.Value;
String Hlp1 = Text3.Value;
String Hlp2 = Text4.Value;
String Hlp3 = Text5.Value;
// control
if (Name.Length == 0)
{
BadName.Text = "mangler navn";
return;
}
if ((Pwd1.Length < 3) ||
(Pwd2.Length < 3) ||
(Pwd1.CompareTo(Pwd2) != 0))
{
BadPwd.Text = "to identiske passord, lenger enn 3 tegn";
return;
}
// user exists already, we pretend name identity
// but is really name and password identity
if (pasadmin.OldUserOk(Name, Pwd1))
{
// sorry already registered
MultiView1.SetActiveView(View6);
return;
}
String res = pasadmin.RegisterUser(Name, Pwd1, Hlp1, Hlp2, Hlp3);
if (res != null)
{
SuccessName.Text = Name;
setCookie(SuccessName.Text);
MultiView1.SetActiveView(View4);
}
}
protected void Submit2_ServerClick(object sender, EventArgs e)
{
// attempt to localize user based on the three fields
String Hlp1 = Text6.Value;
String Hlp2 = Text7.Value;
String Hlp3 = Text8.Value;
String[]NP = pasadmin.FindUser(Hlp1, Hlp2, Hlp3);
if (NP == null)
{
userName.Text="?";
MultiView1.SetActiveView(View5);
return;
}
// found him, ok let him in
String Pwd = NP[0];
String Name = NP[1];
hidden_password.Text = Pwd;
username2.Text = Name;
MultiView1.SetActiveView(View7);
}
protected void Submit3_ServerClick(object sender, EventArgs e)
{
// try again after having submitted existing data
MultiView1.SetActiveView(View2);
}
protected void Submit4_ServerClick(object sender, EventArgs e)
{
// give up after having submitted existing data
MultiView1.SetActiveView(View1);
}
protected void Submit5_ServerClick(object sender, EventArgs e)
{
// user is told he is found, and shown the password
// let him in
SuccessName.Text = username2.Text;
setCookie(SuccessName.Text);
MultiView1.SetActiveView(View4);
}
protected void Button6_Click(object sender, EventArgs e)
{
// want to log out
killCookie();
MultiView1.SetActiveView(View1);
}
}
pasadmin.cs
Administrasjon av passordfila er lagt til en egen klasse, pasadmin. Denne kan lett byttes ut. Klassen har følgende rutiner som brukes utenfra, fra Dafault.aspx.cs: RegisterUser, FindUser, OldUserOk, setFileName.
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Xml;
using System.IO;
/// <summary>
/// Summary description for pasadmin
/// </summary>
public class pasadmin
{
static String FileName;
public pasadmin(String filename)
{
}
public static void setFileName(String fn)
{
// set filename from usercode, since usercode knows the path ?
FileName=fn;
}
static String GetXmlFileName()
{
return FileName;
}
static XmlDocument GetUserDoc()
{
XmlDocument doc = new XmlDocument();
try
{
String FileName = GetXmlFileName();
doc.Load(FileName);
return doc;
}
catch (Exception ex)
{
// errormessage
return null;
}
}
static void SetUserDoc(XmlDocument doc)
{
try
{
String FileName = GetXmlFileName();
FileStream fs = new FileStream(FileName, FileMode.Open);
XmlTextWriter writer =
new XmlTextWriter(fs, System.Text.Encoding.UTF8);
writer.Formatting = Formatting.Indented;
doc.WriteContentTo(writer);
writer.Flush();
writer.Close();
}
catch (Exception ex)
{
// errormessage
}
}
static public bool OldUserOk(String name, String passwd)
{
XmlDocument doc = GetUserDoc();
if (doc == null)
return false;
XmlNodeList users = doc.GetElementsByTagName("user");
foreach (XmlElement user in users)
{
String name_att = user.GetAttribute("name");
String pwd_att = user.GetAttribute("pwd");
if ((name_att.CompareTo(name.Trim()) == 0) &&
(pwd_att.CompareTo(passwd.Trim()) == 0))
return true;
}
return false;
}
static public String[] FindUser(String Hlp1, String Hlp2, String Hlp3)
{
XmlDocument doc = GetUserDoc();
if (doc == null)
return null;
XmlNodeList users = doc.GetElementsByTagName("user");
foreach (XmlElement user in users)
{
String t1 = user.GetAttribute("tag1");
String t2 = user.GetAttribute("tag2");
String t3 = user.GetAttribute("tag3");
if ((t1.CompareTo(Hlp1.Trim()) == 0) &&
(t2.CompareTo(Hlp2.Trim()) == 0) &&
(t3.CompareTo(Hlp3.Trim()) == 0))
{
String[] L = new String[2];
L[0] = user.GetAttribute("pwd");
L[1] = user.GetAttribute("name");
return L;
}
}
return null;
}
static public String RegisterUser(String Name, String Pwd,
String Hlp1, String Hlp2, String Hlp3)
{
// set nonempty values
if (Hlp1.Length == 0)
Hlp1 = "_no_value_at_all";
if (Hlp2.Length == 0)
Hlp2 = "_no_value_whatsoever";
if (Hlp3.Length == 0)
Hlp3 = "_no_value_here";
XmlDocument doc = GetUserDoc();
if (doc == null)
return null;
XmlElement new_user = doc.CreateElement("user");
new_user.SetAttribute("name", Name.Trim());
new_user.SetAttribute("pwd", Pwd.Trim());
new_user.SetAttribute("tag1", Hlp1.Trim());
new_user.SetAttribute("tag2", Hlp2.Trim());
new_user.SetAttribute("tag3", Hlp3.Trim());
doc.DocumentElement.AppendChild(new_user);
SetUserDoc(doc);
return "ok";
}
}
Cookies
Løsnongen setter en cookie når brukeren er godkjent og fjerner den samme cookien når brukeren logger ut. Koden for å sette cookie er slik, fra Default.aspx.cs:
protected void setCookie(String name)
{
HttpCookie cook = new HttpCookie("user");
cook["Navn"] = name;
Response.Cookies.Add(cook);
}
Koden for å fjerne samme cookie er slik, også fra Default.aspx.cs:
protected void killCookie()
{
HttpCookie cook = new HttpCookie("user");
cook.Expires = DateTime.Now.AddDays(-1d);
Response.Cookies.Add(cook);
}
Inputkontroll
Løsningen har en rudimentær inputkontroll på tjeneren. Det vil være en klar forbedring å legge en bedre inputkontroll på klientsiden.