adds access by circle to blog posts

main
Paul Schneider 11 years ago
parent 9da7064791
commit f25aa8ff97
32 changed files with 465 additions and 274 deletions

@ -1,3 +1,8 @@
2015-07-02 Paul Schneider <paul@pschneider.fr>
* NpgsqlBlogProvider.cs:
* NpgsqlBlogProvider.csproj:
2015-06-09 Paul Schneider <paul@pschneider.fr>
* NpgsqlBlogProvider.csproj: Helps to fix packaging, and

@ -4,6 +4,8 @@ using System.Configuration.Provider;
using Npgsql;
using System.Collections.Generic;
using Yavsc.Model.Blogs;
using Yavsc.Model.Circles;
using System.Web.Mvc;
namespace Npgsql.Web.Blog
{
@ -28,6 +30,7 @@ namespace Npgsql.Web.Blog
cmd.CommandText = "insert into bltag (blid,tag) values (@postid,@tag) returning _id";
cmd.Parameters.AddWithValue("@tag",tag);
cmd.Parameters.AddWithValue("@postid",postid);
cnx.Open ();
return (long) cmd.ExecuteScalar ();
}
}
@ -41,20 +44,11 @@ namespace Npgsql.Web.Blog
using (NpgsqlCommand cmd = cnx.CreateCommand ()) {
cmd.CommandText = "delete from bltag where _id = @tagid";
cmd.Parameters.AddWithValue("@tagid",tagid);
cnx.Open ();
cmd.ExecuteNonQuery ();
}
}
/// <summary>
/// Gets the post identifier.
/// </summary>
/// <returns>The post identifier.</returns>
/// <param name="username">Username.</param>
/// <param name="title">Title.</param>
public override long GetPostId (string username, string title)
{
throw new NotImplementedException ();
}
/// <summary>
/// Gets the comments.
/// </summary>
/// <returns>The comments.</returns>
@ -97,10 +91,12 @@ namespace Npgsql.Web.Blog
/// <param name="title">Title.</param>
/// <param name="content">Content.</param>
/// <param name="visible">If set to <c>true</c> visible.</param>
public override void UpdatePost (long postid, string title, string content, bool visible)
/// <param name="cids">Circle identifiers</param>
public override void UpdatePost (long postid, string title, string content,
bool visible, long [] cids)
{
using (NpgsqlConnection cnx = new NpgsqlConnection(connectionString))
using (NpgsqlCommand cmd = cnx.CreateCommand()) {
using (NpgsqlConnection cnx = new NpgsqlConnection(connectionString)) {
using (NpgsqlCommand cmd = cnx.CreateCommand ()) {
DateTime now = DateTime.Now;
cmd.CommandText =
"update blog set modified=@now," +
@ -115,8 +111,10 @@ namespace Npgsql.Web.Blog
cmd.Parameters.AddWithValue ("@id", postid);
cnx.Open ();
cmd.ExecuteNonQuery ();
}
cnx.Close();
}
UpdatePostCircles (postid, cids);
}
/// <summary>
/// Removes the post.
@ -249,6 +247,7 @@ namespace Npgsql.Web.Blog
}
}
}
if (be!=null) SetCirclesOn (be);
return be;
}
/// <summary>
@ -280,10 +279,10 @@ namespace Npgsql.Web.Blog
using (NpgsqlConnection cnx=new NpgsqlConnection(connectionString))
using (NpgsqlCommand cmd = cnx.CreateCommand()) {
cmd.CommandText = "select _id,bcontent,modified,posted,visible from blog " +
"where applicationname = @appname and username = @username and title = @title";
cmd.Parameters.AddWithValue ("@appname", applicationName);
cmd.Parameters.AddWithValue ("@username", username);
cmd.Parameters.AddWithValue ("@title", title);
"where applicationname = :appname and username = :username and title = :title";
cmd.Parameters.AddWithValue ("appname", applicationName);
cmd.Parameters.AddWithValue ("username", username);
cmd.Parameters.AddWithValue ("title", title);
cnx.Open ();
using (NpgsqlDataReader rdr = cmd.ExecuteReader()) {
if (rdr.Read ()) {
@ -298,11 +297,11 @@ namespace Npgsql.Web.Blog
}
rdr.Close ();
}
if (be!=null)
using (NpgsqlCommand cmdtags = cnx.CreateCommand()) {
if (be != null) {
using (NpgsqlCommand cmdtags = cnx.CreateCommand ()) {
List<string> tags = new List<string> ();
cmd.CommandText = "select tag.name from tag,tagged where tag._id = tagged.tagid and tagged.postid = @pid";
cmd.Parameters.AddWithValue ("@pid", be.Id);
cmd.CommandText = "select tag.name from tag,tagged where tag._id = tagged.tagid and tagged.postid = :pid";
cmd.Parameters.AddWithValue ("pid", be.Id);
using (NpgsqlDataReader rdrt = cmd.ExecuteReader ()) {
while (rdrt.Read ()) {
tags.Add (rdrt.GetString (0));
@ -310,9 +309,29 @@ namespace Npgsql.Web.Blog
}
be.Tags = tags.ToArray ();
}
SetCirclesOn (be);
}
}
return be;
}
private void SetCirclesOn(BlogEntry be)
{
List<long> circles = new List<long> ();
using (NpgsqlConnection cnx=new NpgsqlConnection(connectionString))
using (NpgsqlCommand cmdcircles = cnx.CreateCommand ()) {
cmdcircles.CommandText = "select a.circle_id from blog_access a " +
"where a.post_id = :pid";
cmdcircles.Parameters.AddWithValue ("pid", be.Id);
cnx.Open ();
using (NpgsqlDataReader rdr = cmdcircles.ExecuteReader ()) {
while (rdr.Read ()) {
circles.Add ( rdr.GetInt64 (0) );
}
}
}
be.AllowedCircles = circles.ToArray();
}
/// <summary>
/// Post the specified username, title, content and visible.
/// </summary>
@ -320,59 +339,112 @@ namespace Npgsql.Web.Blog
/// <param name="title">Title.</param>
/// <param name="content">Content.</param>
/// <param name="visible">If set to <c>true</c> visible.</param>
public override long Post (string username, string title, string content, bool visible)
/// <param name="circles">.</param>
public override long Post (string username, string title, string content, bool visible, long [] circles)
{
long pid = 0;
if (username == null)
throw new ArgumentNullException("username");
if (title == null)
throw new ArgumentNullException("title");
if (content == null)
throw new ArgumentNullException("content");
using (NpgsqlConnection cnx=new NpgsqlConnection(connectionString))
using (NpgsqlCommand cmd = cnx.CreateCommand()) {
using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) {
using (NpgsqlCommand cmd = cnx.CreateCommand ()) {
cmd.CommandText = "insert into blog (title,bcontent,modified,posted,visible,username,applicationname)" +
"values (@title,@bcontent,@modified,@posted,@visible,@username,@appname) returning _id";
cmd.Parameters.AddWithValue ("@title", title);
cmd.Parameters.AddWithValue ("@bcontent", content);
"values (:title,:bcontent,:modified,:posted,:visible,:username,:appname) returning _id";
cmd.Parameters.AddWithValue ("title", title);
cmd.Parameters.AddWithValue ("bcontent", content);
DateTime now = DateTime.Now;
cmd.Parameters.AddWithValue ("@modified", now);
cmd.Parameters.AddWithValue ("@posted", now);
cmd.Parameters.AddWithValue ("@visible", visible);
cmd.Parameters.AddWithValue ("@username", username);
cmd.Parameters.AddWithValue ("@appname", applicationName);
cmd.Parameters.AddWithValue ("modified", now);
cmd.Parameters.AddWithValue ("posted", now);
cmd.Parameters.AddWithValue ("visible", visible);
cmd.Parameters.AddWithValue ("username", username);
cmd.Parameters.AddWithValue ("appname", applicationName);
cnx.Open ();
return (long) cmd.ExecuteScalar();
pid = (long)cmd.ExecuteScalar ();
}
cnx.Close ();
}
UpdatePostCircles (pid, circles);
return pid;
}
private void UpdatePostCircles( long pid, long[] circles)
{
using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString)) {
cnx.Open ();
using (NpgsqlCommand cmd = cnx.CreateCommand ()) {
cmd.CommandText = "delete from blog_access where post_id = :pid";
cmd.Parameters.AddWithValue ("pid", pid);
cmd.ExecuteNonQuery ();
}
if (circles!=null)
if (circles.Length>0)
using (NpgsqlCommand cmd = cnx.CreateCommand ()) {
cmd.CommandText = "insert into blog_access (post_id,circle_id) values (:pid,:cid)";
cmd.Parameters.AddWithValue ("pid", pid);
cmd.Parameters.Add ("cid", NpgsqlTypes.NpgsqlDbType.Bigint);
cmd.Prepare ();
foreach (long ci in circles) {
cmd.Parameters ["cid"].Value = ci;
cmd.ExecuteNonQuery ();
}
}
cnx.Close ();
}
}
/// <summary>
/// Finds the post.
/// </summary>
/// <returns>The post.</returns>
/// <param name="readersName">Reader's Name.</param>
/// <param name="pattern">Pattern.</param>
/// <param name="searchflags">Searchflags.</param>
/// <param name="pageIndex">Page index.</param>
/// <param name="pageSize">Page size.</param>
/// <param name="totalRecords">Total records.</param>
public override BlogEntryCollection FindPost (string pattern, FindBlogEntryFlags searchflags, int pageIndex, int pageSize, out int totalRecords)
public override BlogEntryCollection FindPost (string readersName, string pattern, FindBlogEntryFlags searchflags, int pageIndex, int pageSize, out int totalRecords)
{
BlogEntryCollection c = new BlogEntryCollection ();
totalRecords = 0;
using (NpgsqlConnection cnx=new NpgsqlConnection(connectionString))
using (NpgsqlCommand cmd = cnx.CreateCommand()) {
cmd.CommandText = "select title,bcontent,modified,posted,username,visible from blog " +
"where applicationname = @appname";
if (readersName != null) {
cmd.CommandText = "select _id, title,bcontent,modified," +
"posted,username,visible " +
"from blog b left outer join " +
"(select count(*)>0 acc, a.post_id pid " +
"from blog_access a," +
" circle_members m, users u where m.circle_id = a.circle_id " +
" and m.member = u.pkid and u.username = :uname " +
" and u.applicationname = :appname " +
" group by a.post_id) ma on (ma.pid = b._id) " +
"where ( ma.acc IS NULL or ma.acc = TRUE or b.UserName = :uname) ";
cmd.Parameters.AddWithValue ("uname", readersName);
} else {
cmd.CommandText = "select _id, title,bcontent,modified," +
"posted,username,visible " +
"from blog b left outer join " +
"(select count(*)>0 acc, a.post_id pid " +
"from blog_access a" +
" group by a.post_id) ma on (ma.pid = b._id)" +
" where " +
" ma.acc IS NULL and " +
" applicationname = :appname";
}
cmd.Parameters.AddWithValue ("@appname", applicationName);
if ((searchflags & FindBlogEntryFlags.MatchContent) > 0) {
cmd.CommandText += " and bcontent like @bcontent";
cmd.Parameters.AddWithValue ("@bcontent", pattern);
cmd.CommandText += " and bcontent like :bcontent";
cmd.Parameters.AddWithValue (":bcontent", pattern);
}
if ((searchflags & FindBlogEntryFlags.MatchTitle) > 0) {
cmd.CommandText += " and title like @title";
cmd.Parameters.AddWithValue ("@title", pattern);
cmd.CommandText += " and title like :title";
cmd.Parameters.AddWithValue (":title", pattern);
}
if ((searchflags & FindBlogEntryFlags.MatchUserName) > 0) {
cmd.CommandText += " and username like @username";
cmd.Parameters.AddWithValue ("@username", pattern);
cmd.CommandText += " and username like :username";
cmd.Parameters.AddWithValue (":username", pattern);
}
if ((searchflags & FindBlogEntryFlags.MatchInvisible) == 0) {
cmd.CommandText += " and visible = true";
@ -397,8 +469,12 @@ namespace Npgsql.Web.Blog
}
totalRecords++;
}
rdr.Close ();
}
}
foreach (BlogEntry be in c)
SetCirclesOn (be);
return c;
}
/// <summary>
@ -442,11 +518,11 @@ namespace Npgsql.Web.Blog
"where blog.posted = lblog.lpost and blog.username = lblog.username " ;
*/
cmd.CommandText = "select * " +
"from blog where applicationname = @appname and visible = true " +
" order by posted desc limit @len" ;
"from blog where applicationname = :appname and visible = true " +
" order by posted desc limit :len" ;
cmd.Parameters.AddWithValue ("@appname", applicationName);
cmd.Parameters.AddWithValue ("@len", defaultPageSize*10);
cmd.Parameters.AddWithValue ("appname", applicationName);
cmd.Parameters.AddWithValue ("len", defaultPageSize*10);
cnx.Open ();
using (NpgsqlDataReader rdr = cmd.ExecuteReader()) {
totalRecords = 0;
@ -467,6 +543,8 @@ namespace Npgsql.Web.Blog
}
}
}
foreach (BlogEntry be in c)
SetCirclesOn (be);
return c;
}
#endregion

