WIP booking

* CalAuth.aspx: A view ... still unused

* style.css: css overflow-y auto, the container making it modal has no
  margin.

* GoogleController.cs: Fixes again the calendar usage,
uses Google API key and client credentials found in configuration file

* ApiClient.cs: Google API key and client credentials are now found in
  configuration file

* CalendarApi.cs: Let the controller build the credential string from
  thr profile object.

* OAuth2.cs: The OAuth2 Client only needs a client id and secret

* yavsc.js: Fixes some css flipping

* ValidateAjaxAttribute.cs: A FIXME

* Web.config: Google key, client id and secret come from application
  settings

* Web.csproj: a page in more

* YavscModel.csproj:
* PostInfoByUser.cs:
* PostInfoByTitle.cs:
* BlogEntryCollection.cs: refactoring
vnext
Paul Schneider 9 years ago
parent d9d5bb308e
commit e6c65019b0
16 changed files with 117 additions and 147 deletions

@ -27,7 +27,7 @@ body {
url('/images/FhHRx.gif')
50% 50%
no-repeat;
overflow: scroll;
overflow: auto;
}
.dispmodal {
position: fixed;
@ -35,7 +35,9 @@ body {
top: 0;
left: 0;
right: 0;
overflow: scroll;
width: 100%;
overflow-y: auto;
overflow-x: hidden;
}
body.loading {
@ -218,9 +220,6 @@ label {
border-radius: 1em;
border: dashed rgb(020,20,256) 2px;
}
#notifications {
padding: 1em;
}
.notification {
font-size: large;
@ -368,7 +367,8 @@ header h1, header a , .actionlink, .menuitem, a { padding:.5em;}
margin:.5em;
padding:.5em;
}
#notifications {
.notification {
padding: .5em;
border-radius:.5em;
margin:.5em;
@ -398,6 +398,7 @@ header {
padding-bottom:.5em;
background: url("/images/star-939235_1280.xxs.jpg") 0 0 no-repeat fixed;
}
header h1, header a { padding:.2em;}
nav {

@ -1,3 +1,32 @@
2015-11-01 Paul Schneider <paul@pschneider.fr>
* CalAuth.aspx: A view ... still unused
* style.css: css overflow-y auto, the container making it
modal has no margin.
* GoogleController.cs: Fixes again the calendar usage,
uses Google API key and client credentials found in
configuration file
* ApiClient.cs: Google API key and client credentials are now
found in configuration file
* CalendarApi.cs: Let the controller build the credential
string from thr profile object.
* OAuth2.cs: The OAuth2 Client only needs a client id and
secret
* yavsc.js: Fixes some css flipping
* ValidateAjaxAttribute.cs: A FIXME
* Web.config: Google key, client id and secret come from
application settings
* Web.csproj: a page in more
2015-11-01 Paul Schneider <paul@pschneider.fr>
* Book-next.aspx: pollution

@ -78,10 +78,12 @@ namespace Yavsc.Controllers
if (string.IsNullOrWhiteSpace (returnUrl))
returnUrl = "/";
Session ["returnUrl"] = returnUrl;
OAuth2 oa = new OAuth2 (AuthGRU);
OAuth2 oa = new OAuth2 (AuthGRU,clientId,clientSecret);
oa.Login (Response, SetSessionSate ());
}
private string clientId = ConfigurationManager.AppSettings ["GOOGLE_CLIENT_ID"];
private string clientSecret = ConfigurationManager.AppSettings ["GOOGLE_CLIENT_SECRET"];
private string clientApiKey = ConfigurationManager.AppSettings ["GOOGLE_API_KEY"];
/// <summary>
/// Gets the cal auth.
/// </summary>
@ -91,8 +93,8 @@ namespace Yavsc.Controllers
if (string.IsNullOrWhiteSpace (returnUrl))
returnUrl = "/";
Session ["returnUrl"] = returnUrl;
OAuth2 oa = new OAuth2 (CalendarGRU);
oa.GetCalAuth (Response, SetSessionSate ());
OAuth2 oa = new OAuth2 (CalendarGRU,clientId,clientSecret);
oa.GetCalendarScope (Response, SetSessionSate ());
}
/// <summary>
@ -105,16 +107,16 @@ namespace Yavsc.Controllers
public ActionResult CalAuth ()
{
string msg;
OAuth2 oa = new OAuth2 (CalendarGRU);
OAuth2 oa = new OAuth2 (CalendarGRU,clientId,clientSecret);
AuthToken gat = oa.GetToken (Request, (string)Session ["state"], out msg);
AuthToken gat = oa.GetToken (Request, (string) Session ["state"], out msg);
if (gat == null) {
YavscHelpers.Notify(ViewData, msg);
return View ("Auth");
}
SaveToken (HttpContext.Profile,gat);
HttpContext.Profile.SetPropertyValue ("gcalapi", true);
string returnUrl = (string)Session ["returnUrl"];
string returnUrl = (string) Session ["returnUrl"];
Session ["returnUrl"] = null;
return Redirect (returnUrl);
}
@ -143,7 +145,7 @@ namespace Yavsc.Controllers
public ActionResult Auth ()
{
string msg;
OAuth2 oa = new OAuth2 (AuthGRU);
OAuth2 oa = new OAuth2 (AuthGRU,clientId,clientSecret);
AuthToken gat = oa.GetToken (Request, (string)Session ["state"], out msg);
if (gat == null) {
YavscHelpers.Notify(ViewData, msg);
@ -188,8 +190,8 @@ namespace Yavsc.Controllers
ModelState.AddModelError ("UserName", "This user name already is in use");
return View ();
}
string returnUrl = (string)Session ["returnUrl"];
AuthToken gat = (AuthToken)Session ["GoogleAuthToken"];
string returnUrl = (string) Session ["returnUrl"];
AuthToken gat = (AuthToken) Session ["GoogleAuthToken"];
People me = (People)Session ["me"];
if (gat == null || me == null)
throw new InvalidDataException ();
@ -232,8 +234,9 @@ namespace Yavsc.Controllers
}
if (me.url != null)
HttpContext.Profile.SetPropertyValue ("WebSite", me.url);
SaveToken (HttpContext.Profile,gat);
// already done in SaveToken: HttpContext.Profile.Save ();
// Will be done in SaveToken: HttpContext.Profile.Save ();
SaveToken (HttpContext.Profile, gat);
Session ["returnUrl"] = null;
return Redirect (returnUrl);
}
ViewData ["returnUrl"] = returnUrl;
@ -258,19 +261,17 @@ namespace Yavsc.Controllers
[HttpGet]
public ActionResult ChooseCalendar (string returnUrl)
{
bool hasCalAuth = (bool)HttpContext.Profile.GetPropertyValue ("gcalapi");
if (!hasCalAuth) {
Session ["returnUrl"] = Request.Url.Scheme + "://" + Request.Url.Authority + "/Google/ChooseCalendar";
if (returnUrl != null) {
Session ["chooseCalReturnUrl"] = returnUrl;
return RedirectToAction ("GetCalAuth",
new {
returnUrl = "ChooseCalendar?returnUrl="+HttpUtility.UrlEncode(returnUrl)
returnUrl = Url.Action ("ChooseCalendar") // "ChooseCalendar?returnUrl="+HttpUtility.UrlEncode(returnUrl)
});
}
string cred = OAuth2.GetFreshGoogleCredential (HttpContext.Profile);
CalendarApi c = new CalendarApi ();
CalendarApi c = new CalendarApi (clientApiKey);
CalendarList cl = c.GetCalendars (cred);
ViewData ["returnUrl"] = returnUrl;
ViewData ["returnUrl"] = Session ["chooseCalReturnUrl"];
return View (cl);
}
@ -300,7 +301,12 @@ namespace Yavsc.Controllers
[Authorize,HttpGet]
public ActionResult Book ()
{
return View (new BookQuery ());
var model = new BookQuery ();
model.StartDate = DateTime.Now;
model.EndDate = model.StartDate.AddDays(2);
model.StartHour = DateTime.Now.ToString("HH:mm");
model.EndHour = DateTime.Now.AddHours(1).ToString("HH:mm");
return View (model);
}
/// <summary>
@ -313,7 +319,7 @@ namespace Yavsc.Controllers
{
if (ModelState.IsValid) {
DateTime mindate = DateTime.Now;
if (model.StartDate < mindate){
if (model.StartDate.Date < mindate.Date){
ModelState.AddModelError ("StartDate", LocalizedText.FillInAFutureDate);
}
if (model.EndDate < model.StartDate)
@ -333,10 +339,11 @@ namespace Yavsc.Controllers
if (ModelState.IsValid) {
string calid = (string) gcalid;
DateTime maxdate = model.EndDate;
CalendarApi c = new CalendarApi ();
CalendarApi c = new CalendarApi (clientApiKey);
CalendarEventList events;
try {
events = c.GetCalendar (calid, mindate, maxdate, upr);
string creds = OAuth2.GetFreshGoogleCredential (upr);
events = c.GetCalendar (calid, mindate, maxdate, creds);
YavscHelpers.Notify (ViewData, "Google calendar API call success");
} catch (WebException ex) {
string response;

@ -40,16 +40,17 @@ namespace Yavsc.Helpers.Google
/// <summary>
/// The CLIENT Id.
/// </summary>
protected static string CLIENT_ID = "325408689282-6bekh7p3guj4k0f3301a6frf025cnrk1.apps.googleusercontent.com";
public static string CLIENT_ID { get ; set ; }
/// <summary>
/// The CLIENt SECREt
/// </summary>
protected static string CLIENT_SECRET = "MaxYcvJJCs2gDGvaELZbzwfL";
public static string CLIENT_SECRET { get ; set ; }
/// <summary>
/// The API KEY.
/// </summary>
protected static string API_KEY="AIzaSyBV_LQHb22nGgjNvFzZwnQHjao3Q7IewRw";
public static string API_KEY { get ; set ; }
/* // to use in descendence
*
protected static string getPeopleUri = "https://www.googleapis.com/plus/v1/people";

@ -36,8 +36,12 @@ namespace Yavsc.Helpers.Google
/// <summary>
/// Google Calendar API client.
/// </summary>
public class CalendarApi: ApiClient
public class CalendarApi : ApiClient
{
public CalendarApi(string apiKey)
{
API_KEY = apiKey;
}
/// <summary>
/// The get cal list URI.
/// </summary>
@ -87,8 +91,11 @@ namespace Yavsc.Helpers.Google
/// <param name="mindate">Mindate.</param>
/// <param name="maxdate">Maxdate.</param>
/// <param name="upr">Upr.</param>
public CalendarEventList GetCalendar (string calid, DateTime mindate, DateTime maxdate, ProfileBase upr)
public CalendarEventList GetCalendar (string calid, DateTime mindate, DateTime maxdate,string cred)
{
if (string.IsNullOrWhiteSpace (calid))
throw new Exception ("the calendar identifier is not specified");
string uri = string.Format (
getCalEntriesUri, HttpUtility.UrlEncode (calid)) +
string.Format ("?orderBy=startTime&singleEvents=true&timeMin={0}&timeMax={1}&key=" + API_KEY,
@ -96,7 +103,7 @@ namespace Yavsc.Helpers.Google
HttpUtility.UrlEncode (maxdate.ToString (dateFormat) + timeZone));
HttpWebRequest webreq = WebRequest.CreateHttp (uri);
string cred = OAuth2.GetFreshGoogleCredential (upr);
webreq.Headers.Add (HttpRequestHeader.Authorization, cred);
webreq.Method = "GET";
webreq.ContentType = "application/http";

@ -36,7 +36,7 @@ namespace Yavsc.Helpers.Google
/// <summary>
/// Google O auth2 client.
/// </summary>
public class OAuth2:ApiClient
public class OAuth2 : ApiClient
{
/// <summary>
/// The URI used to get tokens.
@ -58,9 +58,11 @@ namespace Yavsc.Helpers.Google
/// Initializes a new instance of the <see cref="Yavsc.Helpers.Google.OAuth2"/> class.
/// </summary>
/// <param name="redirectUri">Redirect URI.</param>
public OAuth2 (string redirectUri)
public OAuth2 (string redirectUri, string clientId, string clientSecret)
{
RedirectUri = redirectUri;
CLIENT_ID = clientId;
CLIENT_SECRET = clientSecret;
}
/// <summary>
@ -84,12 +86,10 @@ namespace Yavsc.Helpers.Google
/// </summary>
/// <param name="bresp">Bresp.</param>
/// <param name="state">State.</param>
public void GetCalAuth (HttpResponseBase bresp, string state)
public void GetCalendarScope (HttpResponseBase bresp, string state)
{
string scope = string.Join ("%20", scopeOpenid);
scope = string.Join ("%20", scopeCalendar);
string prms = String.Format ("response_type=code&client_id={0}&redirect_uri={1}&scope={2}&state={3}&include_granted_scopes=false&access_type=offline",
CLIENT_ID, RedirectUri, scope, state);
string prms = String.Format ("response_type=code&client_id={0}&redirect_uri={1}&scope={2}&state={3}&include_granted_scopes=true&access_type=offline&approval_prompt=force",
CLIENT_ID, RedirectUri, scopeCalendar, state);
GetAuthResponse (bresp, prms);
}
@ -230,16 +230,14 @@ namespace Yavsc.Helpers.Google
DateTime token_exp = (DateTime) pr.GetPropertyValue ("gtokenexpir");
if (token_exp < DateTime.Now) {
object ort = pr.GetPropertyValue ("grefreshtoken");
if (ort == null || ort is DBNull) {
if (ort is DBNull || string.IsNullOrWhiteSpace((string)ort)) {
throw new InvalidOAuth2RefreshToken ("Google");
}
else {
string refresh_token = ort as string;
AuthToken gat = OAuth2.GetTokenPosting (
string.Format ("grant_type=refresh_token&client_id={0}&client_secret={1}&refresh_token={2}",
CLIENT_ID, CLIENT_SECRET, refresh_token));
token = gat.access_token;
}
string refresh_token = ort as string;
AuthToken gat = OAuth2.GetTokenPosting (
string.Format ("grant_type=refresh_token&client_id={0}&client_secret={1}&refresh_token={2}",
CLIENT_ID, CLIENT_SECRET, refresh_token));
token = gat.access_token;
pr.SetPropertyValue ("gtoken", token);
pr.Save ();
// ASSERT gat.token_type == pr.GetPropertyValue("gtokentype")

@ -47,7 +47,7 @@ self.ajax = function (method,data,callback) {
self.onScroll = function() {
var $notifications = $('#notifications');
if ($notifications.has('*').length>0) {
if ($(window).scrollTop()>100) {
if ($(window).scrollTop()>0) {
$notifications.addClass("dispmodal");
}
else {

@ -43,7 +43,7 @@ namespace Yavsc
where modelState[x].Errors.Count > 0
select new
{
// FIXME why?
// FIXME why not directly underscores?
key = x.Replace(".","_"),
errors = modelState[x].Errors.
Select(y => y.ErrorMessage).

@ -0,0 +1,5 @@
<%@ Page Title="Catalog" Language="C#" Inherits="System.Web.Mvc.ViewPage" MasterPageFile="~/Models/App.master" %>
<asp:Content ContentPlaceHolderID="MainContent" ID="MainContentContent" runat="server">
</asp:Content>

@ -267,5 +267,8 @@ http://msdn2.microsoft.com/en-us/library/b5ysx397.aspx
<add key="ClientValidationEnabled" value="true" />
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
<add key="PayPalLogger" value="PayPal.Log.Log4netLogger" />
</appSettings>
<add key="GOOGLE_API_KEY" value="AIzaSyCF7Bgz-W_p26bbMzxp1ukdgg3LMDHzAo0" />
<add key="GOOGLE_CLIENT_ID" value="325408689282-6bekh7p3guj4k0f3301a6frf025cnrk1.apps.googleusercontent.com" />
<add key="GOOGLE_CLIENT_SECRET" value="MaxYcvJJCs2gDGvaELZbzwfL" />
</appSettings>
</configuration>

@ -468,6 +468,7 @@
<Content Include="Scripts\jquery.datepair.js" />
<Content Include="Scripts\jquery.datepair.min.js" />
<Content Include="Scripts\jquery-1.11.3.min.js" />
<Content Include="Views\Google\CalAuth.aspx" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" />

@ -82,13 +82,13 @@ namespace Yavsc.Model.Blogs
/// <summary>
/// Groups by title.
/// </summary>
public IEnumerable<IGrouping<string,PostInfoByTitle>> GroupByTitle ()
public IEnumerable<IGrouping<string,BasePostInfo>> GroupByTitle ()
{
bool truncated;
return from be in this
orderby be.Posted descending
group
new PostInfoByTitle { Author = be.Author, Id = be.Id,
group
new BasePostInfo { Author = be.Author, Id = be.Id,
Posted = be.Posted, Modified = be.Modified,
Intro = MarkdownHelper.MarkdownIntro (be.Content, out truncated),
Visible = be.Visible,
@ -103,13 +103,13 @@ namespace Yavsc.Model.Blogs
/// Groups by user.
/// </summary>
/// <returns>The by user.</returns>
public IEnumerable<IGrouping<string,PostInfoByUser>> GroupByUser ()
public IEnumerable<IGrouping<string,BasePostInfo>> GroupByUser ()
{
bool truncated;
return from be in this
orderby be.Posted descending
group
new PostInfoByUser {
new BasePostInfo {
Title = be.Title,
Id = be.Id,
Posted = be.Posted,

@ -1,44 +0,0 @@
//
// PostInfoByTitle.cs
//
// Author:
// Paul Schneider <paul@pschneider.fr>
//
// Copyright (c) 2015 GNU GPL
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// 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.Configuration;
using System.Collections.Generic;
using Yavsc.Model.Blogs;
using System.Linq;
using Yavsc.Model.Circles;
namespace Yavsc.Model.Blogs
{
/// <summary>
/// Post info.
/// </summary>
public class PostInfoByTitle : BasePostInfo {
/// <summary>
/// The name of the user.
/// </summary>
public string Author;
}
}

@ -1,43 +0,0 @@
//
// PostInfoByUser.cs
//
// Author:
// Paul Schneider <paul@pschneider.fr>
//
// Copyright (c) 2015 GNU GPL
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// 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.Configuration;
using System.Collections.Generic;
using Yavsc.Model.Blogs;
using System.Linq;
using Yavsc.Model.Circles;
namespace Yavsc.Model.Blogs
{
/// <summary>
/// Post info by user.
/// </summary>
public class PostInfoByUser : BasePostInfo {
/// <summary>
/// The name of the user.
/// </summary>
public string Title;
}
}

@ -1,3 +1,10 @@
2015-11-01 Paul Schneider <paul@pschneider.fr>
* YavscModel.csproj:
* PostInfoByUser.cs:
* PostInfoByTitle.cs:
* BlogEntryCollection.cs: refactoring
2015-11-01 Paul Schneider <paul@pschneider.fr>
* ProfileEdition.cs: Fixes the username modification

@ -170,8 +170,6 @@
<Compile Include="Blogs\BasePost.cs" />
<Compile Include="Blogs\PostTag.cs" />
<Compile Include="Blogs\BasePostInfo.cs" />
<Compile Include="Blogs\PostInfoByTitle.cs" />
<Compile Include="Blogs\PostInfoByUser.cs" />
<Compile Include="Blogs\TagInfo.cs" />
<Compile Include="Blogs\MarkdownHelper.cs" />
<Compile Include="Calendar\BookQuery.cs" />

Loading…