diff options
author | Jonathan Pryor <jpryor@novell.com> | 2008-10-28 21:23:25 +0300 |
---|---|---|
committer | Jonathan Pryor <jpryor@novell.com> | 2008-10-28 21:23:25 +0300 |
commit | 80d024f43118ef33488869563e2b724c54cd48b2 (patch) | |
tree | 063b026c360b7aaf8b370dc7ef16a5fc2dd753b1 /webdoc | |
parent | 65434f80c133fbdc1e5b155187377ba39eccb8f1 (diff) |
migration
svn path=/trunk/mono-tools/; revision=117284
Diffstat (limited to 'webdoc')
-rw-r--r-- | webdoc/server.cs | 366 |
1 files changed, 366 insertions, 0 deletions
diff --git a/webdoc/server.cs b/webdoc/server.cs new file mode 100644 index 00000000..d026cb22 --- /dev/null +++ b/webdoc/server.cs @@ -0,0 +1,366 @@ +// +// Monodoc server +// +// Author: +// Miguel de Icaza (miguel@ximian.com) +// + +using System; +using System.Collections; +using System.IO; +using System.Web.Mail; +using System.Web.Services; +using System.Web.Services.Protocols; +using System.Data; +using ByteFX.Data.MySqlClient; +using System.Xml; + +namespace Monodoc { + [WebServiceAttribute (Description="Web service for the MonoDoc contribution system")] + public class Contributions : System.Web.Services.WebService + { + const string basedir = "/home/contributions/"; + //const string basedir = "/tmp/contributions/"; + static string connection_string; + + static Contributions () + { + using (StreamReader sr = new StreamReader (File.OpenRead ("connection.string"))){ + connection_string = sr.ReadLine (); + Console.WriteLine ("Connection: " + connection_string); + } + } + + private IDbConnection GetConnection() + { + return new MySqlConnection(connection_string); + } + + private MySqlParameter CreateParameter(string name, object value) + { + return new MySqlParameter (name, value); + } + + static void mail (string recipient, string body) + { + MailMessage m = new MailMessage (); + m.From = "mono-docs-list@ximian.com"; + m.To = recipient; + m.Subject = "Your Monodoc passkey"; + m.Body = String.Format ("\n\nWelcome to the Mono Documentation Effort,\n\n" + + "This is your passkey for contributing to the Mono Documentation effort:\n " + + " {0}\n\n" + + "The Mono Documentation Team (mono-docs-list@ximian.com)", body); + + SmtpMail.SmtpServer = "localhost"; + SmtpMail.Send (m); + } + + // + // 0 => OK to send contributions. + // -1 => Invalid version + // + [WebMethod(Description="Check the client/server version; 0 means that the server can consume your data")] + public int CheckVersion (int version) + { + if (version == 1) + return 0; + return -1; + } + + // + // Return codes: + // -3 invalid characters in login + // -2 Login already registered, password resent. + // -1 Generic error + // 0 password mailed + // + [WebMethod(Description="Requests a registration for a login")] + public int Register (string login) + { + if (login.IndexOf ("'") != -1) + return -3; + + IDbConnection conn = GetConnection(); + conn.Open(); + try + { + IDbCommand cmd = conn.CreateCommand(); + cmd.CommandText = "select password from person where name=@login"; + cmd.Parameters.Add( CreateParameter("@login", login)); + IDataReader reader = cmd.ExecuteReader (); + + if (reader.Read ()){ + string password = (string) reader ["password"]; + mail (login, password); + reader.Close (); + return -2; + } + reader.Close (); + Random rnd = new Random (); + int pass = rnd.Next (); + cmd.CommandText = "INSERT INTO person (name, password, last_serial) VALUES " + + "(@name, @password, 0)"; + cmd.Parameters.Add( CreateParameter("@name",login)); + cmd.Parameters.Add( CreateParameter("@password",pass)); + + cmd.ExecuteNonQuery (); + mail (login, pass.ToString ()); + + return 0; + } catch (Exception e) { + Console.Error.WriteLine (e); + } finally { + conn.Close (); + } + return -1; + } + + [WebMethod (Description="Returns the latest serial number used for a change on the server")] + public int GetSerial (string login, string password) + { + IDbConnection conn = GetConnection(); + conn.Open(); + try + { + IDbCommand cmd = conn.CreateCommand(); + cmd.CommandText = "select last_serial from person where name=@login and password=@password"; + cmd.Parameters.Add( CreateParameter("@login", login)); + cmd.Parameters.Add( CreateParameter("@password", password)); + + object r = cmd.ExecuteScalar(); + if (r != null){ + Console.Error.WriteLine (r); + return (int) r; + } + return -1; + } catch (Exception e){ + Console.Error.WriteLine ("Exception" + e); + } finally { + conn.Close(); + } + return -1; + } + + // -1 Generic error. + // -2 Erroneous XML + int a=1; + [WebMethod (Description="Submits a GlobalChangeSet as a contribution")] + public int Submit (string login, string password, XmlNode node) + { + IDbConnection conn = GetConnection(); + conn.Open(); + try { + IDbCommand cmd = conn.CreateCommand(); + cmd.CommandText = "select * from person where name=@login and password=@password"; + cmd.Parameters.Add( CreateParameter("@login", login)); + cmd.Parameters.Add( CreateParameter("@password", password)); + + IDataReader reader = cmd.ExecuteReader (); + + int ret_val = -1; + + if (reader.Read()){ + int id = (int)reader["person_id"]; + int serial = (int)reader["last_serial"]; + reader.Close (); + + // + // Validate the XML + // + XmlDocument d = new XmlDocument (); + d.AppendChild (d.ImportNode (node, true)); + XmlNodeReader r = new XmlNodeReader (d); + try { + object rr = GlobalChangeset.serializer.Deserialize (r); + } catch { + return -2; + } + + string dudebase = basedir + id; + Directory.CreateDirectory (dudebase); + + d.Save (dudebase + "/" + serial + ".xml"); + IDbTransaction txn = conn.BeginTransaction(); + try { + cmd.CommandText = "UPDATE person SET last_serial=@last_serial WHERE name=@name AND password=@pwd"; + cmd.Parameters.Add( CreateParameter("@last_serial", serial+1)); + cmd.Parameters.Add( CreateParameter("@name", login)); + cmd.Parameters.Add( CreateParameter("@pwd", password)); + cmd.ExecuteNonQuery (); + + + cmd.CommandText = "INSERT INTO status (person_id, serial, status) VALUES (@id, @serial, 0)"; + cmd.Parameters.Add( CreateParameter("@id",id)); + cmd.Parameters.Add( CreateParameter("@serial",serial)); + cmd.ExecuteNonQuery (); + + txn.Commit(); + } catch (Exception e) { + Console.Error.WriteLine ("E: " + e); + } + + ret_val = serial+1; + return ret_val; + } + Console.Error.WriteLine ("Error, going: 4"); + return -4; + } catch (Exception e) { + Console.Error.WriteLine ("Failure in Submit: " + e); + return -3; + } finally { + conn.Close (); + } + } + + bool IsAdmin (IDbConnection conn, string login, string password) + { + IDbCommand cmd = conn.CreateCommand(); + cmd.CommandText = "select person_id,is_admin from person where name=@name and password=@pass"; + cmd.Parameters.Add( CreateParameter("@name",login)); + cmd.Parameters.Add( CreateParameter("@pass",password)); + + int person_id = -1; + bool is_admin = false; + using (IDataReader reader = cmd.ExecuteReader ()){ + if (reader.Read ()){ + person_id = (int) reader ["person_id"]; + is_admin = ((int) reader ["is_admin"]) == 1; + } else + return false; + } + if (person_id == -1 || is_admin == false) + return false; + + return true; + } + + [WebMethod (Description="Obtains the list of pending contributions")] + public PendingChange [] GetPendingChanges (string login, string password) + { + IDbConnection conn = GetConnection(); + conn.Open (); + + try { + if (!IsAdmin (conn, login, password)){ + return new PendingChange [0]; + } + + IDbCommand cmd = conn.CreateCommand(); + ArrayList results = new ArrayList (); + cmd.CommandText = "select status.person_id, serial, person.name from status, person where status=0 and person.person_id = status.person_id"; + using (IDataReader reader = cmd.ExecuteReader ()){ + while (reader.Read ()){ + results.Add (new PendingChange ((string) reader ["name"], (int) reader ["person_id"], (int) reader ["serial"])); + } + } + + PendingChange [] ret = new PendingChange [results.Count]; + results.CopyTo (ret); + return ret; + } catch (Exception e){ + Console.Error.WriteLine (e); + return null; + } finally { + conn.Close (); + } + } + + [WebMethod (Description="Obtains a change set for a user")] + public XmlNode FetchContribution (string login, string password, int person_id, int serial) + { + IDbConnection conn = GetConnection (); + conn.Open (); + try { + if (!IsAdmin (conn, login, password)) + return null; + + XmlDocument d = new XmlDocument (); + string fname = basedir + person_id + "/" + serial + ".xml"; + d.Load (fname); + return d.FirstChild; + } finally { + conn.Close (); + } + } + + [WebMethod (Description="ADMIN: Obtains the number of pending commits")] + public Status GetStatus (string login, string password) + { + IDbConnection conn = GetConnection (); + conn.Open (); + try { + IDbCommand cmd = conn.CreateCommand(); + cmd.CommandText = "select * from person where name=@name and password=@pass"; + cmd.Parameters.Add( CreateParameter("@name",login)); + cmd.Parameters.Add( CreateParameter("@pass",password)); + + IDataReader reader = cmd.ExecuteReader (); + int id = -1; + + if (reader.Read()) + id = (int)reader["person_id"]; + reader.Close (); + if (id == -1) + return null; + + Status s = new Status (); + + cmd.CommandText = String.Format ("select count(*) from status where person_id='{0}'", id); + s.Contributions = (int) cmd.ExecuteScalar (); + cmd.CommandText = String.Format ("select count(*) from status where person_id='{0}' and status='0'", id); + s.Pending = (int) cmd.ExecuteScalar (); + cmd.CommandText = String.Format ("select count(*) from status where person_id='{0}' and status='1'", id); + s.Commited = (int) cmd.ExecuteScalar (); + + return s; + } finally { + conn.Close (); + } + } + + [WebMethod (Description="ADMIN: Updates the status of a contribution")] + public void UpdateStatus (string login, string password, int person_id, int contrib_id, int status) + { + IDbConnection conn = GetConnection(); + conn.Open (); + + try { + if (!IsAdmin (conn, login, password)) + return; + + IDbCommand cmd = conn.CreateCommand(); + cmd.CommandText = "update status set status=@status WHERE person_id=@PID AND serial=@ser"; + cmd.Parameters.Add (CreateParameter ("@status", status)); + cmd.Parameters.Add (CreateParameter ("@PID", person_id)); + cmd.Parameters.Add (CreateParameter ("@ser", contrib_id)); + cmd.ExecuteNonQuery (); + } finally { + conn.Close (); + } + } + } + + public class Status { + public int Contributions; + public int Commited; + public int Pending; + } + + public class PendingChange { + public string Login; + public int ID; + public int Serial; + + public PendingChange (string login, int person_id, int serial) + { + Login = login; + ID = person_id; + Serial = serial; + } + + public PendingChange () + { + } + } +} |