diff --git a/Zero-K.info/AppCode/PostLinkExtensions.cs b/Zero-K.info/AppCode/PostLinkExtensions.cs
new file mode 100644
index 0000000000..976e2d5b91
--- /dev/null
+++ b/Zero-K.info/AppCode/PostLinkExtensions.cs
@@ -0,0 +1,69 @@
+using System.Web.Mvc.Html;
+using System.Web.Routing;
+
+namespace System.Web.Mvc
+{
+ ///
+ /// Renders a link-looking control that submits via POST and carries an anti-forgery token.
+ /// Used for actions that change state: a plain <a> leaves them reachable by GET, which means
+ /// any third-party page can trigger them with the visitor's cookies attached.
+ /// Pass cssClass "js_confirm" to reuse the site's existing confirmation dialog.
+ ///
+ public static class PostLinkExtensions
+ {
+ /// Text link that POSTs to an action.
+ public static MvcHtmlString PostLink(this HtmlHelper html,
+ string linkText,
+ string action,
+ string controller = null,
+ object routeValues = null,
+ string cssClass = null,
+ string nicetitle = null) {
+ return BuildPostForm(html, HttpUtility.HtmlEncode(linkText ?? ""), action, controller, routeValues, cssClass, nicetitle);
+ }
+
+ /// Image link that POSTs to an action. imageHeight of 0 omits the attribute.
+ public static MvcHtmlString PostImageLink(this HtmlHelper html,
+ string imageSrc,
+ int imageHeight,
+ string action,
+ string controller = null,
+ object routeValues = null,
+ string cssClass = null,
+ string nicetitle = null) {
+ var img = new TagBuilder("img");
+ img.Attributes["src"] = imageSrc;
+ if (imageHeight > 0) img.Attributes["height"] = imageHeight.ToString();
+ img.Attributes["alt"] = "";
+ return BuildPostForm(html, img.ToString(TagRenderMode.SelfClosing), action, controller, routeValues, cssClass, nicetitle);
+ }
+
+ static MvcHtmlString BuildPostForm(HtmlHelper html,
+ string innerHtml,
+ string action,
+ string controller,
+ object routeValues,
+ string cssClass,
+ string nicetitle) {
+ var urlHelper = new UrlHelper(html.ViewContext.RequestContext);
+ var values = routeValues == null ? new RouteValueDictionary() : new RouteValueDictionary(routeValues);
+ var url = controller == null ? urlHelper.Action(action, values) : urlHelper.Action(action, controller, values);
+
+ var form = new TagBuilder("form");
+ form.Attributes["method"] = "post";
+ form.Attributes["action"] = url;
+ form.AddCssClass("postlink");
+
+ var button = new TagBuilder("button");
+ button.Attributes["type"] = "submit";
+ // site_main.js skips .postlink-button when it buttonifies :submit with jQuery UI
+ button.AddCssClass("postlink-button");
+ if (!string.IsNullOrEmpty(cssClass)) button.AddCssClass(cssClass);
+ if (!string.IsNullOrEmpty(nicetitle)) button.Attributes["nicetitle"] = nicetitle;
+ button.InnerHtml = innerHtml;
+
+ form.InnerHtml = html.AntiForgeryToken().ToHtmlString() + button.ToString(TagRenderMode.Normal);
+ return new MvcHtmlString(form.ToString(TagRenderMode.Normal));
+ }
+ }
+}
diff --git a/Zero-K.info/Controllers/ContributionsController.cs b/Zero-K.info/Controllers/ContributionsController.cs
index a5c8fe96b8..677335b4dc 100644
--- a/Zero-K.info/Controllers/ContributionsController.cs
+++ b/Zero-K.info/Controllers/ContributionsController.cs
@@ -44,6 +44,7 @@ public ActionResult ThankYou() {
///
/// Manually input a contribution
///
+ [HttpPost]
[ValidateAntiForgeryToken]
[Auth(Role = AdminLevel.Moderator)]
public ActionResult AddContribution(int accountID,int kudos, string item, string currency, double gross, double grossEur, double netEur, string email, string comment, bool isSpring, DateTime date) {
diff --git a/Zero-K.info/Controllers/FactionsController.cs b/Zero-K.info/Controllers/FactionsController.cs
index b916df5a86..9fb6903ec4 100644
--- a/Zero-K.info/Controllers/FactionsController.cs
+++ b/Zero-K.info/Controllers/FactionsController.cs
@@ -116,6 +116,9 @@ public ActionResult NewTreaty(int? acceptingFactionID) {
/// Delete the specified ?
/// If not null or empty, this is a newly proposed treaty
///
+ [Auth]
+ [HttpPost]
+ [ValidateAntiForgeryToken]
public ActionResult ModifyTreaty(int factionTreatyID,
int? turns,
int? acceptingFactionID,
@@ -203,6 +206,9 @@ public ActionResult ModifyTreaty(int factionTreatyID,
+ [Auth]
+ [HttpPost]
+ [ValidateAntiForgeryToken]
public ActionResult CancelTreaty(int id) {
var db = new ZkDataContext();
var treaty = db.FactionTreaties.Single(x => x.FactionTreatyID == id);
@@ -218,6 +224,9 @@ public ActionResult CancelTreaty(int id) {
return Content("Cannot cancel");
}
+ [Auth]
+ [HttpPost]
+ [ValidateAntiForgeryToken]
public ActionResult CounterProposal(int id) {
var db = new ZkDataContext();
var treaty = db.FactionTreaties.Single(x => x.FactionTreatyID == id);
@@ -292,6 +301,9 @@ public ActionResult AcceptTreaty(int id) {
///
/// Set faction secret topic (applied to lobby channel as well)
///
+ [Auth]
+ [HttpPost]
+ [ValidateAntiForgeryToken]
public ActionResult SetTopic(int factionID, string secretTopic) {
var db = new ZkDataContext();
var fac = db.Factions.Single(x => x.FactionID == factionID);
diff --git a/Zero-K.info/Controllers/ForumController.cs b/Zero-K.info/Controllers/ForumController.cs
index c034a6de63..28c68dc164 100644
--- a/Zero-K.info/Controllers/ForumController.cs
+++ b/Zero-K.info/Controllers/ForumController.cs
@@ -538,6 +538,7 @@ public ActionResult Thread(int? id, int? postID) {
return View(res);
}
+ [HttpPost]
[ValidateAntiForgeryToken]
[Auth(Role = AdminLevel.Moderator)]
public ActionResult AdminThread(int threadID, int newcat, bool isPinned, bool isLocked) {
diff --git a/Zero-K.info/Controllers/LobbyController.cs b/Zero-K.info/Controllers/LobbyController.cs
index eebc2fe74e..fd78950bb0 100644
--- a/Zero-K.info/Controllers/LobbyController.cs
+++ b/Zero-K.info/Controllers/LobbyController.cs
@@ -94,6 +94,8 @@ public async Task AddBlockedHost(string hostname, string comment)
}
//[ValidateAntiForgeryToken]
+ [HttpPost]
+ [ValidateAntiForgeryToken]
[Auth(Role = AdminLevel.Moderator)]
public async Task RemoveBlockedCompany(int companyID)
{
@@ -108,6 +110,8 @@ public async Task RemoveBlockedCompany(int companyID)
}
//[ValidateAntiForgeryToken]
+ [HttpPost]
+ [ValidateAntiForgeryToken]
[Auth(Role = AdminLevel.Moderator)]
public async Task RemoveBlockedHost(int hostID)
{
diff --git a/Zero-K.info/Controllers/LobbyNewsController.cs b/Zero-K.info/Controllers/LobbyNewsController.cs
index 2dd7bd02e1..8acac7ee0a 100644
--- a/Zero-K.info/Controllers/LobbyNewsController.cs
+++ b/Zero-K.info/Controllers/LobbyNewsController.cs
@@ -28,6 +28,8 @@ public ActionResult Edit(int? id)
return View("LobbyNewsEdit", db.LobbyNews.Find(id));
}
+ [HttpPost]
+ [ValidateAntiForgeryToken]
[Auth(Role = AdminLevel.Moderator)]
public ActionResult Delete(int id)
{
@@ -45,6 +47,7 @@ public ActionResult Delete(int id)
///
/// The existing item, if editing
/// Also makes or edits a and its starting
+ [HttpPost]
[ValidateAntiForgeryToken]
[Auth(Role = AdminLevel.Moderator)]
[ValidateInput(false)]
diff --git a/Zero-K.info/Controllers/MapBansController.cs b/Zero-K.info/Controllers/MapBansController.cs
index 1f37e23e17..fe56ac2879 100644
--- a/Zero-K.info/Controllers/MapBansController.cs
+++ b/Zero-K.info/Controllers/MapBansController.cs
@@ -46,6 +46,9 @@ public ActionResult Index()
///
///
+ [Auth]
+ [HttpPost]
+ [ValidateAntiForgeryToken]
public ActionResult Update(List resources)
{
if (resources == null) return Content("No input given");
diff --git a/Zero-K.info/Controllers/MapsController.cs b/Zero-K.info/Controllers/MapsController.cs
index 0b19a2d424..28fc4ae6b1 100644
--- a/Zero-K.info/Controllers/MapsController.cs
+++ b/Zero-K.info/Controllers/MapsController.cs
@@ -207,6 +207,7 @@ public JsonResult JsonSearch(string search,
/// Brings up the planet image selector page
///
/// The ID of the map to assign a planet image to
+ [Auth(Role = AdminLevel.Moderator)]
public ActionResult PlanetImageSelect(int resourceID) {
var res = new PlanetImageSelectData();
var db = new ZkDataContext();
@@ -239,6 +240,9 @@ public ActionResult Rate(int id, int rating) {
return Content("");
}
+ [Auth(Role = AdminLevel.Moderator)]
+ [HttpPost]
+ [ValidateAntiForgeryToken]
public ActionResult RemovePlanetIcon(int resourceID) {
var db = new ZkDataContext();
var res = db.Resources.Single(x => x.ResourceID == resourceID);
@@ -247,6 +251,9 @@ public ActionResult RemovePlanetIcon(int resourceID) {
return RedirectToAction("Detail", new { id = res.ResourceID });
}
+ [Auth(Role = AdminLevel.Moderator)]
+ [HttpPost]
+ [ValidateAntiForgeryToken]
public ActionResult SubmitPlanetIcon(int resourceID, string icon) {
var db = new ZkDataContext();
var res = db.Resources.Single(x => x.ResourceID == resourceID);
diff --git a/Zero-K.info/Controllers/MissionsController.cs b/Zero-K.info/Controllers/MissionsController.cs
index ee4a7ef658..644ac4a27a 100644
--- a/Zero-K.info/Controllers/MissionsController.cs
+++ b/Zero-K.info/Controllers/MissionsController.cs
@@ -13,6 +13,7 @@ public class MissionsController : Controller
// GET: /Missions/
+ [HttpPost]
[ValidateAntiForgeryToken]
[Auth(Role = AdminLevel.Moderator)]
public ActionResult ChangeFeaturedOrder(int id, float? featuredOrder, string script)
@@ -31,6 +32,8 @@ public ActionResult ChangeFeaturedOrder(int id, float? featuredOrder, string scr
}
//[ValidateAntiForgeryToken]
+ [HttpPost]
+ [ValidateAntiForgeryToken]
[Auth(Role = AdminLevel.Moderator)]
public ActionResult Delete(int id)
{
@@ -153,6 +156,8 @@ public ActionResult Script(int id)
}
//[ValidateAntiForgeryToken]
+ [HttpPost]
+ [ValidateAntiForgeryToken]
[Auth(Role = AdminLevel.Moderator)]
public ActionResult Undelete(int id)
{
diff --git a/Zero-K.info/Controllers/MyController.cs b/Zero-K.info/Controllers/MyController.cs
index 71cf2a5f97..05a7d2ab26 100644
--- a/Zero-K.info/Controllers/MyController.cs
+++ b/Zero-K.info/Controllers/MyController.cs
@@ -252,6 +252,9 @@ public ActionResult Index()
///
/// Reset all the user's unlocks
///
+ [Auth]
+ [HttpPost]
+ [ValidateAntiForgeryToken]
public ActionResult Reset()
{
var db = new ZkDataContext();
diff --git a/Zero-K.info/Controllers/NewsController.cs b/Zero-K.info/Controllers/NewsController.cs
index dcddc22d48..12c61a37cc 100644
--- a/Zero-K.info/Controllers/NewsController.cs
+++ b/Zero-K.info/Controllers/NewsController.cs
@@ -34,6 +34,7 @@ public ActionResult Detail(int id) {
///
/// The existing item, if editing
/// Also makes or edits a and its starting
+ [HttpPost]
[ValidateAntiForgeryToken]
[Auth(Role = AdminLevel.Moderator)]
[ValidateInput(false)]
diff --git a/Zero-K.info/Controllers/PlanetwarsAdminController.cs b/Zero-K.info/Controllers/PlanetwarsAdminController.cs
index 20799cb461..46efb701e6 100644
--- a/Zero-K.info/Controllers/PlanetwarsAdminController.cs
+++ b/Zero-K.info/Controllers/PlanetwarsAdminController.cs
@@ -149,6 +149,8 @@ private static void PurgeGalaxy(int galaxyID, bool unassignFactions, bool resetR
}
+ [HttpPost]
+ [ValidateAntiForgeryToken]
public ActionResult SetDefault(int galaxyid)
{
var db = new ZkDataContext();
@@ -158,6 +160,8 @@ public ActionResult SetDefault(int galaxyid)
return RedirectToAction("Index");
}
+ [HttpPost]
+ [ValidateAntiForgeryToken]
[Auth(Role = AdminLevel.SuperAdmin)]
public ActionResult Delete(int galaxyid)
{
@@ -168,6 +172,8 @@ public ActionResult Delete(int galaxyid)
return RedirectToAction("Index");
}
+ [HttpPost]
+ [ValidateAntiForgeryToken]
public ActionResult SetPlanetTeamSizes(int galaxyID)
{
var db = new ZkDataContext();
@@ -189,6 +195,8 @@ public ActionResult SetPlanetTeamSizes(int galaxyID)
return RedirectToAction("Index");
}
+ [HttpPost]
+ [ValidateAntiForgeryToken]
public ActionResult RandomizeMaps(int galaxyID)
{
using (var db = new ZkDataContext())
@@ -232,6 +240,8 @@ public ActionResult ResetRatings()
return RedirectToAction("Index");
}
+ [HttpPost]
+ [ValidateAntiForgeryToken]
public ActionResult AddWormholes(int galaxyID)
{
var db = new ZkDataContext();
@@ -246,6 +256,8 @@ public ActionResult AddWormholes(int galaxyID)
return RedirectToAction("Index");
}
+ [HttpPost]
+ [ValidateAntiForgeryToken]
public ActionResult OwnPlanets(int galaxyID)
{
var db = new ZkDataContext();
@@ -290,6 +302,8 @@ public ActionResult OwnPlanets(int galaxyID)
return RedirectToAction("Index");
}
+ [HttpPost]
+ [ValidateAntiForgeryToken]
public ActionResult StartGalaxy(int galaxyID)
{
AddWormholes(galaxyID);
diff --git a/Zero-K.info/Controllers/PlanetwarsController.cs b/Zero-K.info/Controllers/PlanetwarsController.cs
index b2b1b9dcd7..3010f21985 100644
--- a/Zero-K.info/Controllers/PlanetwarsController.cs
+++ b/Zero-K.info/Controllers/PlanetwarsController.cs
@@ -439,6 +439,8 @@ public ActionResult RunSetPlanetOwners()
+ [HttpPost]
+ [ValidateAntiForgeryToken]
[Auth(Role = AdminLevel.Moderator)]
public ActionResult SubmitRenamePlanet(int planetID, string newName, int teamSize, string map)
{
@@ -461,6 +463,9 @@ public ActionResult SubmitRenamePlanet(int planetID, string newName, int teamSiz
}
+ [Auth]
+ [HttpPost]
+ [ValidateAntiForgeryToken]
public ActionResult RecallRole(int accountID, int roletypeID)
{
var db = new ZkDataContext();
@@ -482,6 +487,9 @@ public ActionResult RecallRole(int accountID, int roletypeID)
else return Content("Cannot recall");
}
+ [Auth]
+ [HttpPost]
+ [ValidateAntiForgeryToken]
public ActionResult AppointRole(int accountID, int roletypeID)
{
var db = new ZkDataContext();
diff --git a/Zero-K.info/Controllers/PollController.cs b/Zero-K.info/Controllers/PollController.cs
index 33b76afbf9..9624a0a628 100644
--- a/Zero-K.info/Controllers/PollController.cs
+++ b/Zero-K.info/Controllers/PollController.cs
@@ -21,6 +21,7 @@ public ActionResult Index(int pollID)
return null;
}
+ [HttpPost]
[ValidateAntiForgeryToken]
[Auth(Role = AdminLevel.Moderator)]
public ActionResult NewPoll(string question, string answers, bool? isAnonymous)
@@ -195,6 +196,8 @@ public ActionResult PollVote(int pollID)
}
//[ValidateAntiForgeryToken]
+ [HttpPost]
+ [ValidateAntiForgeryToken]
[Auth(Role = AdminLevel.Moderator)]
public ActionResult SwapHeadline(int pollid)
{
@@ -217,6 +220,8 @@ public ActionResult UserVotes(int? id)
return View("PollUserVotes", acc);
}
+ [HttpPost]
+ [ValidateAntiForgeryToken]
[Auth(Role = AdminLevel.Moderator)]
public ActionResult SwapVisible(int pollid)
{
diff --git a/Zero-K.info/Scripts/site_main.js b/Zero-K.info/Scripts/site_main.js
index 2e14582fd2..3dca355ffc 100644
--- a/Zero-K.info/Scripts/site_main.js
+++ b/Zero-K.info/Scripts/site_main.js
@@ -205,8 +205,8 @@ function GlobalPageInit(root) {
s.find(".js_datetimepicker").datetimepicker();
// buttonification
- s.find(":submit").button();
- s.find(":button").button();
+ s.find(":submit").not(".postlink-button").button();
+ s.find(":button").not(".postlink-button").button();
s.find(".js_button").button();
s.find(".js_accordion").accordion();
diff --git a/Zero-K.info/Styles/style.css b/Zero-K.info/Styles/style.css
index 0219d0988b..678a680083 100644
--- a/Zero-K.info/Styles/style.css
+++ b/Zero-K.info/Styles/style.css
@@ -640,4 +640,37 @@ div#busy
.video-container {
max-width: 100%;
-}
\ No newline at end of file
+}
+
+/* Action links that POST instead of GET so they can carry an anti-forgery token.
+ Renders
+@Html.AntiForgeryToken()
@for (int i = 0; i < Model.Count; i++)
{
diff --git a/Zero-K.info/Views/Maps/PlanetImageSelect.cshtml b/Zero-K.info/Views/Maps/PlanetImageSelect.cshtml
index f80d5dc382..779b57c070 100644
--- a/Zero-K.info/Views/Maps/PlanetImageSelect.cshtml
+++ b/Zero-K.info/Views/Maps/PlanetImageSelect.cshtml
@@ -2,10 +2,13 @@
@{
Layout = null;
}
-@Html.ActionLink("Remove planet", "RemovePlanetIcon", new { resourceID = Model.ResourceID})
+
+@Html.PostLink("Remove planet", "RemovePlanetIcon", null, new { resourceID = Model.ResourceID }, "js_confirm")
@foreach (var x in Model.Icons) {
-
-
-
+ @Html.PostImageLink("/img/planets/" + x, 0, "SubmitPlanetIcon", null, new { resourceID = Model.ResourceID, icon = x }, "planeticon")
}
diff --git a/Zero-K.info/Views/Missions/Detail.cshtml b/Zero-K.info/Views/Missions/Detail.cshtml
index b9221323e3..b875b94b2c 100644
--- a/Zero-K.info/Views/Missions/Detail.cshtml
+++ b/Zero-K.info/Views/Missions/Detail.cshtml
@@ -167,9 +167,9 @@
if (!m.IsDeleted) {
-
Delete mission
+
@Html.PostLink("Delete mission", "Delete", "Missions", new { id = m.MissionID }, "js_confirm")
} else {
-
Undelete
+
@Html.PostLink("Undelete", "Undelete", "Missions", new { id = m.MissionID })
}
}
diff --git a/Zero-K.info/Views/Planetwars/Planet.cshtml b/Zero-K.info/Views/Planetwars/Planet.cshtml
index d9e390319b..7b77d4078c 100644
--- a/Zero-K.info/Views/Planetwars/Planet.cshtml
+++ b/Zero-K.info/Views/Planetwars/Planet.cshtml
@@ -111,6 +111,7 @@
{
+ @Html.AntiForgeryToken()
diff --git a/Zero-K.info/Views/PlanetwarsAdmin/PlanetwarsAdminIndex.cshtml b/Zero-K.info/Views/PlanetwarsAdmin/PlanetwarsAdminIndex.cshtml
index 0b957b2caa..aff849dcf2 100644
--- a/Zero-K.info/Views/PlanetwarsAdmin/PlanetwarsAdminIndex.cshtml
+++ b/Zero-K.info/Views/PlanetwarsAdmin/PlanetwarsAdminIndex.cshtml
@@ -24,9 +24,9 @@
}
else
{
- @Html.ActionLink("Select", "SetDefault", new { galaxyID = gal.GalaxyID })
+ @Html.PostLink("Select", "SetDefault", null, new { galaxyID = gal.GalaxyID })
|
- @Html.ActionLink("Delete", "Delete", new { galaxyID = gal.GalaxyID }, new { @class = "js_confirm" })
+ @Html.PostLink("Delete", "Delete", null, new { galaxyID = gal.GalaxyID }, "js_confirm")
}
}
@@ -78,9 +78,11 @@
Selected map utils
- @Html.ActionLink("Randomize maps", "RandomizeMaps", new { galaxyID = Model.LastSelectedGalaxyID })
- @Html.ActionLink("Set team sizes", "SetPlanetTeamSizes", new { galaxyID = Model.LastSelectedGalaxyID })
- @Html.ActionLink("Start galaxy", "StartGalaxy", new { galaxyID = Model.LastSelectedGalaxyID })
+ @Html.PostLink("Randomize maps", "RandomizeMaps", null, new { galaxyID = Model.LastSelectedGalaxyID }, "js_confirm")
+ @Html.PostLink("Set team sizes", "SetPlanetTeamSizes", null, new { galaxyID = Model.LastSelectedGalaxyID }, "js_confirm")
+ @Html.PostLink("Start galaxy", "StartGalaxy", null, new { galaxyID = Model.LastSelectedGalaxyID }, "js_confirm")
+ @Html.PostLink("Add wormholes", "AddWormholes", null, new { galaxyID = Model.LastSelectedGalaxyID }, "js_confirm")
+ @Html.PostLink("Own planets", "OwnPlanets", null, new { galaxyID = Model.LastSelectedGalaxyID }, "js_confirm")
@Html.ActionLink("Reset all PW player ratings", "ResetRatings")
diff --git a/Zero-K.info/Views/Poll/PollUserVotes.cshtml b/Zero-K.info/Views/Poll/PollUserVotes.cshtml
index 1b1dfb5509..1974d94315 100644
--- a/Zero-K.info/Views/Poll/PollUserVotes.cshtml
+++ b/Zero-K.info/Views/Poll/PollUserVotes.cshtml
@@ -31,8 +31,8 @@
{
- @Html.ActionLink(p.IsVisible ? "visible, hide completely?" : "hidden, show in this list?", "SwapVisible", new { pollID = p.PollID })
- @Html.ActionLink(p.IsHeadline ? "HEADLINE, stop displaying on home?" : "add to home headline?", "SwapHeadline", new { pollID = p.PollID })
+ @Html.PostLink(p.IsVisible ? "visible, hide completely?" : "hidden, show in this list?", "SwapVisible", null, new { pollID = p.PollID })
+ @Html.PostLink(p.IsHeadline ? "HEADLINE, stop displaying on home?" : "add to home headline?", "SwapHeadline", null, new { pollID = p.PollID })
}
diff --git a/Zero-K.info/Views/Shared/DisplayTemplates/AccountRole.cshtml b/Zero-K.info/Views/Shared/DisplayTemplates/AccountRole.cshtml
index 815c30996c..0a5b537366 100644
--- a/Zero-K.info/Views/Shared/DisplayTemplates/AccountRole.cshtml
+++ b/Zero-K.info/Views/Shared/DisplayTemplates/AccountRole.cshtml
@@ -13,6 +13,6 @@
if (Global.Account != null && Global.Account.CanRecall(entry.Account, entry.RoleType))
{
- (recall)
+ @Html.PostLink("(recall)", "RecallRole", "Planetwars", new { accountID = entry.AccountID, roleTypeID = entry.RoleTypeID }, "js_confirm")
}
}
\ No newline at end of file
diff --git a/Zero-K.info/Views/Shared/DisplayTemplates/FactionTreaty.cshtml b/Zero-K.info/Views/Shared/DisplayTemplates/FactionTreaty.cshtml
index c4c2b2444e..02ca619c40 100644
--- a/Zero-K.info/Views/Shared/DisplayTemplates/FactionTreaty.cshtml
+++ b/Zero-K.info/Views/Shared/DisplayTemplates/FactionTreaty.cshtml
@@ -59,10 +59,10 @@
@if (tr.CanCancel(Global.Account))
{
- @Html.ActionLink("(cancel treaty)", "CancelTreaty", "Factions", new { id = tr.FactionTreatyID }, null) |
+ @Html.PostLink("(cancel treaty)", "CancelTreaty", "Factions", new { id = tr.FactionTreatyID }, "js_confirm") |
@if (tr.TreatyState == TreatyState.Proposed)
{
- @Html.ActionLink("(counter proposal)", "CounterProposal", "Factions", new { id = tr.FactionTreatyID }, null) @: |
+ @Html.PostLink("(counter proposal)", "CounterProposal", "Factions", new { id = tr.FactionTreatyID }) @: |
if (tr.CanAccept(Global.Account))
{
@Html.ActionLink("(accept)", "AcceptTreaty", "Factions", new { id = tr.FactionTreatyID }, new { @class = "delete" })
diff --git a/Zero-K.info/Views/Users/UserRoleList.cshtml b/Zero-K.info/Views/Users/UserRoleList.cshtml
index 7464c55150..c8d463ed8d 100644
--- a/Zero-K.info/Views/Users/UserRoleList.cshtml
+++ b/Zero-K.info/Views/Users/UserRoleList.cshtml
@@ -40,7 +40,7 @@
}
if (Global.Account.CanAppoint(Model, role))
{
- (appoint)
+ @Html.PostLink("(appoint)", "AppointRole", "Planetwars", new { accountID = Model.AccountID, roleTypeID = role.RoleTypeID })
}
index++;
if (index < grp.ToList().Count)
diff --git a/Zero-K.info/Web.config b/Zero-K.info/Web.config
index 9ce0c3ad00..074b1ec7ae 100644
--- a/Zero-K.info/Web.config
+++ b/Zero-K.info/Web.config
@@ -7,9 +7,6 @@
-
@@ -43,7 +40,7 @@
-
+
diff --git a/Zero-K.info/asp.net.csproj b/Zero-K.info/asp.net.csproj
index 06bfc9cbda..8bd8bb0af0 100644
--- a/Zero-K.info/asp.net.csproj
+++ b/Zero-K.info/asp.net.csproj
@@ -153,6 +153,7 @@
+
diff --git a/ZkData/Ef/Account.cs b/ZkData/Ef/Account.cs
index 2545c3f249..a92d9916f0 100644
--- a/ZkData/Ef/Account.cs
+++ b/ZkData/Ef/Account.cs
@@ -292,10 +292,17 @@ public bool VerifyPassword(string passwordHash)
}
+ ///
+ /// BCrypt cost for newly written hashes. Existing hashes keep the cost they were written
+ /// with - it is stored in the hash itself - so raising this only affects passwords set from
+ /// now on, and Verify keeps working for the old ones.
+ ///
+ public const int BcryptWorkFactor = 10;
+
public void SetPasswordHashed(string passwordHash)
{
if (string.IsNullOrEmpty(passwordHash)) PasswordBcrypt = null;
- else PasswordBcrypt = BCrypt.Net.BCrypt.HashPassword(passwordHash, 4);
+ else PasswordBcrypt = BCrypt.Net.BCrypt.HashPassword(passwordHash, BcryptWorkFactor);
}
public void SetPasswordPlain(string passwordPlain)