@ -46,6 +46,7 @@
<Reference Include="Npgsql">
<HintPath>..\packages\Npgsql.2.2.5\lib\net45\Npgsql.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc" />
</ItemGroup>
<ProjectExtensions>
<MonoDevelop>

@ -1,3 +1,7 @@
2015-07-02 Paul Schneider <paul@pschneider.fr>
* NpgsqlCircleProvider.cs:
2015-06-18 Paul Schneider <paul@pschneider.fr>
* NpgsqlCircleProvider.cs: Fixes the Circle creation

@ -26,6 +26,8 @@ using Npgsql;
using NpgsqlTypes;
using System.Collections.Generic;
using System.Web.Security;
using System.Web.Mvc;
using Yavsc.Model;
namespace WorkFlowProvider
{
@ -43,6 +45,31 @@ namespace WorkFlowProvider
#region implemented abstract members of CircleProvider
/// <summary>
/// Returns circles from owner.
/// </summary>
/// <param name="circle_ids">Circle identifiers.</param>
/// <param name="member">Member name.</param>
public override bool Matches (long [] circle_ids, string member)
{
bool result=false;
using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString))
using (NpgsqlCommand cmd = cnx.CreateCommand ()) {
cmd.CommandText = "select count(*)>0 from circle_members where _id = :cid and m.member = :mbr";
cmd.Parameters.Add("cid",NpgsqlDbType.Bigint);
cmd.Parameters.AddWithValue("mbr",member);
cnx.Open ();
cmd.Prepare ();
foreach (long cid in circle_ids) {
result = (bool) cmd.ExecuteScalar();
if (result)
break;
}
cnx.Close ();
}
return result;
}
/// <summary>
/// Add the specified user.
/// </summary>
@ -148,6 +175,7 @@ namespace WorkFlowProvider
cmd.Parameters.AddWithValue ("cid", id);
cmd.Parameters.Add ("mbr", NpgsqlDbType.Varchar);
cmd.Prepare ();
if (users!=null)
foreach (string user in users) {
object pkid = Membership.GetUser (user).ProviderUserKey;
cmd.Parameters[1].Value = pkid.ToString();
@ -179,9 +207,9 @@ namespace WorkFlowProvider
/// List user's circles.
/// </summary>
/// <param name="user">User.</param>
public override CircleInfoCollection List (string user)
public override IEnumerable<ListItem> List (string user)
{
CircleInfoCollection cc = null;
List<ListItem> cc = null;
using (NpgsqlConnection cnx = new NpgsqlConnection (connectionString))
using (NpgsqlCommand cmd = cnx.CreateCommand ()) {
cmd.CommandText = "select _id, title from circle where owner = :wnr";
@ -190,7 +218,7 @@ namespace WorkFlowProvider
cmd.Prepare ();
using (NpgsqlDataReader rdr = cmd.ExecuteReader ()) {
if (rdr.HasRows) {
cc = new CircleInfoCollection ();
cc = new List<ListItem> ();
while (rdr.Read ()) {
string title = null;
int ottl = rdr.GetOrdinal ("title");
@ -198,7 +226,7 @@ namespace WorkFlowProvider
title = rdr.GetString (ottl);
long id = (long) rdr.GetInt64 (
rdr.GetOrdinal ("_id"));
cc.Add (new CircleInfo (id,title));
cc.Add (new ListItem { Value = id.ToString(), Text = title} );
}
}
rdr.Close ();

@ -1,3 +1,8 @@
2015-07-02 Paul Schneider <paul@pschneider.fr>
* UserCard.cs:
* InputCircle.cs:
2015-06-10 Paul Schneider <paul@pschneider.fr>
* InputCircle.cs: An input control specialized for circle

@ -26,8 +26,11 @@ using System.ComponentModel;
using System.Web.UI.WebControls;
using Yavsc.Model.Circles;
using System.Web.Security;
using System.Collections;
using System.Collections.Generic;
using System.Web.Mvc;
namespace WebControls
namespace Yavsc.WebControls
{
/// <summary>
/// Input circle.
@ -63,13 +66,21 @@ namespace WebControls
}
}
/// <summary>
/// Gets or sets the value.
/// Gets or sets the The CircleInfo collection.
/// </summary>
/// <value>The value.</value>
[Bindable (true), DefaultValue(""), Localizable(true)]
public string Value {
[Bindable (true), DefaultValue(null), Localizable(true),
Category("Behavior"),
Description("The CircleInfo collection"),
DesignerSerializationVisibility(
DesignerSerializationVisibility.Content),
PersistenceMode(PersistenceMode.InnerDefaultProperty)
]
public IEnumerable<SelectListItem> Value {
get {
return (string) ViewState["Value"];
if (ViewState ["Value"] == null)
ViewState ["Value"] = new List<SelectListItem> ();
return (IEnumerable<SelectListItem>) ViewState["Value"];
}
set {
ViewState ["Value"] = value;
@ -134,10 +145,7 @@ namespace WebControls
if (Multiple)
writer.AddAttribute ("multiple","true");
writer.RenderBeginTag ("select");
string[] selected = null;
if (!string.IsNullOrWhiteSpace (Value)) {
selected = Value.Split (',');
}
if (EmptyValue!=null) {
writer.AddAttribute ("value", "");
writer.RenderBeginTag ("option");
@ -146,13 +154,15 @@ namespace WebControls
}
var u = Membership.GetUser ();
if (u != null) {
foreach (CircleInfo ci in CircleManager.DefaultProvider.List(u.UserName)) {
if (selected != null)
if (Array.Exists (selected, x => x == ci.Id.ToString ()))
foreach (Yavsc.Model.ListItem ci in CircleManager.DefaultProvider.List(u.UserName)) {
foreach (SelectListItem sli in Value)
if (sli.Value == ci.Value) {
writer.AddAttribute ("selected", null);
writer.AddAttribute ("value", ci.Id.ToString ());
break;
}
writer.AddAttribute ("value", ci.Value );
writer.RenderBeginTag ("option");
writer.Write (ci.Title);
writer.Write (ci.Text);
writer.RenderEndTag ();
}
}

@ -26,8 +26,11 @@ using System.Web.UI;
using System.ComponentModel;
using System.Web.Security;
namespace WebControls
namespace Yavsc.WebControls
{
/// <summary>
/// User card.
/// </summary>
[
AspNetHostingPermission (SecurityAction.Demand,
Level = AspNetHostingPermissionLevel.Minimal),
@ -37,9 +40,6 @@ namespace WebControls
DefaultProperty ("Name"),
ToolboxData ("<{0}:UserCard runat=\"server\"> </{0}:UserCard>")
]
/// <summary>
/// User card.
/// </summary>
public class UserCard: WebControl
{
/// <summary>

@ -24,6 +24,8 @@ using Yavsc.Model.RolesAndMembers;
using System.Collections.Generic;
using Yavsc.Model.Circles;
using System.Web.Security;
using System.Collections.Specialized;
using Yavsc.Model;
namespace Yavsc.ApiControllers
{
@ -91,12 +93,11 @@ namespace Yavsc.ApiControllers
return c;
}
/// <summary>
/// List the circles
/// </summary>
[Authorize]
public CircleInfoCollection List()
public IEnumerable<ListItem> List()
{
string user = Membership.GetUser ().UserName;
return CircleManager.DefaultProvider.List (user);

@ -1,3 +1,20 @@
2015-07-02 Paul Schneider <paul@pschneider.fr>
* Web.csproj:
* Web.config:
* instdbws.sql:
* Web.config:
* Edit.aspx:
* YavscHelpers.cs:
* ThanksHelper.cs:
* Circles.aspx:
* BlogsController.cs:
* TitleNotFound.aspx:
* NotAuthorized.aspx:
* TexToPdfFormatter.cs:
* AccountController.cs:
* CircleController.cs:
2015-06-28 Paul Schneider <paul@pschneider.fr>
* AccountController.cs: Fixes the canonical login

@ -309,10 +309,8 @@ namespace Yavsc.Controllers
public ActionResult Circles ()
{
string user = Membership.GetUser ().UserName;
CircleInfoCollection cic = CircleManager.DefaultProvider.List (user);
if (cic == null)
cic = new CircleInfoCollection ();
return View (cic);
ViewData["Circles"] = CircleManager.DefaultProvider.List (user);
return View ();
}
/// <summary>
/// Logout the specified returnUrl.

@ -17,6 +17,7 @@ using Yavsc.ApiControllers;
using Yavsc.Model.RolesAndMembers;
using System.Net;
using System.Web.Mvc;
using Yavsc.Model.Circles;
namespace Yavsc.Controllers
{
@ -94,9 +95,6 @@ namespace Yavsc.Controllers
return View ("Index", bs);
}
// page index becomes one-based
/// <summary>
/// Users the posts.
/// </summary>
@ -112,12 +110,15 @@ namespace Yavsc.Controllers
FindBlogEntryFlags sf = FindBlogEntryFlags.MatchUserName;
ViewData ["SiteName"] = sitename;
ViewData ["BlogUser"] = user;
string readersName = null;
// displays invisible items when the logged user is also the author
if (u != null)
if (u.UserName == user)
if (u != null) {
if (u.UserName == user || Roles.IsUserInRole ("Admin"))
sf |= FindBlogEntryFlags.MatchInvisible;
readersName = u.UserName;
}
// find entries
BlogEntryCollection c = BlogManager.FindPost (user, sf, pageIndex, pageSize, out tr);
BlogEntryCollection c = BlogManager.FindPost (readersName, user, sf, pageIndex, pageSize, out tr);
// Get author's meta data
Profile bupr = new Profile (ProfileBase.Create (user));
ViewData ["BlogUserProfile"] = bupr;
@ -155,7 +156,7 @@ namespace Yavsc.Controllers
return View ("TitleNotFound");
Profile pr = new Profile (ProfileBase.Create (e.UserName));
if (pr==null)
return View ("TitleNotFound");
return View ("NotAuthorized");
ViewData ["BlogUserProfile"] = pr;
ViewData ["BlogTitle"] = pr.BlogTitle;
ViewData ["Avatar"] = pr.avatar;
@ -163,17 +164,33 @@ namespace Yavsc.Controllers
if (u != null)
ViewData ["UserName"] = u.UserName;
if (!e.Visible || !pr.BlogVisible) {
if (u==null)
return View ("TitleNotFound");
// only deliver to admins or owner
if (u == null)
return View ("NotAuthorized");
else {
if (u.UserName!=e.UserName)
if (!Roles.IsUserInRole(u.UserName,"Admin"))
return View ("TitleNotFound");
if (u.UserName != e.UserName)
if (!Roles.IsUserInRole (u.UserName, "Admin"))
return View ("NotAuthorized");
}
} else {
if (!CanViewPost(e,u))
return View ("NotAuthorized");
}
ViewData ["Comments"] = BlogManager.GetComments (e.Id);
return View ("UserPost", e);
}
private bool CanViewPost (BlogEntry e, MembershipUser u=null) {
if (e.AllowedCircles!=null && e.AllowedCircles.Length > 0) {
// only deliver to admins, owner, or specified circle memebers
if (u == null)
return false;
if (u.UserName != e.UserName)
if (!Roles.IsUserInRole (u.UserName, "Admin"))
if (!CircleManager.DefaultProvider.Matches (e.AllowedCircles, u.UserName))
return false;
}
return true;
}
/// <summary>
/// Users the post.
/// </summary>
@ -208,26 +225,14 @@ namespace Yavsc.Controllers
if (String.IsNullOrEmpty (title))
title = "";
ViewData ["UserName"] = un;
ViewData["AllowedCircles"] = CircleManager.DefaultProvider.List (Membership.GetUser ().UserName).Select (x => new SelectListItem {
Value = x.Value,
Text = x.Text
});
return View ("Edit", new BlogEntry { Title = title });
}
/// <summary>
/// Validates the post.
/// </summary>
/// <returns>The post.</returns>
/// <param name="model">Model.</param>
[Authorize,
ValidateInput(false)]
public ActionResult ValidatePost (BlogEntry model)
{
string username = Membership.GetUser ().UserName;
ViewData ["SiteName"] = sitename;
ViewData ["BlogUser"] = username;
if (ModelState.IsValid) {
BlogManager.Post (username, model.Title, model.Content, model.Visible);
return UserPost (username, model.Title);
}
return View ("Post", model);
}
/// <summary>
/// Validates the edit.
/// </summary>
@ -241,13 +246,14 @@ namespace Yavsc.Controllers
ViewData ["BlogUser"] = Membership.GetUser ().UserName;
if (ModelState.IsValid) {
if (model.Id != 0)
BlogManager.UpdatePost (model.Id, model.Title, model.Content, model.Visible);
BlogManager.UpdatePost (model.Id, model.Title, model.Content, model.Visible, model.AllowedCircles);
else
BlogManager.Post (model.UserName, model.Title, model.Content, model.Visible);
return UserPost(model.UserName, model.Title);
model.Id = BlogManager.Post (model.UserName, model.Title, model.Content, model.Visible, model.AllowedCircles);
return RedirectToAction ("UserPost",new { user = model.UserName, title = model.Title });
}
return View ("Edit", model);
}
/// <summary>
/// Edit the specified model.
/// </summary>
@ -256,7 +262,6 @@ namespace Yavsc.Controllers
ValidateInput(false)]
public ActionResult Edit (BlogEntry model)
{
if (model != null) {
string user = Membership.GetUser ().UserName;
Profile pr = new Profile (HttpContext.Profile);
@ -268,13 +273,22 @@ namespace Yavsc.Controllers
BlogEntry e = BlogManager.GetPost (model.UserName, model.Title);
if (e != null) {
if (e.UserName != user) {
return View ("TitleNotFound");
return View ("NotAuthorized");
}
model = e;
ModelState.Clear ();
TryValidateModel (model);
}
}
if (model.AllowedCircles==null)
model.AllowedCircles = new long[0];
ViewData["AllowedCircles"] = CircleManager.DefaultProvider.List (Membership.GetUser ().UserName).Select (x => new SelectListItem {
Value = x.Value,
Text = x.Text,
Selected = model.AllowedCircles.Contains(long.Parse(x.Value))
});
return View (model);
}

@ -113,6 +113,11 @@ namespace Yavsc.Formatters
SetFileName(contentHeaders, value.GetHashCode ().ToString ());
}
/// <summary>
/// Sets the name of the file.
/// </summary>
/// <param name="contentHeaders">Content headers.</param>
/// <param name="basename">Basename.</param>
public static void SetFileName(HttpContentHeaders contentHeaders, string basename) {
contentHeaders.ContentDisposition = new ContentDispositionHeaderValue ("attachment") {
FileName = "doc-" + basename + ".pdf"

@ -2,6 +2,8 @@ using System;
using System.Configuration;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Linq.Expressions;
using Yavsc.Model.Circles;
namespace Yavsc.Helpers
{
@ -55,6 +57,7 @@ namespace Yavsc.Helpers
result.Add( new Link { Url = e.Url, Image=e.Image, Text = e.Name });
return result.ToArray();
}
}
}

@ -9,6 +9,10 @@ using System.Web.Http.ModelBinding;
using Yavsc.Model.RolesAndMembers;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Web.Mvc;
using Yavsc.Model.Circles;
using System.Web.UI;
using System.Linq.Expressions;
namespace Yavsc.Helpers
{
@ -17,9 +21,6 @@ namespace Yavsc.Helpers
/// </summary>
public static class YavscHelpers
{
private static string siteName = null;
/// <summary>
/// Gets the name of the site.

@ -1,4 +1,4 @@
<%@ Page Title="Circles" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage<Yavsc.Model.Circles.CircleInfoCollection>" %>
<%@ Page Title="Circles" Language="C#" MasterPageFile="~/Models/App.master" Inherits="System.Web.Mvc.ViewPage" %>
<%@ Register Assembly="Yavsc.WebControls" TagPrefix="yavsc" Namespace="Yavsc.WebControls" %>
<asp:Content ID="headContent" ContentPlaceHolderID="head" runat="server">
<script type="text/javascript" src="<%=Url.Content("~/Scripts/stupidtable.js")%>"></script>
@ -13,9 +13,9 @@
</thead>
<tbody id="tbcb">
<% int lc=0;
foreach (CircleInfo ci in Model) { lc++; %>
<tr class="<%= (ci.Id%2==0)?"even ":"odd " %>row" id="c_<%=ci.Id%>">
<td><%=ci.Title%></td>
foreach (SelectListItem ci in ViewData["Circles"]) { lc++; %>
<tr class="<%= (lc%2==0)?"even ":"odd " %>row" id="c_<%=ci.Value%>">
<td><%=ci.Text%></td>
<td>
<input type="button" value="<%=Html.Translate("Remove")%>" class="actionlink rowbtnrm"/>
<input type="button" value="<%=Html.Translate("Members")%>" class="actionlink rowbtnvw"/>

@ -1,4 +1,5 @@
<%@ Page Title="Bill edition" Language="C#" Inherits="System.Web.Mvc.ViewPage<BlogEntry>" MasterPageFile="~/Models/App.master" %>
<%@ Register Assembly="Yavsc.WebControls" TagPrefix="yavsc" Namespace="Yavsc.WebControls" %>
<asp:Content ContentPlaceHolderID="head" ID="HeadContent1" runat="server">
<link rel="stylesheet" href="<%=Url.Content("~/Theme/mdd_styles.css")%>">
<script type="text/javascript" src="<%=Url.Content("~/Scripts/MarkdownDeepLib.min.js")%>">
@ -26,15 +27,26 @@
<br/>
<%= Html.CheckBox( "Visible" ) %>
<%= Html.LabelFor(model => model.Visible) %>
<%= Html.ValidationMessage("Visible", "*") %>
<%= Html.Hidden("Id") %>
<%= Html.Hidden("UserName") %>
<br/>
<%= Html.LabelFor(model => model.AllowedCircles) %>
<%= Html.ListBox("AllowedCircles") %>
<%= Html.ValidationMessage("AllowedCircles", "*") %>
<%= Html.Hidden("Id") %>
<%= Html.Hidden("UserName") %>
<br/>
<input type="submit"/>
<% } %>
<script>
$(document).ready(function () {
$("textarea.mdd_editor").MarkdownDeep({
help_location: "/Scripts/html/mdd_help.htm",

@ -0,0 +1,4 @@
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<BlogEntryCollection>" MasterPageFile="~/Models/App.master"%>
<asp:Content ContentPlaceHolderID="MainContent" ID="MainContentContent" runat="server">
Ce contenu est d'accès restreint : &lt;<%= Html.Encode(ViewData["BlogUser"]) %>/<%= Html.Encode(ViewData["PostTitle"]) %>&gt;
</asp:Content>

@ -1,8 +1,5 @@
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<BlogEntryCollection>" MasterPageFile="~/Models/App.master"%>
<asp:Content ContentPlaceHolderID="MainContent" ID="MainContentContent" runat="server">
Pas d'article trouvé ici: &lt;<%= Html.Encode(ViewData["BlogUser"]) %>/<%= Html.Encode(ViewData["PostTitle"]) %>&gt;
<br/>
<%= Html.ActionLink("Poster?","Post/", new { user = ViewData["BlogUser"], title = ViewData["PostTitle"]}, new { @class="actionlink" }) %>
</asp:Content>
Pas d'article trouvé ici: &lt;<%= Html.Encode(ViewData["BlogUser"]) %>/<%= Html.Encode(ViewData["PostTitle"]) %>&gt;
<br/> <%= Html.ActionLink("Poster?","Post/", new { user = ViewData["BlogUser"], title = ViewData["PostTitle"]}, new { @class="actionlink" }) %>
</asp:Content>

@ -36,7 +36,7 @@
<system.webServer>
<defaultDocument enabled="true"> <!-- this line enables default documents for a directory -->
<files>
<clear/> <!-- removes the existing default document list -->
<!-- <clear/> removes the existing default document list -->
<add value="Index"/>
</files>
</defaultDocument>

@ -36,7 +36,7 @@ http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx
affects performance, set this value to true only
during development.
-->
<compilation defaultLanguage="C#" debug="true" batch="false">
<compilation defaultLanguage="C#" debug="true" >
<assemblies>
<add assembly="System.Configuration.Install, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<add assembly="System.Web.Http.WebHost, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
@ -185,14 +185,6 @@ http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx
<add name="Npgsql Data Provider" invariant="Npgsql" support="FF" description=".Net Framework Data Provider for Postgresql Server" type="Npgsql.NpgsqlFactory, Npgsql" />
</DbProviderFactories>
</system.data>
<system.diagnostics>
<trace autoflush="false" indentsize="4">
<listeners>
<remove name="Default" />
<add name="Default" type="System.Diagnostics.TextWriterTraceListener" initializeData="TextWriterOutput.log" />
</listeners>
</trace>
</system.diagnostics>
<catalog defaultProvider="XmlCatalogProvider">
<providers>
<add name="XmlCatalogProvider" connection="~/Catalog.xml" applicationName="/" type="SalesCatalog.XmlImplementation.XmlCatalogProvider, SalesCatalog" />
@ -255,6 +247,7 @@ http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx
<add name="yavsc" connectionString="Server=127.0.0.1;Port=5432;Database=YavscDev;User Id=yavscdev;Password=admin;Encoding=Unicode;" providerName="Npgsql" />
</connectionStrings>
<appSettings>
<add key="MonoServerDefaultIndexFiles" value="index.html,Index.aspx" />
<add key="WorkflowContentProviderClass" value="yavsc.NpgsqlContentProvider" />
<add key="SmtpServer" value="smtp.free.fr" />
<add key="AdminEMail" value="paulschneider@free.fr" />

@ -348,6 +348,7 @@
<Content Include="Views\Account\Circles.aspx" />
<Content Include="Views\Account\Register.ascx" />
<Content Include="Views\Account\ResetPassword.aspx" />
<Content Include="Views\Blogs\NotAuthorized.aspx" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />

@ -667,8 +667,7 @@ CREATE TABLE circle
WITH (
OIDS=FALSE
);
ALTER TABLE circle
OWNER TO yavscdev;
COMMENT ON COLUMN circle._id IS 'Circle identifier';
COMMENT ON COLUMN circle.owner IS 'creator of this circle';
COMMENT ON COLUMN circle.applicationname IS 'Application name';
@ -709,5 +708,23 @@ WITH (
);
-- Table: blog_access
-- DROP TABLE blog_access;
CREATE TABLE blog_access
(
post_id bigint NOT NULL,
circle_id bigint NOT NULL,
CONSTRAINT blog_access_pkey PRIMARY KEY (post_id, circle_id),
CONSTRAINT blog_access_circle_id_fkey FOREIGN KEY (circle_id)
REFERENCES circle (_id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT blog_access_post_id_fkey FOREIGN KEY (post_id)
REFERENCES blog (_id) MATCH SIMPLE
ON UPDATE CASCADE ON DELETE CASCADE
)
WITH (
OIDS=FALSE
);

@ -2,6 +2,8 @@ using System;
using System.Configuration;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using Yavsc.Model.Circles;
using System.Web.Mvc;
namespace Yavsc.Model.Blogs
{
@ -121,11 +123,21 @@ namespace Yavsc.Model.Blogs
/// <value><c>true</c> if visible; otherwise, <c>false</c>.</value>
public bool Visible { get; set ; }
/// <summary>
/// Gets or sets the circles allowed to read this ticket.
/// An empty collection specifies a public post.
/// </summary>
/// <value>The circles.</value>
[Display(Name="Cercles autorisés")]
public long[] AllowedCircles { get; set; }
/// <summary>
/// Gets or sets the tags.
/// </summary>
/// <value>The tags.</value>
public string [] Tags { get; set ; }
}
}

@ -3,6 +3,8 @@ using Yavsc.Model.Blogs;
using Yavsc.Model.RolesAndMembers;
using System.Web;
using System.Web.Security;
using Yavsc.Model.Circles;
using System.Web.Mvc;
namespace Yavsc.Model.Blogs
@ -17,10 +19,11 @@ namespace Yavsc.Model.Blogs
/// </summary>
/// <returns>The comment.</returns>
/// <param name="cmtid">Cmtid.</param>
public static long RemoveComment(long cmtid)
public static long RemoveComment (long cmtid)
{
return Provider.RemoveComment (cmtid);
}
/// <summary>
/// Comment the specified from, postid, content and visible.
/// </summary>
@ -42,7 +45,7 @@ namespace Yavsc.Model.Blogs
public static BlogProvider Provider {
get {
if (provider == null)
provider = BlogHelper.GetProvider();
provider = BlogHelper.GetProvider ();
return provider;
}
}
@ -55,7 +58,7 @@ namespace Yavsc.Model.Blogs
/// <param name="title">Title.</param>
public static BlogEntry GetPost (string username, string title)
{
return Provider.GetPost (username, title );
return Provider.GetPost (username, title);
}
/// <summary>
@ -63,7 +66,7 @@ namespace Yavsc.Model.Blogs
/// </summary>
/// <returns>The post.</returns>
/// <param name="postid">Postid.</param>
public static BlogEntry GetPost(long postid)
public static BlogEntry GetPost (long postid)
{
return Provider.GetPost (postid);
}
@ -75,9 +78,10 @@ namespace Yavsc.Model.Blogs
/// <param name="title">Title.</param>
/// <param name="content">Content.</param>
/// <param name="visible">If set to <c>true</c> visible.</param>
public static void Post(string username, string title, string content, bool visible)
/// <param name="cids">sets the circles.</param>
public static long Post (string username, string title, string content, bool visible, long [] cids)
{
Provider.Post(username, title, content, visible );
return Provider.Post (username, title, content, visible, cids);
}
/// <summary>
@ -87,9 +91,10 @@ namespace Yavsc.Model.Blogs
/// <param name="title">Title.</param>
/// <param name="content">Content.</param>
/// <param name="visible">If set to <c>true</c> visible.</param>
public static void UpdatePost(long postid, string title, string content, bool visible)
/// <param name="cids">sets the circles.</param>
public static void UpdatePost (long postid, string title, string content, bool visible,long [] cids)
{
Provider.UpdatePost(postid, title, content, visible);
Provider.UpdatePost (postid, title, content, visible,cids);
}
/// <summary>
@ -101,10 +106,11 @@ namespace Yavsc.Model.Blogs
/// <param name="pageIndex">Page index.</param>
/// <param name="pageSize">Page size.</param>
/// <param name="totalRecords">Total records.</param>
public static BlogEntryCollection FindPost (string pattern, FindBlogEntryFlags searchflags, int pageIndex, int pageSize, out int totalRecords)
public static BlogEntryCollection FindPost (string readersName, string pattern, FindBlogEntryFlags searchflags, int pageIndex, int pageSize, out int totalRecords)
{
return Provider.FindPost (pattern, searchflags, pageIndex, pageSize, out totalRecords);
return Provider.FindPost (readersName, pattern, searchflags, pageIndex, pageSize, out totalRecords);
}
/// <summary>
/// Removes the post.
/// </summary>
@ -118,7 +124,7 @@ namespace Yavsc.Model.Blogs
throw new AccessViolationException (
string.Format (
"{1}, Vous n'avez pas le droit de suprimer des billets du Blog de {0}",
username,rguser));
username, rguser));
}
}
Provider.RemovePost (username, title);
@ -142,17 +148,19 @@ namespace Yavsc.Model.Blogs
/// <returns>The comments.</returns>
/// <param name="postid">Postid.</param>
/// <param name="getHidden">If set to <c>true</c> get hidden.</param>
public static Comment[] GetComments(long postid, bool getHidden=true)
public static Comment[] GetComments (long postid, bool getHidden = true)
{
return Provider.GetComments (postid,getHidden);
return Provider.GetComments (postid, getHidden);
}
/// <summary>
/// Tag the specified post by postid.
/// </summary>
/// <param name="postid">Postid.</param>
/// <param name="tag">Tag.</param>
/// <returns>The tag identifier</returns>
public static long Tag(long postid, string tag) {
public static long Tag (long postid, string tag)
{
return Provider.Tag (postid, tag);
}

@ -2,6 +2,8 @@ using System;
using System.Configuration;
using System.Configuration.Provider;
using System.Collections.Generic;
using Yavsc.Model.Circles;
using System.Web.Mvc;
namespace Yavsc.Model.Blogs
{
@ -25,14 +27,6 @@ namespace Yavsc.Model.Blogs
/// <param name="title">Title.</param>
public abstract BlogEntry GetPost (string username, string title);
/// <summary>
/// Gets the post identifier.
/// </summary>
/// <returns>The post identifier.</returns>
/// <param name="username">Username.</param>
/// <param name="title">Title.</param>
public abstract long GetPostId (string username, string title);
/// <summary>
/// Post the specified username, title, content and visible.
/// </summary>
@ -40,7 +34,7 @@ namespace Yavsc.Model.Blogs
/// <param name="title">Title.</param>
/// <param name="content">Content.</param>
/// <param name="visible">If set to <c>true</c> visible.</param>
public abstract long Post (string username, string title, string content, bool visible);
public abstract long Post (string username, string title, string content, bool visible, long[] allowedCircles);
/// <summary>
/// Updates the post.
@ -49,7 +43,7 @@ namespace Yavsc.Model.Blogs
/// <param name="title">Title.</param>
/// <param name="content">Content.</param>
/// <param name="visible">If set to <c>true</c> visible.</param>
public abstract void UpdatePost (long postid, string title, string content, bool visible);
public abstract void UpdatePost (long postid, string title, string content, bool visible, long[] allowedCircles);
/// <summary>
/// Finds the post.
@ -60,7 +54,7 @@ namespace Yavsc.Model.Blogs
/// <param name="pageIndex">Page index.</param>
/// <param name="pageSize">Page size.</param>
/// <param name="totalRecords">Total records.</param>
public abstract BlogEntryCollection FindPost (string pattern, FindBlogEntryFlags searchflags,
public abstract BlogEntryCollection FindPost (string readersName, string pattern, FindBlogEntryFlags searchflags,
int pageIndex, int pageSize, out int totalRecords);
/// <summary>

@ -1,3 +1,14 @@
2015-07-02 Paul Schneider <paul@pschneider.fr>
* ListItem.cs:
* YavscModel.csproj:
* BlogEntry.cs:
* BlogManager.cs:
* BlogProvider.cs:
* CircleManager.cs:
* CircleProvider.cs:
* SimpleMessage.cs:
2015-06-26 Paul Schneider <paul@pschneider.fr>
* Period.cs:

@ -73,47 +73,8 @@ namespace Yavsc.Model.Circles
defaultProvider = ci.Invoke (Type.EmptyTypes) as CircleProvider;
defaultProvider.Initialize (pSection.DefaultProvider,pSetDef.Parameters);
}
/*
foreach (ProviderSettings pSettings in
providerSettings)
{
Console.WriteLine(
"Provider settings name: {0}",
pSettings.Name);
Console.WriteLine(
"Provider settings type: {0}",
pSettings.Type);
NameValueCollection parameters =
pSettings.Parameters;
IEnumerator pEnum =
parameters.GetEnumerator();
int i = 0;
while (pEnum.MoveNext())
{
string pLength =
parameters[i].Length.ToString();
Console.WriteLine(
"Provider ssettings: {0} has {1} parameters",
pSettings.Name, pLength);
}
}
*/
}
}
}

@ -25,6 +25,8 @@ using System.Collections.Specialized;
using System.Collections;
using System.Reflection;
using System.Configuration.Provider;
using System.Web.Mvc;
using System.Collections.Generic;
namespace Yavsc.Model.Circles
{
@ -70,7 +72,14 @@ namespace Yavsc.Model.Circles
/// <summary>
/// List this instance.
/// </summary>
public abstract CircleInfoCollection List(string user);
public abstract IEnumerable<ListItem> List(string user);
/// <summary>
/// Covers the specified username.
/// </summary>
/// <param name="circle_ids">circle's owner.</param>
/// <param name="member">Username in his circle.</param>
public abstract bool Matches(long [] circle_ids, string member);
}

@ -1,5 +1,5 @@
//
// CircleInfoCollection.cs
//
// ListItem.cs
//
// Author:
// Paul Schneider <paul@pschneider.fr>
@ -18,18 +18,15 @@
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
namespace Yavsc.Model.Circles
namespace Yavsc.Model
{
/// <summary>
/// Circle info collection.
/// </summary>
public class CircleInfoCollection : List<CircleInfo>
public class ListItem
{
public string Value { get; set; }
public string Text { get; set; }
public string Icon { get; set; }
}
}

@ -1,5 +1,5 @@
//
// CircleInfo.cs
//
// Message.cs
//
// Author:
// Paul Schneider <paul@pschneider.fr>
@ -18,31 +18,35 @@
//
// You should have received a copy of the GNU Lesser General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.ComponentModel.DataAnnotations;
namespace Yavsc.Model.Circles
namespace Yavsc.Model.Messaging
{
/// <summary>
/// Circle info.
/// Simple message.
/// </summary>
public class CircleInfo
public class SimpleMessage
{
public long Id { get; set; }
public string Title { get; set; }
public CircleInfo(Circle c)
{
Id = c.Id;
Title = c.Title;
}
public CircleInfo(long id, string title)
{
Id = id;
Title = title;
}
/// <summary>
/// Gets or sets the user name this message is comming from.
/// </summary>
/// <value>From.</value>
public string From { get; set; }
/// <summary>
/// Gets or sets the user names, separted by semilicon to which this message will be sent.
/// </summary>
/// <value>To.</value>
public string To { get; set; }
/// <summary>
/// Gets or sets the subject.
/// </summary>
/// <value>The subject.</value>
public string Subject { get; set; }
/// <summary>
/// Gets or sets the body.
/// </summary>
/// <value>The body.</value>
public string Body { get; set; }
}
}

@ -143,8 +143,6 @@
<Compile Include="Calendar\YaEvent.cs" />
<Compile Include="Google\GCMRegisterModel.cs" />
<Compile Include="Circles\Circle.cs" />
<Compile Include="Circles\CircleInfo.cs" />
<Compile Include="Circles\CircleInfoCollection.cs" />
<Compile Include="Circles\CircleManager.cs" />
<Compile Include="Circles\CircleProvider.cs" />
<Compile Include="DataProviderConfigurationSection.cs" />
@ -160,6 +158,8 @@
<Compile Include="RolesAndMembers\ProviderPublicInfo.cs" />
<Compile Include="RolesAndMembers\GCMRegister.cs" />
<Compile Include="RolesAndMembers\LostPasswordModel.cs" />
<Compile Include="Messaging\SimpleMessage.cs" />
<Compile Include="ListItem.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
@ -174,6 +174,7 @@
<Folder Include="Google\Messaging\" />
<Folder Include="Circles\" />
<Folder Include="RolesAndMembers\" />
<Folder Include="Messaging\" />
</ItemGroup>
<ProjectExtensions>
<MonoDevelop>

Loading…