Passage à ASP.NET vNext
This commit is contained in:
parent
ea90fefc31
commit
388b004837
1929 changed files with 104611 additions and 235941 deletions
121
Yavsc/src/ApiController/AccountController.cs
Normal file
121
Yavsc/src/ApiController/AccountController.cs
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Account;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Yavsc.ViewModels.Account;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Yavsc.WebApi.Controllers
|
||||
{
|
||||
|
||||
[Authorize,Route("~/api/account")]
|
||||
public class ApiAccountController : Controller
|
||||
{
|
||||
private UserManager<ApplicationUser> _userManager;
|
||||
private readonly SignInManager<ApplicationUser> _signInManager;
|
||||
|
||||
private ILogger _logger;
|
||||
|
||||
public ApiAccountController(UserManager<ApplicationUser> userManager,
|
||||
SignInManager<ApplicationUser> signInManager, ILoggerFactory loggerFactory)
|
||||
{
|
||||
UserManager = userManager;
|
||||
_signInManager = signInManager;
|
||||
_logger = loggerFactory.CreateLogger("ApiAuth");
|
||||
}
|
||||
|
||||
public UserManager<ApplicationUser> UserManager
|
||||
{
|
||||
get
|
||||
{
|
||||
return _userManager;
|
||||
}
|
||||
private set
|
||||
{
|
||||
_userManager = value;
|
||||
}
|
||||
}
|
||||
|
||||
// POST api/Account/ChangePassword
|
||||
public async Task<IActionResult> ChangePassword(ChangePasswordBindingModel model)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return new BadRequestObjectResult(ModelState);
|
||||
}
|
||||
var user = await _userManager.FindByIdAsync(User.GetUserId());
|
||||
if (user == null || !(await _userManager.IsEmailConfirmedAsync(user))) {
|
||||
IdentityResult result = await UserManager.ChangePasswordAsync(user, model.OldPassword,
|
||||
model.NewPassword);
|
||||
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
AddErrors(result);
|
||||
return new BadRequestObjectResult(ModelState);
|
||||
}
|
||||
}
|
||||
return Ok();
|
||||
}
|
||||
|
||||
// POST api/Account/SetPassword
|
||||
public async Task<IActionResult> SetPassword(SetPasswordBindingModel model)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return new BadRequestObjectResult(ModelState);
|
||||
}
|
||||
var user = await _userManager.FindByIdAsync(User.GetUserId());
|
||||
if (user == null || !(await _userManager.IsEmailConfirmedAsync(user))) {
|
||||
IdentityResult result = await UserManager.AddPasswordAsync(user, model.NewPassword);
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
AddErrors (result);
|
||||
return new BadRequestObjectResult(ModelState);
|
||||
}
|
||||
}
|
||||
return Ok();
|
||||
}
|
||||
|
||||
// POST api/Account/Register
|
||||
[AllowAnonymous]
|
||||
public async Task<IActionResult> Register(RegisterViewModel model)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return new BadRequestObjectResult(ModelState);
|
||||
}
|
||||
|
||||
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
|
||||
|
||||
IdentityResult result = await UserManager.CreateAsync(user, model.Password);
|
||||
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
AddErrors (result);
|
||||
return new BadRequestObjectResult(ModelState);
|
||||
}
|
||||
await _signInManager.SignInAsync(user, isPersistent: false);
|
||||
return Ok();
|
||||
}
|
||||
private void AddErrors(IdentityResult result)
|
||||
{
|
||||
foreach (var error in result.Errors)
|
||||
{
|
||||
ModelState.AddModelError(string.Empty, error.Description);
|
||||
}
|
||||
}
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
UserManager.Dispose();
|
||||
}
|
||||
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
47
Yavsc/src/Auth/GoogleExtensions.cs
Normal file
47
Yavsc/src/Auth/GoogleExtensions.cs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
using System;
|
||||
using Microsoft.AspNet.Builder;
|
||||
|
||||
namespace Yavsc.Auth
|
||||
{
|
||||
/// <summary>
|
||||
/// Extension methods to add Google authentication capabilities to an HTTP application pipeline.
|
||||
/// </summary>
|
||||
public static class GoogleAppBuilderExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds the <see cref="GoogleMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables Google authentication capabilities.
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
public static IApplicationBuilder UseGoogleAuthentication(this IApplicationBuilder app)
|
||||
{
|
||||
if (app == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(app));
|
||||
}
|
||||
|
||||
return app.UseMiddleware<GoogleMiddleware>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the <see cref="GoogleMiddleware"/> middleware to the specified <see cref="IApplicationBuilder"/>, which enables Google authentication capabilities.
|
||||
/// </summary>
|
||||
/// <param name="app">The <see cref="IApplicationBuilder"/> to add the middleware to.</param>
|
||||
/// <param name="options">A <see cref="GoogleOptions"/> that specifies options for the middleware.</param>
|
||||
/// <returns>A reference to this instance after the operation has completed.</returns>
|
||||
public static IApplicationBuilder UseGoogleAuthentication(this IApplicationBuilder app, GoogleOptions options)
|
||||
{
|
||||
if (app == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(app));
|
||||
}
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
return app.UseMiddleware<GoogleMiddleware>(options);
|
||||
}
|
||||
}
|
||||
}
|
||||
123
Yavsc/src/Auth/GoogleHandler.cs
Normal file
123
Yavsc/src/Auth/GoogleHandler.cs
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Authentication;
|
||||
using Microsoft.AspNet.Authentication.OAuth;
|
||||
using Microsoft.AspNet.Http.Authentication;
|
||||
using Microsoft.AspNet.WebUtilities;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace Yavsc.Auth
|
||||
{
|
||||
internal class GoogleHandler : OAuthHandler<GoogleOptions>
|
||||
{
|
||||
private ILogger _logger;
|
||||
public GoogleHandler(HttpClient httpClient,ILogger logger)
|
||||
: base(httpClient)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
protected override async Task<AuthenticationTicket> CreateTicketAsync(ClaimsIdentity identity,
|
||||
AuthenticationProperties properties, OAuthTokenResponse tokens
|
||||
)
|
||||
{
|
||||
// TODO use Options.AuthenticationType instead of Bearer ?
|
||||
// Get the Google user
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint);
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", tokens.AccessToken);
|
||||
|
||||
var response = await Backchannel.SendAsync(request, Context.RequestAborted);
|
||||
response.EnsureSuccessStatusCode();
|
||||
|
||||
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
|
||||
|
||||
var identifier = GoogleHelper.GetId(payload);
|
||||
|
||||
|
||||
var ticket = new AuthenticationTicket(new ClaimsPrincipal(identity), properties, Options.AuthenticationScheme);
|
||||
var context = new GoogleOAuthCreatingTicketContext(Context, Options, Backchannel, tokens, ticket, identifier);
|
||||
|
||||
if (!string.IsNullOrEmpty(identifier))
|
||||
{
|
||||
identity.AddClaim(new Claim(ClaimTypes.NameIdentifier, identifier, ClaimValueTypes.String, Options.ClaimsIssuer));
|
||||
}
|
||||
|
||||
var givenName = GoogleHelper.GetGivenName(payload);
|
||||
if (!string.IsNullOrEmpty(givenName))
|
||||
{
|
||||
identity.AddClaim(new Claim(ClaimTypes.GivenName, givenName, ClaimValueTypes.String, Options.ClaimsIssuer));
|
||||
}
|
||||
|
||||
var familyName = GoogleHelper.GetFamilyName(payload);
|
||||
if (!string.IsNullOrEmpty(familyName))
|
||||
{
|
||||
identity.AddClaim(new Claim(ClaimTypes.Surname, familyName, ClaimValueTypes.String, Options.ClaimsIssuer));
|
||||
}
|
||||
|
||||
var name = GoogleHelper.GetName(payload);
|
||||
if (!string.IsNullOrEmpty(name))
|
||||
{
|
||||
identity.AddClaim(new Claim(ClaimTypes.Name, name, ClaimValueTypes.String, Options.ClaimsIssuer));
|
||||
}
|
||||
|
||||
var email = GoogleHelper.GetEmail(payload);
|
||||
if (!string.IsNullOrEmpty(email))
|
||||
{
|
||||
identity.AddClaim(new Claim(ClaimTypes.Email, email, ClaimValueTypes.String, Options.ClaimsIssuer));
|
||||
}
|
||||
|
||||
var profile = GoogleHelper.GetProfile(payload);
|
||||
if (!string.IsNullOrEmpty(profile))
|
||||
{
|
||||
identity.AddClaim(new Claim("urn:google:profile", profile, ClaimValueTypes.String, Options.ClaimsIssuer));
|
||||
}
|
||||
|
||||
await Options.Events.CreatingTicket(context);
|
||||
|
||||
return ticket;
|
||||
}
|
||||
|
||||
// TODO: Abstract this properties override pattern into the base class?
|
||||
protected override string BuildChallengeUrl(AuthenticationProperties properties, string redirectUri)
|
||||
{
|
||||
var scope = FormatScope();
|
||||
var queryStrings = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
|
||||
queryStrings.Add("response_type", "code");
|
||||
queryStrings.Add("client_id", Options.ClientId);
|
||||
queryStrings.Add("redirect_uri", redirectUri);
|
||||
|
||||
AddQueryString(queryStrings, properties, "scope", scope);
|
||||
|
||||
AddQueryString(queryStrings, properties, "access_type", Options.AccessType);
|
||||
AddQueryString(queryStrings, properties, "approval_prompt");
|
||||
AddQueryString(queryStrings, properties, "login_hint");
|
||||
|
||||
var state = Options.StateDataFormat.Protect(properties);
|
||||
queryStrings.Add("state", state);
|
||||
|
||||
var authorizationEndpoint = QueryHelpers.AddQueryString(Options.AuthorizationEndpoint, queryStrings);
|
||||
return authorizationEndpoint;
|
||||
}
|
||||
|
||||
private static void AddQueryString(IDictionary<string, string> queryStrings, AuthenticationProperties properties,
|
||||
string name, string defaultValue = null)
|
||||
{
|
||||
string value;
|
||||
if (!properties.Items.TryGetValue(name, out value))
|
||||
{
|
||||
value = defaultValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Remove the parameter from AuthenticationProperties so it won't be serialized to state parameter
|
||||
properties.Items.Remove(name);
|
||||
}
|
||||
queryStrings[name] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
125
Yavsc/src/Auth/GoogleHelper.cs
Normal file
125
Yavsc/src/Auth/GoogleHelper.cs
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
|
||||
|
||||
using System;
|
||||
using Newtonsoft.Json.Linq;
|
||||
/// <summary>
|
||||
/// Contains static methods that allow to extract user's information from a <see cref="JObject"/>
|
||||
/// instance retrieved from Google after a successful authentication process.
|
||||
/// </summary>
|
||||
public static class GoogleHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the Google user ID.
|
||||
/// </summary>
|
||||
public static string GetId(JObject user)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
return user.Value<string>("id");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user's name.
|
||||
/// </summary>
|
||||
public static string GetName(JObject user)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
return user.Value<string>("displayName");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user's given name.
|
||||
/// </summary>
|
||||
public static string GetGivenName(JObject user)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
return TryGetValue(user, "name", "givenName");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user's family name.
|
||||
/// </summary>
|
||||
public static string GetFamilyName(JObject user)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
return TryGetValue(user, "name", "familyName");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user's profile link.
|
||||
/// </summary>
|
||||
public static string GetProfile(JObject user)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
return user.Value<string>("url");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user's email.
|
||||
/// </summary>
|
||||
public static string GetEmail(JObject user)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
return TryGetFirstValue(user, "emails", "value");
|
||||
}
|
||||
|
||||
// Get the given subProperty from a property.
|
||||
private static string TryGetValue(JObject user, string propertyName, string subProperty)
|
||||
{
|
||||
JToken value;
|
||||
if (user.TryGetValue(propertyName, out value))
|
||||
{
|
||||
var subObject = JObject.Parse(value.ToString());
|
||||
if (subObject != null && subObject.TryGetValue(subProperty, out value))
|
||||
{
|
||||
return value.ToString();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Get the given subProperty from a list property.
|
||||
private static string TryGetFirstValue(JObject user, string propertyName, string subProperty)
|
||||
{
|
||||
JToken value;
|
||||
if (user.TryGetValue(propertyName, out value))
|
||||
{
|
||||
var array = JArray.Parse(value.ToString());
|
||||
if (array != null && array.Count > 0)
|
||||
{
|
||||
var subObject = JObject.Parse(array.First.ToString());
|
||||
if (subObject != null)
|
||||
{
|
||||
if (subObject.TryGetValue(subProperty, out value))
|
||||
{
|
||||
return value.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
80
Yavsc/src/Auth/GoogleMiddleWare.cs
Normal file
80
Yavsc/src/Auth/GoogleMiddleWare.cs
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
// Copyright (c) .NET Foundation. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNet.Authentication;
|
||||
using Microsoft.AspNet.Authentication.OAuth;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.DataProtection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.OptionsModel;
|
||||
using Microsoft.Extensions.WebEncoders;
|
||||
namespace Yavsc.Auth
|
||||
{
|
||||
/// <summary>
|
||||
/// An ASP.NET Core middleware for authenticating users using Google OAuth 2.0.
|
||||
/// </summary>
|
||||
public class GoogleMiddleware : OAuthMiddleware<GoogleOptions>
|
||||
{
|
||||
private RequestDelegate _next;
|
||||
private ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="GoogleMiddleware"/>.
|
||||
/// </summary>
|
||||
/// <param name="next">The next middleware in the HTTP pipeline to invoke.</param>
|
||||
/// <param name="dataProtectionProvider"></param>
|
||||
/// <param name="loggerFactory"></param>
|
||||
/// <param name="encoder"></param>
|
||||
/// <param name="sharedOptions"></param>
|
||||
/// <param name="options">Configuration options for the middleware.</param>
|
||||
public GoogleMiddleware(
|
||||
RequestDelegate next,
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
ILoggerFactory loggerFactory,
|
||||
UrlEncoder encoder,
|
||||
IOptions<SharedAuthenticationOptions> sharedOptions,
|
||||
GoogleOptions options)
|
||||
: base(next, dataProtectionProvider, loggerFactory, encoder, sharedOptions, options)
|
||||
{
|
||||
if (next == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(next));
|
||||
}
|
||||
_next = next;
|
||||
|
||||
if (dataProtectionProvider == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(dataProtectionProvider));
|
||||
}
|
||||
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
_logger = loggerFactory.CreateLogger<GoogleMiddleware>();
|
||||
|
||||
if (encoder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(encoder));
|
||||
}
|
||||
|
||||
if (sharedOptions == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(sharedOptions));
|
||||
}
|
||||
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected override AuthenticationHandler<GoogleOptions> CreateHandler()
|
||||
{
|
||||
return new GoogleHandler(Backchannel,_logger);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
27
Yavsc/src/Auth/GoogleOAuthCreatingTicket.cs
Normal file
27
Yavsc/src/Auth/GoogleOAuthCreatingTicket.cs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
using System.Net.Http;
|
||||
using Microsoft.AspNet.Authentication;
|
||||
using Microsoft.AspNet.Authentication.OAuth;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Yavsc.Auth {
|
||||
|
||||
|
||||
public class GoogleOAuthCreatingTicketContext : OAuthCreatingTicketContext {
|
||||
public GoogleOAuthCreatingTicketContext(HttpContext context, OAuthOptions options,
|
||||
HttpClient backchannel, OAuthTokenResponse tokens, AuthenticationTicket ticket, string googleUserId )
|
||||
: base( context, options, backchannel, tokens )
|
||||
{
|
||||
_ticket = ticket;
|
||||
_googleUserId = googleUserId;
|
||||
Principal = ticket.Principal;
|
||||
}
|
||||
AuthenticationTicket _ticket;
|
||||
string _googleUserId;
|
||||
|
||||
public AuthenticationTicket Ticket { get { return _ticket; } }
|
||||
|
||||
public string GoogleUserId { get { return _googleUserId; } }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
44
Yavsc/src/Auth/GoogleOptions.cs
Normal file
44
Yavsc/src/Auth/GoogleOptions.cs
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
using Microsoft.AspNet.Authentication.OAuth;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Yavsc.Auth
|
||||
{
|
||||
public static class GoogleDefaults
|
||||
{
|
||||
public const string AuthenticationScheme = "Google";
|
||||
|
||||
public static readonly string AuthorizationEndpoint = "https://accounts.google.com/o/oauth2/auth";
|
||||
|
||||
public static readonly string TokenEndpoint = "https://www.googleapis.com/oauth2/v3/token";
|
||||
|
||||
public static readonly string UserInformationEndpoint = "https://www.googleapis.com/plus/v1/people/me";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configuration options for <see cref="GoogleMiddleware"/>.
|
||||
/// </summary>
|
||||
public class GoogleOptions : OAuthOptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new <see cref="GoogleOptions"/>.
|
||||
/// </summary>
|
||||
public GoogleOptions()
|
||||
{
|
||||
AuthenticationScheme = GoogleDefaults.AuthenticationScheme;
|
||||
DisplayName = AuthenticationScheme;
|
||||
CallbackPath = new PathString("/signin-google");
|
||||
AuthorizationEndpoint = GoogleDefaults.AuthorizationEndpoint;
|
||||
TokenEndpoint = GoogleDefaults.TokenEndpoint;
|
||||
UserInformationEndpoint = GoogleDefaults.UserInformationEndpoint;
|
||||
Scope.Add("openid");
|
||||
Scope.Add("profile");
|
||||
Scope.Add("email");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// access_type. Set to 'offline' to request a refresh token.
|
||||
/// </summary>
|
||||
public string AccessType { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
35
Yavsc/src/Auth/MonoDataProtectionProvider.cs
Normal file
35
Yavsc/src/Auth/MonoDataProtectionProvider.cs
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
|
||||
|
||||
using System;
|
||||
using Microsoft.AspNet.DataProtection;
|
||||
namespace Yavsc.Auth
|
||||
{
|
||||
public class MonoDataProtectionProvider : IDataProtectionProvider
|
||||
{
|
||||
private readonly string appName;
|
||||
|
||||
public MonoDataProtectionProvider()
|
||||
: this(Guid.NewGuid().ToString())
|
||||
{ }
|
||||
|
||||
public MonoDataProtectionProvider(string appName)
|
||||
{
|
||||
if (appName == null) { throw new ArgumentNullException("appName"); }
|
||||
|
||||
this.appName = appName;
|
||||
}
|
||||
|
||||
public IDataProtector Create(params string[] purposes)
|
||||
{
|
||||
if (purposes == null) { throw new ArgumentNullException("purposes"); }
|
||||
|
||||
return new MonoDataProtector(appName, purposes);
|
||||
}
|
||||
|
||||
public IDataProtector CreateProtector(string purpose)
|
||||
{
|
||||
return Create(new string[] {purpose});
|
||||
}
|
||||
}
|
||||
}
|
||||
87
Yavsc/src/Auth/MonoDataProtector.cs
Normal file
87
Yavsc/src/Auth/MonoDataProtector.cs
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
//
|
||||
// MonoDataProtector.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paul@pschneider.fr>
|
||||
//
|
||||
// Copyright (c) 2016 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.Security.Cryptography;
|
||||
using System.IO;
|
||||
using Microsoft.AspNet.DataProtection;
|
||||
using System.Linq;
|
||||
|
||||
namespace Yavsc.Auth
|
||||
{
|
||||
public class MonoDataProtector : IDataProtector
|
||||
{
|
||||
private const string PRIMARY_PURPOSE = "Microsoft.Owin.Security.IDataProtector";
|
||||
|
||||
private readonly string appName;
|
||||
private readonly DataProtectionScope dataProtectionScope;
|
||||
private readonly string[] purposes;
|
||||
|
||||
public MonoDataProtector(string appName, string[] purposes)
|
||||
{
|
||||
if (appName == null) { throw new ArgumentNullException("appName"); }
|
||||
if (purposes == null) { throw new ArgumentNullException("purposes"); }
|
||||
|
||||
this.appName = appName;
|
||||
this.purposes = purposes;
|
||||
this.dataProtectionScope = DataProtectionScope.CurrentUser;
|
||||
}
|
||||
|
||||
public IDataProtector CreateProtector(string purpose)
|
||||
{
|
||||
if (purposes.Contains(purpose))
|
||||
return new MonoDataProtector(appName,new string[] {purpose});
|
||||
return new MonoDataProtector(appName,new string[] {});
|
||||
}
|
||||
|
||||
public byte[] Protect(byte[] userData)
|
||||
{
|
||||
return ProtectedData.Protect(userData, this.GetEntropy(), dataProtectionScope);
|
||||
}
|
||||
|
||||
public byte[] Unprotect(byte[] protectedData)
|
||||
{
|
||||
return ProtectedData.Unprotect(protectedData, this.GetEntropy(), dataProtectionScope);
|
||||
}
|
||||
|
||||
private byte[] GetEntropy()
|
||||
{
|
||||
using (SHA256 sha256 = SHA256.Create())
|
||||
{
|
||||
using (MemoryStream memoryStream = new MemoryStream())
|
||||
using (CryptoStream cryptoStream = new CryptoStream(memoryStream, sha256, CryptoStreamMode.Write))
|
||||
using (StreamWriter writer = new StreamWriter(cryptoStream))
|
||||
{
|
||||
writer.Write(this.appName);
|
||||
writer.Write(PRIMARY_PURPOSE);
|
||||
|
||||
foreach (string purpose in this.purposes)
|
||||
{
|
||||
writer.Write(purpose);
|
||||
}
|
||||
}
|
||||
|
||||
return sha256.Hash;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
101
Yavsc/src/Auth/RSAKeyUtils.cs
Normal file
101
Yavsc/src/Auth/RSAKeyUtils.cs
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Yavsc
|
||||
{
|
||||
public class RSAKeyUtils
|
||||
{
|
||||
public static RSAParameters GetRandomKey()
|
||||
{
|
||||
using (var rsa = new RSACryptoServiceProvider(2048))
|
||||
{
|
||||
try
|
||||
{
|
||||
return rsa.ExportParameters(true);
|
||||
}
|
||||
finally
|
||||
{
|
||||
rsa.PersistKeyInCsp = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static RSAParameters GenerateKeyAndSave(string file)
|
||||
{
|
||||
var p = GetRandomKey();
|
||||
RSAParametersWithPrivate t = new RSAParametersWithPrivate();
|
||||
t.SetParameters(p);
|
||||
File.WriteAllText(file, JsonConvert.SerializeObject(t));
|
||||
return p;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This expects a file in the format:
|
||||
/// {
|
||||
/// "Modulus": "z7eXmrs9z3Xm7VXwYIdziDYzXGfi3XQiozIRa58m3ApeLVDcsDeq6Iv8C5zJ2DHydDyc0x6o5dtTRIb23r5/ZRj4I/UwbgrwMk5iHA0bVsXVPBDSWsrVcPDGafr6YbUNQnNWIF8xOqgpeTwxrqGiCJMUjuKyUx01PBzpBxjpnQ++Ryz6Y7MLqKHxBkDiOw5wk9cxO8/IMspSNJJosOtRXFTR74+bj+pvNBa8IJ+5Jf/UfJEEjk+qC+pohCAryRk0ziXcPdxXEv5KGT4zf3LdtHy1YwsaGLnTb62vgbdqqCJaVyHWOoXsDTQBLjxNl9o9CzP6CrfBGK6JV8pA/xfQlw==",
|
||||
/// "Exponent": "AQAB",
|
||||
/// "P": "+VsETS2exORYlg2CxaRMzyG60dTfHSuv0CsfmO3PFv8mcYxglGa6bUV5VGtB6Pd1HdtV/iau1WR/hYXQphCP99Pu803NZvFvVi34alTFbh0LMfZ+2iQ9toGzVfO8Qdbj7go4TWoHNzCpG4UCx/9wicVIWJsNzkppSEcXYigADMM=",
|
||||
/// "Q": "1UCJ2WAHasiCdwJtV2Ep0VCK3Z4rVFLWg3q1v5OoOU1CkX5/QAcrr6bX6zOdHR1bDCPsH1n1E9cCMvwakgi9M4Ch0dYF5CxDKtlx+IGsZJL0gB6HhcEsHat+yXUtOAlS4YB82G1hZqiDw+Q0O8LGyu/gLDPB+bn0HmbkUC2kP50=",
|
||||
/// "DP": "CBqvLxr2eAu73VSfFXFblbfQ7JTwk3AiDK/6HOxNuL+eLj6TvP8BvB9v7BB4WewBAHFqgBIdyI21n09UErGjHDjlIT88F8ZtCe4AjuQmboe/H2aVhN18q/vXKkn7qmAjlE78uXdiuKZ6OIzAJGPm8nNZAJg5gKTmexTka6pFJiU=",
|
||||
/// "DQ": "ND6zhwX3yzmEfROjJh0v2ZAZ9WGiy+3fkCaoEF9kf2VmQa70DgOzuDzv+TeT7mYawEasuqGXYVzztPn+qHhrogqJmpcMqnINopnTSka6rYkzTZAtM5+35yz0yvZiNbBTFdwcuglSK4xte7iU828stNs/2JR1mXDtVeVvWhVUgCE=",
|
||||
/// "InverseQ": "Heo0BHv685rvWreFcI5MXSy3AN0Zs0YbwAYtZZd1K/OzFdYVdOnqw+Dg3wGU9yFD7h4icJFwZUBGOZ0ww/gZX/5ZgJK35/YY/DeV+qfZmywKauUzC6+DPsrDdW1uf1eAety6/huRZTduBFTwIOlPdZ+PY49j6S38DjPFNImn0cU=",
|
||||
/// "D": "IvjMI5cGzxkQqkDf2cC0aOiHOTWccqCM/GD/odkH1+A+/u4wWdLliYWYB/R731R5d6yE0t7EnP6SRGVcxx/XnxPXI2ayorRgwHeF+ScTxUZFonlKkVK5IOzI2ysQYMb01o1IoOamCTQq12iVDMvV1g+9VFlCoM+4GMjdSv6cxn6ELabuD4nWt8tCskPjECThO+WdrknbUTppb2rRgMvNKfsPuF0H7+g+WisbzVS+UVRvJe3U5O5X5j7Z82Uq6hw2NCwv2YhQZRo/XisFZI7yZe0OU2JkXyNG3NCk8CgsM9yqX8Sk5esXMZdJzjwXtEpbR7FiKZXiz9LhPSmzxz/VsQ=="
|
||||
/// }
|
||||
///
|
||||
/// Generate
|
||||
/// </summary>
|
||||
/// <param name="file"></param>
|
||||
/// <returns></returns>
|
||||
public static RSAParameters GetKeyParameters(string file)
|
||||
{
|
||||
if (!File.Exists(file)) throw new FileNotFoundException("Check configuration - cannot find auth key file: " + file);
|
||||
var keyParams = JsonConvert.DeserializeObject<RSAParametersWithPrivate>(File.ReadAllText(file));
|
||||
return keyParams.ToRSAParameters();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Util class to allow restoring RSA parameters from JSON as the normal
|
||||
/// RSA parameters class won't restore private key info.
|
||||
/// </summary>
|
||||
private class RSAParametersWithPrivate
|
||||
{
|
||||
public byte[] D { get; set; }
|
||||
public byte[] DP { get; set; }
|
||||
public byte[] DQ { get; set; }
|
||||
public byte[] Exponent { get; set; }
|
||||
public byte[] InverseQ { get; set; }
|
||||
public byte[] Modulus { get; set; }
|
||||
public byte[] P { get; set; }
|
||||
public byte[] Q { get; set; }
|
||||
|
||||
public void SetParameters(RSAParameters p)
|
||||
{
|
||||
D = p.D;
|
||||
DP = p.DP;
|
||||
DQ = p.DQ;
|
||||
Exponent = p.Exponent;
|
||||
InverseQ = p.InverseQ;
|
||||
Modulus = p.Modulus;
|
||||
P = p.P;
|
||||
Q = p.Q;
|
||||
}
|
||||
public RSAParameters ToRSAParameters()
|
||||
{
|
||||
return new RSAParameters()
|
||||
{
|
||||
D = this.D,
|
||||
DP = this.DP,
|
||||
DQ = this.DQ,
|
||||
Exponent = this.Exponent,
|
||||
InverseQ = this.InverseQ,
|
||||
Modulus = this.Modulus,
|
||||
P = this.P,
|
||||
Q = this.Q
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
Yavsc/src/Auth/RequiredScopesMiddleware.cs
Normal file
57
Yavsc/src/Auth/RequiredScopesMiddleware.cs
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Http;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Api
|
||||
{
|
||||
public class RequiredScopesMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private readonly IEnumerable<string> _requiredScopes;
|
||||
|
||||
public RequiredScopesMiddleware(RequestDelegate next, IList<string> requiredScopes)
|
||||
{
|
||||
_next = next;
|
||||
_requiredScopes = requiredScopes;
|
||||
}
|
||||
|
||||
public async Task Invoke(HttpContext context)
|
||||
{
|
||||
if (context.User.Identity.IsAuthenticated)
|
||||
{
|
||||
if (!ScopePresent(context.User))
|
||||
{
|
||||
context.Response.OnCompleted(Send403, context);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
await _next(context);
|
||||
}
|
||||
|
||||
private bool ScopePresent(ClaimsPrincipal principal)
|
||||
{
|
||||
foreach (var scope in principal.FindAll("scope"))
|
||||
{
|
||||
if (_requiredScopes.Contains(scope.Value))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private Task Send403(object contextObject)
|
||||
{
|
||||
var context = contextObject as HttpContext;
|
||||
context.Response.StatusCode = 403;
|
||||
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
11
Yavsc/src/Auth/TokenAuthOptions.cs
Normal file
11
Yavsc/src/Auth/TokenAuthOptions.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
using System.IdentityModel.Tokens;
|
||||
|
||||
namespace Yavsc
|
||||
{
|
||||
public class TokenAuthOptions
|
||||
{
|
||||
public string Audience { get; set; }
|
||||
public string Issuer { get; set; }
|
||||
public SigningCredentials SigningCredentials { get; set; }
|
||||
}
|
||||
}
|
||||
36
Yavsc/src/Auth/UserTokenProvider.cs
Normal file
36
Yavsc/src/Auth/UserTokenProvider.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.DataProtection;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Yavsc.Models;
|
||||
|
||||
namespace Yavsc.Auth {
|
||||
|
||||
public class UserTokenProvider : Microsoft.AspNet.Identity.IUserTokenProvider<ApplicationUser>
|
||||
{
|
||||
|
||||
public Task<bool> CanGenerateTwoFactorTokenAsync(UserManager<ApplicationUser> manager, ApplicationUser user)
|
||||
{
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
public Task<string> GenerateAsync(string purpose, UserManager<ApplicationUser> manager, ApplicationUser user)
|
||||
{
|
||||
var por = new MonoDataProtector(Constants.ApplicationName,new string[] { purpose } );
|
||||
|
||||
return Task.FromResult(por.Protect(UserStamp(user)));
|
||||
}
|
||||
|
||||
public Task<bool> ValidateAsync(string purpose, string token, UserManager<ApplicationUser> manager, ApplicationUser user)
|
||||
{
|
||||
var por = new MonoDataProtector(Constants.ApplicationName,new string[] { purpose } );
|
||||
var userStamp = por.Unprotect(token);
|
||||
string [] values = userStamp.Split(' ');
|
||||
return Task.FromResult ( user.Id == values[0] && user.Email == values[1] && user.UserName == values[2]);
|
||||
}
|
||||
|
||||
public string UserStamp(ApplicationUser user) {
|
||||
return $"{user.Id} {user.Email} {user.UserName}";
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Yavsc/src/Auth/XmlEncryptor.cs
Normal file
23
Yavsc/src/Auth/XmlEncryptor.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
|
||||
|
||||
using System;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.AspNet.DataProtection.XmlEncryption;
|
||||
|
||||
namespace Yavsc.Auth {
|
||||
|
||||
public class MonoXmlEncryptor : IXmlEncryptor
|
||||
{
|
||||
public MonoXmlEncryptor (IServiceProvider serviceProvider)
|
||||
{
|
||||
}
|
||||
public EncryptedXmlInfo Encrypt(XElement plaintextElement)
|
||||
{
|
||||
var result = new EncryptedXmlInfo(plaintextElement,
|
||||
typeof(MonoDataProtector));
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
147
Yavsc/src/Auth/Yavsc/YavscAuthenticationHandler.cs
Normal file
147
Yavsc/src/Auth/Yavsc/YavscAuthenticationHandler.cs
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
//
|
||||
// YavscAuthenticationHandler.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paul@pschneider.fr>
|
||||
//
|
||||
// Copyright (c) 2016 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.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yavsc.Authentication
|
||||
{
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using Microsoft.AspNet.Authentication;
|
||||
using Microsoft.AspNet.Authentication.OAuth;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Http.Authentication;
|
||||
using Microsoft.AspNet.Http.Features.Authentication;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
public static class YavscAuthenticationExtensions
|
||||
{
|
||||
}
|
||||
|
||||
class YavscAuthenticationHandler : OAuthHandler<YavscAuthenticationOptions>
|
||||
{
|
||||
private ILogger _logger;
|
||||
private HttpClient _backchannel;
|
||||
|
||||
public YavscAuthenticationHandler(HttpClient backchannel, ILogger logger) : base (backchannel)
|
||||
{
|
||||
_backchannel = backchannel;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
protected new async Task<AuthenticationTicket> AuthenticateAsync(AuthenticateContext context)
|
||||
{
|
||||
AuthenticationProperties properties = null;
|
||||
|
||||
try
|
||||
{
|
||||
// ASP.Net Identity requires the NameIdentitifer field to be set or it won't
|
||||
// accept the external login (AuthenticationManagerExtensions.GetExternalLoginInfo)
|
||||
|
||||
string code = null;
|
||||
string state = null;
|
||||
|
||||
IReadableStringCollection query = Request.Query;
|
||||
IList<string> values = query["code"];
|
||||
if (values != null && values.Count == 1)
|
||||
{
|
||||
code = values[0];
|
||||
}
|
||||
values = query["state"];
|
||||
if (values != null && values.Count == 1)
|
||||
{
|
||||
state = values[0];
|
||||
}
|
||||
|
||||
properties = Options.StateDataFormat.Unprotect(state);
|
||||
if (properties == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// OAuth2 10.12 CSRF
|
||||
if (!ValidateCorrelationId(properties))
|
||||
{
|
||||
return new AuthenticationTicket(null, properties, this.Options.AuthenticationScheme);
|
||||
}
|
||||
|
||||
string requestPrefix = Request.Scheme + "://" + Request.Host;
|
||||
string redirectUri = requestPrefix + Request.PathBase + Options.CallbackPath;
|
||||
|
||||
// Build up the body for the token request
|
||||
var body = new List<KeyValuePair<string, string>>();
|
||||
body.Add(new KeyValuePair<string, string>("grant_type", "authorization_code"));
|
||||
body.Add(new KeyValuePair<string, string>("code", code));
|
||||
body.Add(new KeyValuePair<string, string>("redirect_uri", redirectUri));
|
||||
body.Add(new KeyValuePair<string, string>("client_id", Options.ClientId));
|
||||
body.Add(new KeyValuePair<string, string>("client_secret", Options.ClientSecret));
|
||||
|
||||
// Request the token
|
||||
HttpResponseMessage tokenResponse =
|
||||
await _backchannel.PostAsync(Options.TokenEndpoint, new FormUrlEncodedContent(body));
|
||||
tokenResponse.EnsureSuccessStatusCode();
|
||||
string text = await tokenResponse.Content.ReadAsStringAsync();
|
||||
|
||||
// Deserializes the token response
|
||||
JObject response = JObject.Parse(text);
|
||||
string accessToken = response.Value<string>("access_token");
|
||||
|
||||
if (string.IsNullOrWhiteSpace(accessToken))
|
||||
{
|
||||
_logger.LogWarning("Access token was not found");
|
||||
return new AuthenticationTicket(null, properties, this.Options.AuthenticationScheme);
|
||||
}
|
||||
|
||||
// Get the user
|
||||
HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, Options.UserInformationEndpoint);
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue(this.Options.AuthenticationScheme, accessToken);
|
||||
HttpResponseMessage graphResponse = await _backchannel.SendAsync(request);
|
||||
graphResponse.EnsureSuccessStatusCode();
|
||||
text = await graphResponse.Content.ReadAsStringAsync();
|
||||
JObject user = JObject.Parse(text);
|
||||
// Read user data
|
||||
|
||||
var id = new ClaimsIdentity(
|
||||
Options.SignInAsAuthenticationType,
|
||||
ClaimsIdentity.DefaultNameClaimType,
|
||||
ClaimsIdentity.DefaultRoleClaimType);
|
||||
context.Authenticated(new ClaimsPrincipal(id)
|
||||
, new Dictionary<string,string>(), new Dictionary<string,object>{
|
||||
{ "John" , (object) "Doe" }
|
||||
});
|
||||
return new AuthenticationTicket(context.Principal, properties, Options.SignInAsAuthenticationType);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError("Authentication failed", ex);
|
||||
return new AuthenticationTicket(null, properties, this.Options.AuthenticationScheme);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
102
Yavsc/src/Auth/Yavsc/YavscAuthenticationMiddleware.cs
Normal file
102
Yavsc/src/Auth/Yavsc/YavscAuthenticationMiddleware.cs
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
//
|
||||
// YavscAuthenticationMiddleware.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paul@pschneider.fr>
|
||||
//
|
||||
// Copyright (c) 2016 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 Microsoft.AspNet.Authentication;
|
||||
using Microsoft.AspNet.Authentication.OAuth;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.DataProtection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.OptionsModel;
|
||||
using Microsoft.Extensions.WebEncoders;
|
||||
|
||||
namespace Yavsc.Authentication
|
||||
{
|
||||
public class YavscAuthenticationMiddleware : OAuthMiddleware<YavscAuthenticationOptions>
|
||||
{
|
||||
RequestDelegate _next;
|
||||
ILogger _logger;
|
||||
|
||||
public YavscAuthenticationMiddleware(
|
||||
RequestDelegate next,
|
||||
IDataProtectionProvider dataProtectionProvider,
|
||||
ILoggerFactory loggerFactory,
|
||||
UrlEncoder encoder,
|
||||
IOptions<SharedAuthenticationOptions> sharedOptions,
|
||||
YavscAuthenticationOptions options)
|
||||
: base(next, dataProtectionProvider, loggerFactory, encoder, sharedOptions, options)
|
||||
{
|
||||
|
||||
if (next == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(next));
|
||||
}
|
||||
_next = next;
|
||||
|
||||
if (dataProtectionProvider == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(dataProtectionProvider));
|
||||
}
|
||||
|
||||
if (loggerFactory == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(loggerFactory));
|
||||
}
|
||||
_logger = loggerFactory.CreateLogger<YavscAuthenticationMiddleware>();
|
||||
|
||||
if (encoder == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(encoder));
|
||||
}
|
||||
|
||||
if (sharedOptions == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(sharedOptions));
|
||||
}
|
||||
|
||||
if (options == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(options));
|
||||
}
|
||||
|
||||
if(string.IsNullOrEmpty(options.SignInAsAuthenticationType))
|
||||
{
|
||||
options.SignInAsAuthenticationType = sharedOptions.Value.SignInScheme;
|
||||
}
|
||||
|
||||
if(options.StateDataFormat == null)
|
||||
{
|
||||
var dataProtector = dataProtectionProvider.CreateProtector(typeof(YavscAuthenticationMiddleware).FullName,
|
||||
options.AuthenticationScheme);
|
||||
|
||||
options.StateDataFormat = new PropertiesDataFormat(dataProtector);
|
||||
}
|
||||
}
|
||||
|
||||
// Called for each request, to create a handler for each request.
|
||||
protected override AuthenticationHandler<YavscAuthenticationOptions> CreateHandler()
|
||||
{
|
||||
return new YavscAuthenticationHandler(this.Backchannel,_logger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
62
Yavsc/src/Auth/Yavsc/YavscAuthenticationMiddlewareOptions.cs
Normal file
62
Yavsc/src/Auth/Yavsc/YavscAuthenticationMiddlewareOptions.cs
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
//
|
||||
// YavscAuthenticationMiddlewareOptions.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paul@pschneider.fr>
|
||||
//
|
||||
// Copyright (c) 2016 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 Microsoft.AspNet.Authentication.OAuth;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Yavsc.Authentication
|
||||
{
|
||||
|
||||
public class YavscAuthenticationOptions: OAuthOptions
|
||||
{
|
||||
public YavscAuthenticationOptions()
|
||||
{}
|
||||
|
||||
public YavscAuthenticationOptions(string authType, string clientId, string clientSecret)
|
||||
{
|
||||
if (authType == null)
|
||||
throw new NotSupportedException();
|
||||
Description.AuthenticationScheme = authType;
|
||||
ClientId = clientId;
|
||||
ClientSecret = clientSecret;
|
||||
SignInAsAuthenticationType = authType;
|
||||
Scope.Clear();
|
||||
}
|
||||
public PathString TokenPath { get; set; }
|
||||
public PathString AuthorizePath { get; set; }
|
||||
|
||||
public PathString ReturnUrl { get; set; }
|
||||
public PathString LoginPath { get; set; }
|
||||
public PathString LogoutPath { get; set; }
|
||||
|
||||
internal string AuthenticationServerUri = "https://accounts.google.com/o/oauth2/auth";
|
||||
internal string TokenServerUri = "https://accounts.google.com/o/oauth2/token";
|
||||
|
||||
private string signInAsAuthenticationType = null;
|
||||
public string SignInAsAuthenticationType { get
|
||||
{ return signInAsAuthenticationType ; }
|
||||
set { signInAsAuthenticationType = value;
|
||||
ReturnUrl = new PathString("/signin-"+signInAsAuthenticationType.ToLower());
|
||||
} }
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
111
Yavsc/src/AuthorisationHandlers.cs
Normal file
111
Yavsc/src/AuthorisationHandlers.cs
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
using System;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using Yavsc.Models;
|
||||
|
||||
namespace Yavsc {
|
||||
public class PrivateChatEntryRequirement : IAuthorizationRequirement
|
||||
{
|
||||
}
|
||||
|
||||
public class EditRequirement : IAuthorizationRequirement
|
||||
{
|
||||
public EditRequirement()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public class ViewRequirement : IAuthorizationRequirement
|
||||
{
|
||||
public ViewRequirement()
|
||||
{
|
||||
}
|
||||
}
|
||||
public class BlogEditHandler : AuthorizationHandler<EditRequirement, Blog>
|
||||
{
|
||||
protected override void Handle(AuthorizationContext context, EditRequirement requirement, Blog resource)
|
||||
{
|
||||
if (context.User.IsInRole("Moderator"))
|
||||
context.Succeed(requirement);
|
||||
else if (context.User.Identity.IsAuthenticated)
|
||||
if (resource.AuthorId == context.User.GetUserId())
|
||||
context.Succeed(requirement);
|
||||
}
|
||||
|
||||
}
|
||||
public class BlogViewHandler : AuthorizationHandler<ViewRequirement, Blog>
|
||||
{
|
||||
protected override void Handle(AuthorizationContext context, ViewRequirement requirement, Blog resource)
|
||||
{
|
||||
if (context.User.IsInRole("Moderator"))
|
||||
context.Succeed(requirement);
|
||||
else if (context.User.Identity.IsAuthenticated)
|
||||
if (resource.AuthorId == context.User.GetUserId())
|
||||
context.Succeed(requirement);
|
||||
// TODO else if (resource.Circles && context.User belongs to
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class CommandViewHandler : AuthorizationHandler<ViewRequirement, Command>
|
||||
{
|
||||
protected override void Handle(AuthorizationContext context, ViewRequirement requirement, Command resource)
|
||||
{
|
||||
if (context.User.IsInRole("FrontOffice"))
|
||||
context.Succeed(requirement);
|
||||
else if (context.User.Identity.IsAuthenticated)
|
||||
if (resource.ClientId == context.User.GetUserId())
|
||||
context.Succeed(requirement);
|
||||
else if (resource.PerformerId == context.User.GetUserId())
|
||||
context.Succeed(requirement);
|
||||
}
|
||||
|
||||
}
|
||||
public class CommandEditHandler : AuthorizationHandler<EditRequirement, Command>
|
||||
{
|
||||
protected override void Handle(AuthorizationContext context, EditRequirement requirement, Command resource)
|
||||
{
|
||||
if (context.User.IsInRole("FrontOffice"))
|
||||
context.Succeed(requirement);
|
||||
else if (context.User.Identity.IsAuthenticated)
|
||||
if (resource.ClientId == context.User.GetUserId())
|
||||
context.Succeed(requirement);
|
||||
}
|
||||
|
||||
}
|
||||
public class HasTemporaryPassHandler : AuthorizationHandler<PrivateChatEntryRequirement>
|
||||
{
|
||||
protected override void Handle(AuthorizationContext context, PrivateChatEntryRequirement requirement)
|
||||
{
|
||||
if (!context.User.HasClaim(c => c.Type == "TemporaryBadgeExpiry" &&
|
||||
c.Issuer == Constants.Issuer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var temporaryBadgeExpiry =
|
||||
Convert.ToDateTime(context.User.FindFirst(
|
||||
c => c.Type == "TemporaryBadgeExpiry" &&
|
||||
c.Issuer == Constants.Issuer).Value);
|
||||
|
||||
if (temporaryBadgeExpiry > DateTime.Now)
|
||||
{
|
||||
context.Succeed(requirement);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class HasBadgeHandler : AuthorizationHandler<PrivateChatEntryRequirement>
|
||||
{
|
||||
protected override void Handle(AuthorizationContext context, PrivateChatEntryRequirement requirement)
|
||||
{
|
||||
if (!context.User.HasClaim(c => c.Type == "BadgeNumber" &&
|
||||
c.Issuer == Constants.Issuer))
|
||||
{
|
||||
return;
|
||||
}
|
||||
context.Succeed(requirement);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
12
Yavsc/src/ClaimTypes.cs
Normal file
12
Yavsc/src/ClaimTypes.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
|
||||
|
||||
namespace Yavsc {
|
||||
|
||||
|
||||
internal static class YavscClaimTypes {
|
||||
|
||||
public const string GoogleUserId = "GoogleUserId";
|
||||
}
|
||||
|
||||
}
|
||||
43
Yavsc/src/Constants.cs
Normal file
43
Yavsc/src/Constants.cs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
namespace Yavsc
|
||||
{
|
||||
using Yavsc.Models.Auth;
|
||||
|
||||
public static class Constants
|
||||
{
|
||||
public const string RememberMeCookieName = "Berme";
|
||||
public static readonly Scope[] SiteScopes = {
|
||||
new Scope { Id = "profile", Description = "Your profile informations" },
|
||||
new Scope { Id = "book" , Description ="Your booking interface"},
|
||||
new Scope { Id = "blog" , Description ="Your blogging interface"},
|
||||
new Scope { Id = "estimate" , Description ="Your estimation interface"},
|
||||
new Scope { Id = "contract" , Description ="Your contract signature access"},
|
||||
new Scope { Id = "admin" , Description ="Your administration rights on this site"},
|
||||
new Scope { Id = "moderation" , Description ="Your moderator interface"},
|
||||
new Scope { Id = "frontoffice" , Description ="Your front office interface" }
|
||||
};
|
||||
|
||||
public const string CompanyInfoUrl = " https://societeinfo.com/app/rest/api/v1/company/json?registration_number={0}&key={1}";
|
||||
public const string DefaultFactor = "Default";
|
||||
public const string MobileAppFactor = "Google.clood";
|
||||
public const string EMailFactor = "Email";
|
||||
public const string SMSFactor = "Phone";
|
||||
public const string AdminGroupName = "Administrator";
|
||||
public const string FrontOfficeGroupName = "FrontOffice";
|
||||
public const string UserBlogFilesDir= "Blog";
|
||||
public const string UserBillsFilesDir= "Bills";
|
||||
|
||||
public const string UserFilesRequestPath = "/UserFiles";
|
||||
public const string GCMNotificationUrl = "https://gcm-http.googleapis.com/gcm/send";
|
||||
private static readonly string[] GoogleScopes = { "openid", "profile", "email" };
|
||||
|
||||
public static readonly string[] GoogleCalendarScopes =
|
||||
{ "openid", "profile", "email", "https://www.googleapis.com/auth/calendar" };
|
||||
public const string ApplicationName = "Yavsc";
|
||||
|
||||
public const string Issuer = "https://dev.pschneider.fr";
|
||||
|
||||
public const string CompanyClaimType = "https://schemas.pschneider.fr/identity/claims/Company";
|
||||
|
||||
public const string UserNameRegExp = @"^[a-zA-Z][a-zA-Z0-9 ]*$";
|
||||
}
|
||||
}
|
||||
518
Yavsc/src/Controllers/AccountController.cs
Normal file
518
Yavsc/src/Controllers/AccountController.cs
Normal file
|
|
@ -0,0 +1,518 @@
|
|||
|
||||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Mvc.Rendering;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.OptionsModel;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Services;
|
||||
using Yavsc.ViewModels.Account;
|
||||
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
[AllowAnonymous]
|
||||
[ServiceFilter(typeof(LanguageActionFilter))]
|
||||
public class AccountController : Controller
|
||||
{
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
private readonly SignInManager<ApplicationUser> _signInManager;
|
||||
private readonly IEmailSender _emailSender;
|
||||
// private readonly ISmsSender _smsSender;
|
||||
private readonly ILogger _logger;
|
||||
SiteSettings _siteSettings;
|
||||
SmtpSettings _smtpSettings;
|
||||
TwilioSettings _twilioSettings;
|
||||
|
||||
// TwilioSettings _twilioSettings;
|
||||
|
||||
public AccountController(
|
||||
UserManager<ApplicationUser> userManager,
|
||||
SignInManager<ApplicationUser> signInManager,
|
||||
IEmailSender emailSender,
|
||||
IOptions<SiteSettings> siteSettings,
|
||||
IOptions<SmtpSettings> smtpSettings,
|
||||
ILoggerFactory loggerFactory, IOptions<TwilioSettings> twilioSettings)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_signInManager = signInManager;
|
||||
// _userManager.RegisterTokenProvider("SMS",new UserTokenProvider());
|
||||
// _userManager.RegisterTokenProvider("Phone", new UserTokenProvider());
|
||||
_emailSender = emailSender;
|
||||
_siteSettings = siteSettings.Value;
|
||||
_smtpSettings = smtpSettings.Value;
|
||||
_twilioSettings = twilioSettings.Value;
|
||||
_logger = loggerFactory.CreateLogger<AccountController>();
|
||||
}
|
||||
|
||||
//
|
||||
// GET: /Account/Login
|
||||
[HttpGet]
|
||||
public IActionResult Login(string returnUrl = null)
|
||||
{
|
||||
ViewData["ReturnUrl"] = returnUrl;
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult Forbidden()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
// POST: /Account/Login
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null)
|
||||
{
|
||||
ViewData["ReturnUrl"] = returnUrl;
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
|
||||
// This doesn't count login failures towards account lockout
|
||||
// To enable password failures to trigger account lockout, set lockoutOnFailure: true
|
||||
var result = await _signInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, lockoutOnFailure: false);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
_logger.LogInformation(1, "User logged in.");
|
||||
|
||||
return RedirectToLocal(returnUrl);
|
||||
}
|
||||
if (result.RequiresTwoFactor)
|
||||
{
|
||||
return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe });
|
||||
}
|
||||
if (result.IsLockedOut)
|
||||
{
|
||||
_logger.LogWarning(2, "User account locked out.");
|
||||
return View("Lockout");
|
||||
}
|
||||
else
|
||||
{
|
||||
ModelState.AddModelError(string.Empty, "Invalid login attempt.");
|
||||
return View(model);
|
||||
}
|
||||
}
|
||||
|
||||
// If we got this far, something failed, redisplay form
|
||||
return View(model);
|
||||
}
|
||||
|
||||
//
|
||||
// GET: /Account/Register
|
||||
[HttpGet]
|
||||
public IActionResult Register()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
//
|
||||
// POST: /Account/Register
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> Register(RegisterViewModel model)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
var user = new ApplicationUser { UserName = model.Email, Email = model.Email };
|
||||
var result = await _userManager.CreateAsync(user, model.Password);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713
|
||||
// Send an email with this link
|
||||
var code = await _userManager.GenerateEmailConfirmationTokenAsync(user);
|
||||
var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);
|
||||
await _emailSender.SendEmailAsync(_siteSettings, _smtpSettings, model.Email, "Confirm your account",
|
||||
"Please confirm your account by clicking this link: <a href=\"" + callbackUrl + "\">link</a>");
|
||||
// await _signInManager.SignInAsync(user, isPersistent: false);
|
||||
_logger.LogInformation(3, "User created a new account with password.");
|
||||
return RedirectToAction(nameof(HomeController.Index), "Home");
|
||||
}
|
||||
AddErrors(result);
|
||||
}
|
||||
|
||||
// If we got this far, something failed, redisplay form
|
||||
return View(model);
|
||||
}
|
||||
|
||||
//
|
||||
// POST: /Account/LogOff
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> LogOff()
|
||||
{
|
||||
await _signInManager.SignOutAsync();
|
||||
_logger.LogInformation(4, "User logged out.");
|
||||
return RedirectToAction(nameof(HomeController.Index), "Home");
|
||||
}
|
||||
|
||||
//
|
||||
// POST: /Account/ExternalLogin
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult ExternalLogin(string provider, string returnUrl = null)
|
||||
{
|
||||
// Request a redirect to the external login provider.
|
||||
var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = returnUrl });
|
||||
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
|
||||
return new ChallengeResult(provider, properties);
|
||||
}
|
||||
|
||||
//
|
||||
// GET: /Account/ExternalLoginCallback
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> ExternalLoginCallback(string returnUrl = null)
|
||||
{
|
||||
var info = await _signInManager.GetExternalLoginInfoAsync();
|
||||
if (info == null)
|
||||
{
|
||||
return RedirectToAction(nameof(Login));
|
||||
}
|
||||
|
||||
// Sign in the user with this external login provider if the user already has a login.
|
||||
var result = await _signInManager.ExternalLoginSignInAsync(info.LoginProvider, info.ProviderKey, isPersistent: false);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
_logger.LogInformation(5, "User logged in with {Name} provider.", info.LoginProvider);
|
||||
|
||||
return RedirectToLocal(returnUrl);
|
||||
}
|
||||
if (result.RequiresTwoFactor)
|
||||
{
|
||||
return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl });
|
||||
}
|
||||
if (result.IsLockedOut)
|
||||
{
|
||||
return View("Lockout");
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the user does not have an account, then ask the user to create an account.
|
||||
ViewData["ReturnUrl"] = returnUrl;
|
||||
ViewData["LoginProvider"] = info.LoginProvider;
|
||||
var email = info.ExternalPrincipal.FindFirstValue(ClaimTypes.Email);
|
||||
var name = info.ExternalPrincipal.FindFirstValue(ClaimTypes.Name);
|
||||
var avatar = info.ExternalPrincipal.FindFirstValue("urn:google:profile");
|
||||
/* var phone = info.ExternalPrincipal.FindFirstValue(ClaimTypes.HomePhone);
|
||||
var mobile = info.ExternalPrincipal.FindFirstValue(ClaimTypes.MobilePhone);
|
||||
var postalcode = info.ExternalPrincipal.FindFirstValue(ClaimTypes.PostalCode);
|
||||
var locality = info.ExternalPrincipal.FindFirstValue(ClaimTypes.Locality);
|
||||
var country = info.ExternalPrincipal.FindFirstValue(ClaimTypes.Country);*/
|
||||
foreach (var claim in info.ExternalPrincipal.Claims)
|
||||
_logger.LogWarning("# {0} Claim: {1} {2}",info.LoginProvider,claim.Type,claim.Value);
|
||||
|
||||
var access_token = info.ExternalPrincipal.FindFirstValue("access_token");
|
||||
var token_type = info.ExternalPrincipal.FindFirstValue("token_type");
|
||||
var expires_in = info.ExternalPrincipal.FindFirstValue("expires_in");
|
||||
|
||||
return View("ExternalLoginConfirmation", new ExternalLoginConfirmationViewModel { Email = email,
|
||||
Name = name });
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// POST: /Account/ExternalLoginConfirmation
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl = null)
|
||||
{
|
||||
if (User.IsSignedIn())
|
||||
{
|
||||
return RedirectToAction(nameof(ManageController.Index), "Manage");
|
||||
}
|
||||
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
// Get the information about the user from the external login provider
|
||||
var info = await _signInManager.GetExternalLoginInfoAsync();
|
||||
if (info == null)
|
||||
{
|
||||
return View("ExternalLoginFailure");
|
||||
}
|
||||
var user = new ApplicationUser { UserName = model.Name, Email = model.Email };
|
||||
var result = await _userManager.CreateAsync(user);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
result = await _userManager.AddLoginAsync(user, info);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
await _signInManager.SignInAsync(user, isPersistent: false);
|
||||
_logger.LogInformation(6, "User created an account using {Name} provider.", info.LoginProvider);
|
||||
|
||||
return RedirectToLocal(returnUrl);
|
||||
}
|
||||
}
|
||||
AddErrors(result);
|
||||
}
|
||||
|
||||
ViewData["ReturnUrl"] = returnUrl;
|
||||
return View(model);
|
||||
}
|
||||
|
||||
// GET: /Account/ConfirmEmail
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> ConfirmEmail(string userId, string code)
|
||||
{
|
||||
if (userId == null || code == null)
|
||||
{
|
||||
return View("Error");
|
||||
}
|
||||
var user = await _userManager.FindByIdAsync(userId);
|
||||
if (user == null)
|
||||
{
|
||||
return View("Error");
|
||||
}
|
||||
var result = await _userManager.ConfirmEmailAsync(user, code);
|
||||
return View(result.Succeeded ? "ConfirmEmail" : "Error");
|
||||
}
|
||||
|
||||
//
|
||||
// GET: /Account/ForgotPassword
|
||||
[HttpGet]
|
||||
public IActionResult ForgotPassword()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
//
|
||||
// POST: /Account/ForgotPassword
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
var user = await _userManager.FindByNameAsync(model.Email);
|
||||
if (user == null || !(await _userManager.IsEmailConfirmedAsync(user)))
|
||||
{
|
||||
// Don't reveal that the user does not exist or is not confirmed
|
||||
return View("ForgotPasswordConfirmation");
|
||||
}
|
||||
|
||||
// For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=532713
|
||||
// Send an email with this link
|
||||
//var code = await _userManager.GeneratePasswordResetTokenAsync(user);
|
||||
//var callbackUrl = Url.Action("ResetPassword", "Account", new { userId = user.Id, code = code }, protocol: HttpContext.Request.Scheme);
|
||||
//await _emailSender.SendEmailAsync(model.Email, "Reset Password",
|
||||
// "Please reset your password by clicking here: <a href=\"" + callbackUrl + "\">link</a>");
|
||||
//return View("ForgotPasswordConfirmation");
|
||||
}
|
||||
|
||||
// If we got this far, something failed, redisplay form
|
||||
return View(model);
|
||||
}
|
||||
|
||||
//
|
||||
// GET: /Account/ForgotPasswordConfirmation
|
||||
[HttpGet]
|
||||
public IActionResult ForgotPasswordConfirmation()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
//
|
||||
// GET: /Account/ResetPassword
|
||||
[HttpGet]
|
||||
public IActionResult ResetPassword(string code = null)
|
||||
{
|
||||
return code == null ? View("Error") : View();
|
||||
}
|
||||
|
||||
//
|
||||
// POST: /Account/ResetPassword
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> ResetPassword(ResetPasswordViewModel model)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return View(model);
|
||||
}
|
||||
var user = await _userManager.FindByNameAsync(model.Email);
|
||||
if (user == null)
|
||||
{
|
||||
// Don't reveal that the user does not exist
|
||||
return RedirectToAction(nameof(AccountController.ResetPasswordConfirmation), "Account");
|
||||
}
|
||||
var result = await _userManager.ResetPasswordAsync(user, model.Code, model.Password);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
return RedirectToAction(nameof(AccountController.ResetPasswordConfirmation), "Account");
|
||||
}
|
||||
AddErrors(result);
|
||||
return View();
|
||||
}
|
||||
|
||||
//
|
||||
// GET: /Account/ResetPasswordConfirmation
|
||||
[HttpGet]
|
||||
public IActionResult ResetPasswordConfirmation()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
//
|
||||
// GET: /Account/SendCode
|
||||
[HttpGet,AllowAnonymous]
|
||||
public async Task<ActionResult> SendCode(string returnUrl = null, bool rememberMe = false)
|
||||
{
|
||||
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
|
||||
if (user == null)
|
||||
{
|
||||
return View("Error",new Exception("No Two factor authentication user" ));
|
||||
}
|
||||
var userFactors = await _userManager.GetValidTwoFactorProvidersAsync(user);
|
||||
|
||||
|
||||
var factorOptions = userFactors.Select(purpose => new SelectListItem { Text = purpose, Value = purpose }).ToList();
|
||||
return View(new SendCodeViewModel { Providers = factorOptions, ReturnUrl = returnUrl, RememberMe = rememberMe });
|
||||
}
|
||||
|
||||
//
|
||||
// POST: /Account/SendCode
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken,AllowAnonymous]
|
||||
public async Task<IActionResult> SendCode(SendCodeViewModel model)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return View();
|
||||
}
|
||||
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
|
||||
if (user == null)
|
||||
{
|
||||
return View("Error",new Exception("user is null"));
|
||||
}
|
||||
|
||||
// Generate the token and send it
|
||||
var code = await _userManager.GenerateTwoFactorTokenAsync(user, model.SelectedProvider);
|
||||
if (string.IsNullOrWhiteSpace(code))
|
||||
{
|
||||
return View("Error",new Exception("Code is empty"));
|
||||
}
|
||||
|
||||
var message = "Your security code is: " + code;
|
||||
if (model.SelectedProvider == Constants.MobileAppFactor)
|
||||
{
|
||||
return View("Error",new Exception("No SMS service was activated"));
|
||||
}
|
||||
else // if (model.SelectedProvider == Constants.EMailFactor || model.SelectedProvider == "Default" )
|
||||
if (model.SelectedProvider == Constants.SMSFactor)
|
||||
{
|
||||
return View("Error",new Exception("No SMS service was activated"));
|
||||
// await _smsSender.SendSmsAsync(_twilioSettings, await _userManager.GetPhoneNumberAsync(user), message);
|
||||
}
|
||||
else // if (model.SelectedProvider == Constants.EMailFactor || model.SelectedProvider == "Default" )
|
||||
{
|
||||
await _emailSender.SendEmailAsync(_siteSettings, _smtpSettings, await _userManager.GetEmailAsync(user), "Security Code", message);
|
||||
}
|
||||
return RedirectToAction(nameof(VerifyCode), new { Provider = model.SelectedProvider, ReturnUrl = model.ReturnUrl, RememberMe = model.RememberMe });
|
||||
}
|
||||
|
||||
//
|
||||
// GET: /Account/VerifyCode
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> VerifyCode(string provider, bool rememberMe, string returnUrl = null)
|
||||
{
|
||||
// Require that the user has already logged in via username/password or external login
|
||||
var user = await _signInManager.GetTwoFactorAuthenticationUserAsync();
|
||||
if (user == null)
|
||||
{
|
||||
return View("Error",new Exception("user is null"));
|
||||
}
|
||||
return View(new VerifyCodeViewModel { Provider = provider, ReturnUrl = returnUrl, RememberMe = rememberMe });
|
||||
}
|
||||
|
||||
//
|
||||
// POST: /Account/VerifyCode
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> VerifyCode(VerifyCodeViewModel model)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return View(model);
|
||||
}
|
||||
|
||||
// The following code protects for brute force attacks against the two factor codes.
|
||||
// If a user enters incorrect codes for a specified amount of time then the user account
|
||||
// will be locked out for a specified amount of time.
|
||||
_logger.LogWarning("Signin with code: {0} {1}",model.Provider, model.Code);
|
||||
var result = await _signInManager.TwoFactorSignInAsync(model.Provider, model.Code, model.RememberMe, model.RememberBrowser);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
ViewData["StatusMessage"] = "Your code was verified";
|
||||
return RedirectToLocal(model.ReturnUrl);
|
||||
}
|
||||
if (result.IsLockedOut)
|
||||
{
|
||||
_logger.LogWarning(7, "User account locked out.");
|
||||
return View("Lockout");
|
||||
}
|
||||
else
|
||||
{
|
||||
ModelState.AddModelError("", "Code invalide ");
|
||||
return View(model);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet,Authorize]
|
||||
public IActionResult Delete()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpPost,Authorize]
|
||||
public async Task<IActionResult> Delete(UnregisterViewModel model)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return View(model);
|
||||
}
|
||||
var user = await _userManager.FindByIdAsync(User.GetUserId());
|
||||
var result = await _userManager.DeleteAsync(user);
|
||||
if (!result.Succeeded)
|
||||
{
|
||||
AddErrors(result);
|
||||
return new BadRequestObjectResult(ModelState);
|
||||
}
|
||||
await _signInManager.SignOutAsync();
|
||||
|
||||
return RedirectToAction("Index","Home");
|
||||
}
|
||||
|
||||
#region Helpers
|
||||
|
||||
private void AddErrors(IdentityResult result)
|
||||
{
|
||||
foreach (var error in result.Errors)
|
||||
{
|
||||
ModelState.AddModelError(string.Empty, error.Description);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<ApplicationUser> GetCurrentUserAsync()
|
||||
{
|
||||
return await _userManager.FindByIdAsync(HttpContext.User.GetUserId());
|
||||
}
|
||||
|
||||
private IActionResult RedirectToLocal(string returnUrl)
|
||||
{
|
||||
if (Url.IsLocalUrl(returnUrl))
|
||||
{
|
||||
return Redirect(returnUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
return RedirectToAction(nameof(HomeController.Index), "Home");
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
120
Yavsc/src/Controllers/ActivityController.cs
Normal file
120
Yavsc/src/Controllers/ActivityController.cs
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
using System.Linq;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Yavsc.Models;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
[ServiceFilter(typeof(LanguageActionFilter)),Authorize("AdministratorOnly")]
|
||||
public class ActivityController : Controller
|
||||
{
|
||||
private ApplicationDbContext _context;
|
||||
|
||||
public ActivityController(ApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// GET: Activity
|
||||
public IActionResult Index()
|
||||
{
|
||||
return View(_context.Activities.ToList());
|
||||
}
|
||||
|
||||
// GET: Activity/Details/5
|
||||
public IActionResult Details(string id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
Activity activity = _context.Activities.Single(m => m.Code == id);
|
||||
if (activity == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
return View(activity);
|
||||
}
|
||||
|
||||
// GET: Activity/Create
|
||||
public IActionResult Create()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
// POST: Activity/Create
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult Create(Activity activity)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
_context.Activities.Add(activity);
|
||||
_context.SaveChanges();
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
return View(activity);
|
||||
}
|
||||
|
||||
// GET: Activity/Edit/5
|
||||
public IActionResult Edit(string id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
Activity activity = _context.Activities.Single(m => m.Code == id);
|
||||
if (activity == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
return View(activity);
|
||||
}
|
||||
|
||||
// POST: Activity/Edit/5
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult Edit(Activity activity)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
_context.Update(activity);
|
||||
_context.SaveChanges();
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
return View(activity);
|
||||
}
|
||||
|
||||
// GET: Activity/Delete/5
|
||||
[ActionName("Delete")]
|
||||
public IActionResult Delete(string id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
Activity activity = _context.Activities.Single(m => m.Code == id);
|
||||
if (activity == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
return View(activity);
|
||||
}
|
||||
|
||||
// POST: Activity/Delete/5
|
||||
[HttpPost, ActionName("Delete")]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult DeleteConfirmed(string id)
|
||||
{
|
||||
Activity activity = _context.Activities.Single(m => m.Code == id);
|
||||
_context.Activities.Remove(activity);
|
||||
_context.SaveChanges();
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
}
|
||||
}
|
||||
70
Yavsc/src/Controllers/AdministrationController.cs
Normal file
70
Yavsc/src/Controllers/AdministrationController.cs
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.AspNet.Identity.EntityFramework;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Yavsc.Models;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
[ServiceFilter(typeof(LanguageActionFilter)), Authorize()]
|
||||
public class AdministrationController : Controller
|
||||
{
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
private readonly RoleManager<IdentityRole> _roleManager;
|
||||
|
||||
public AdministrationController(UserManager<ApplicationUser> userManager,
|
||||
RoleManager<IdentityRole> roleManager)
|
||||
{
|
||||
_userManager = userManager;
|
||||
_roleManager = roleManager;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gives the (new if was not existing) administrator role
|
||||
/// to current authenticated user, when no existing
|
||||
/// administrator was found.
|
||||
/// When nothing is to do, it returns a 404.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Produces("application/json")]
|
||||
public async Task<IActionResult> Take()
|
||||
{
|
||||
// If some amdin already exists, make this method disapear
|
||||
var admins = await _userManager.GetUsersInRoleAsync(Constants.AdminGroupName);
|
||||
if (admins != null && admins.Count > 0) return HttpNotFound();
|
||||
var user = await _userManager.FindByIdAsync(User.GetUserId());
|
||||
|
||||
IdentityRole adminRole;
|
||||
if (!await _roleManager.RoleExistsAsync(Constants.AdminGroupName))
|
||||
{
|
||||
adminRole = new IdentityRole { Name = Constants.AdminGroupName };
|
||||
var resultCreate = await _roleManager.CreateAsync(adminRole);
|
||||
if (!resultCreate.Succeeded)
|
||||
{
|
||||
AddErrors(resultCreate);
|
||||
return new BadRequestObjectResult(ModelState);
|
||||
}
|
||||
}
|
||||
else adminRole = await _roleManager.FindByNameAsync(Constants.AdminGroupName);
|
||||
var addToRoleResult = await _userManager.AddToRoleAsync(user, Constants.AdminGroupName);
|
||||
if (!addToRoleResult.Succeeded)
|
||||
{
|
||||
AddErrors(addToRoleResult);
|
||||
return new BadRequestObjectResult(ModelState);
|
||||
}
|
||||
return Ok(new {message="you owned it."});
|
||||
}
|
||||
|
||||
private void AddErrors(IdentityResult result)
|
||||
{
|
||||
foreach (var error in result.Errors)
|
||||
{
|
||||
ModelState.AddModelError(string.Empty, error.Description);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
120
Yavsc/src/Controllers/ApplicationController.cs
Normal file
120
Yavsc/src/Controllers/ApplicationController.cs
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
using System.Linq;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Yavsc.Models;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
[Authorize("AdministratorOnly")]
|
||||
public class ApplicationController : Controller
|
||||
{
|
||||
private ApplicationDbContext _context;
|
||||
|
||||
public ApplicationController(ApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// GET: Application
|
||||
public IActionResult Index()
|
||||
{
|
||||
return View(_context.Applications.ToList());
|
||||
}
|
||||
|
||||
// GET: Application/Details/5
|
||||
public IActionResult Details(string id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
Application application = _context.Applications.Single(m => m.ApplicationID == id);
|
||||
if (application == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
return View(application);
|
||||
}
|
||||
|
||||
// GET: Application/Create
|
||||
public IActionResult Create()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
// POST: Application/Create
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult Create(Application application)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
_context.Applications.Add(application);
|
||||
_context.SaveChanges();
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
return View(application);
|
||||
}
|
||||
|
||||
// GET: Application/Edit/5
|
||||
public IActionResult Edit(string id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
Application application = _context.Applications.Single(m => m.ApplicationID == id);
|
||||
if (application == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
return View(application);
|
||||
}
|
||||
|
||||
// POST: Application/Edit/5
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult Edit(Application application)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
_context.Update(application);
|
||||
_context.SaveChanges();
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
return View(application);
|
||||
}
|
||||
|
||||
// GET: Application/Delete/5
|
||||
[ActionName("Delete")]
|
||||
public IActionResult Delete(string id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
Application application = _context.Applications.Single(m => m.ApplicationID == id);
|
||||
if (application == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
return View(application);
|
||||
}
|
||||
|
||||
// POST: Application/Delete/5
|
||||
[HttpPost, ActionName("Delete")]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult DeleteConfirmed(string id)
|
||||
{
|
||||
Application application = _context.Applications.Single(m => m.ApplicationID == id);
|
||||
_context.Applications.Remove(application);
|
||||
_context.SaveChanges();
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
}
|
||||
}
|
||||
193
Yavsc/src/Controllers/BlogspotController.cs
Normal file
193
Yavsc/src/Controllers/BlogspotController.cs
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
using System.Linq;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Yavsc.Models;
|
||||
using System;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Data.Entity;
|
||||
using Microsoft.Extensions.OptionsModel;
|
||||
|
||||
// For more information on enabling Web API for empty projects, visit http://go.microsoft.com/fwlink/?LinkID=397860
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
[ServiceFilter(typeof(LanguageActionFilter)),
|
||||
AllowAnonymous]
|
||||
public class BlogspotController : Controller
|
||||
{
|
||||
ILogger _logger;
|
||||
private ApplicationDbContext _context;
|
||||
|
||||
private SiteSettings _siteSettings;
|
||||
private IAuthorizationService _authorizationService;
|
||||
public BlogspotController(
|
||||
ApplicationDbContext context,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
ILoggerFactory loggerFactory,
|
||||
IAuthorizationService authorizationService,
|
||||
IOptions<SiteSettings> siteSettings)
|
||||
{
|
||||
_context = context;
|
||||
_logger = loggerFactory.CreateLogger<AccountController>();
|
||||
_authorizationService = authorizationService;
|
||||
_siteSettings = siteSettings.Value;
|
||||
}
|
||||
|
||||
// GET: Blog
|
||||
public IActionResult Index(string id)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(id))
|
||||
return UserPosts(id);
|
||||
return View(_context.Blogspot.Include(
|
||||
b=>b.Author
|
||||
).Where(p=>p.visible));
|
||||
}
|
||||
|
||||
[Route("/Title/{id?}")]
|
||||
public IActionResult Title(string id)
|
||||
{
|
||||
return View("Index", _context.Blogspot.Include(
|
||||
b=>b.Author
|
||||
).Where(x=>x.title==id).ToList());
|
||||
}
|
||||
|
||||
[Route("/Blog/{id?}")]
|
||||
public IActionResult UserPosts(string id)
|
||||
{
|
||||
|
||||
if (User.IsSignedIn())
|
||||
return View("Index", _context.Blogspot.Include(
|
||||
b=>b.Author
|
||||
).Where(x=>x.Author.UserName==id).ToList());
|
||||
return View("Index", _context.Blogspot.Include(
|
||||
b=>b.Author
|
||||
).Where(x=>x.Author.UserName==id && x.visible).ToList());
|
||||
}
|
||||
// GET: Blog/Details/5
|
||||
public IActionResult Details(long? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
Blog blog = _context.Blogspot.Include(
|
||||
b=>b.Author
|
||||
).Single(m => m.Id == id);
|
||||
if (blog == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
return View(blog);
|
||||
}
|
||||
|
||||
// GET: Blog/Create
|
||||
public IActionResult Create()
|
||||
{
|
||||
return View( new Blog { AuthorId = User.GetUserId() } );
|
||||
}
|
||||
|
||||
// POST: Blog/Create
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken,Authorize]
|
||||
public IActionResult Create(Blog blog)
|
||||
{
|
||||
blog.modified = blog.posted = DateTime.Now;
|
||||
blog.rate = 0;
|
||||
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
blog.posted = DateTime.Now;
|
||||
_context.Blogspot.Add(blog);
|
||||
_context.SaveChanges();
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
_logger.LogWarning("Invalid Blog entry ...");
|
||||
return View(blog);
|
||||
}
|
||||
|
||||
// GET: Blog/Edit/5
|
||||
public async Task<IActionResult> Edit(long? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
Blog blog = _context.Blogspot.Include(x=>x.Author).Single(m => m.Id == id);
|
||||
if (blog == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
if (await _authorizationService.AuthorizeAsync(User, blog, new EditRequirement()))
|
||||
{
|
||||
return View(blog);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new ChallengeResult();
|
||||
}
|
||||
}
|
||||
|
||||
// POST: Blog/Edit/5
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult Edit(Blog blog)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
var auth = _authorizationService.AuthorizeAsync(User, blog, new EditRequirement());
|
||||
if (auth.Result)
|
||||
{
|
||||
blog.modified = DateTime.Now;
|
||||
_context.Update(blog);
|
||||
_context.SaveChanges();
|
||||
ViewData["StatusMessage"]="Post modified";
|
||||
return RedirectToAction("Index");
|
||||
} // TODO Else hit me hard
|
||||
else {
|
||||
ViewData["StatusMessage"]="Access denied ...";
|
||||
}
|
||||
}
|
||||
return View(blog);
|
||||
}
|
||||
|
||||
// GET: Blog/Delete/5
|
||||
[ActionName("Delete")]
|
||||
public IActionResult Delete(long? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
Blog blog = _context.Blogspot.Include(
|
||||
b=>b.Author
|
||||
).Single(m => m.Id == id);
|
||||
if (blog == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
return View(blog);
|
||||
}
|
||||
|
||||
// POST: Blog/Delete/5
|
||||
[HttpPost, ActionName("Delete"), Authorize]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult DeleteConfirmed(long id)
|
||||
{
|
||||
Blog blog = _context.Blogspot.Single(m => m.Id == id);
|
||||
var auth = _authorizationService.AuthorizeAsync(User, blog, new EditRequirement());
|
||||
if (auth.Result) {
|
||||
_context.Blogspot.Remove(blog);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
}
|
||||
}
|
||||
119
Yavsc/src/Controllers/CircleController.cs
Normal file
119
Yavsc/src/Controllers/CircleController.cs
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
using System.Linq;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Yavsc.Models;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
[ServiceFilter(typeof(LanguageActionFilter))]
|
||||
public class CircleController : Controller
|
||||
{
|
||||
private ApplicationDbContext _context;
|
||||
|
||||
public CircleController(ApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
// GET: Circle
|
||||
public IActionResult Index()
|
||||
{
|
||||
return View(_context.CircleMembers.ToList());
|
||||
}
|
||||
|
||||
// GET: Circle/Details/5
|
||||
public IActionResult Details(long? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
CircleMember circleMember = _context.CircleMembers.Single(m => m.Id == id);
|
||||
if (circleMember == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
return View(circleMember);
|
||||
}
|
||||
|
||||
// GET: Circle/Create
|
||||
public IActionResult Create()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
// POST: Circle/Create
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult Create(CircleMember circleMember)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
_context.CircleMembers.Add(circleMember);
|
||||
_context.SaveChanges();
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
return View(circleMember);
|
||||
}
|
||||
|
||||
// GET: Circle/Edit/5
|
||||
public IActionResult Edit(long? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
CircleMember circleMember = _context.CircleMembers.Single(m => m.Id == id);
|
||||
if (circleMember == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
return View(circleMember);
|
||||
}
|
||||
|
||||
// POST: Circle/Edit/5
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult Edit(CircleMember circleMember)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
_context.Update(circleMember);
|
||||
_context.SaveChanges();
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
return View(circleMember);
|
||||
}
|
||||
|
||||
// GET: Circle/Delete/5
|
||||
[ActionName("Delete")]
|
||||
public IActionResult Delete(long? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
CircleMember circleMember = _context.CircleMembers.Single(m => m.Id == id);
|
||||
if (circleMember == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
return View(circleMember);
|
||||
}
|
||||
|
||||
// POST: Circle/Delete/5
|
||||
[HttpPost, ActionName("Delete")]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult DeleteConfirmed(long id)
|
||||
{
|
||||
CircleMember circleMember = _context.CircleMembers.Single(m => m.Id == id);
|
||||
_context.CircleMembers.Remove(circleMember);
|
||||
_context.SaveChanges();
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
}
|
||||
}
|
||||
219
Yavsc/src/Controllers/CommandController.cs
Normal file
219
Yavsc/src/Controllers/CommandController.cs
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.Data.Entity;
|
||||
using Microsoft.Extensions.Localization;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.OptionsModel;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Booking;
|
||||
using Yavsc.Models.Google.Messaging;
|
||||
using Yavsc.Services;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
[ServiceFilter(typeof(LanguageActionFilter))]
|
||||
public class CommandController : Controller
|
||||
{
|
||||
private UserManager<ApplicationUser> _userManager;
|
||||
private ApplicationDbContext _context;
|
||||
private GoogleAuthSettings _googleSettings;
|
||||
private IGoogleCloudMessageSender _GCMSender;
|
||||
private IEmailSender _emailSender;
|
||||
private IStringLocalizer _localizer;
|
||||
SiteSettings _siteSettings;
|
||||
SmtpSettings _smtpSettings;
|
||||
|
||||
private readonly ILogger _logger;
|
||||
public CommandController(ApplicationDbContext context,IOptions<GoogleAuthSettings> googleSettings,
|
||||
IGoogleCloudMessageSender GCMSender,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
IStringLocalizer<Yavsc.Resources.YavscLoc> localizer,
|
||||
IEmailSender emailSender,
|
||||
IOptions<SmtpSettings> smtpSettings,
|
||||
IOptions<SiteSettings> siteSettings,
|
||||
ILoggerFactory loggerFactory)
|
||||
{
|
||||
_context = context;
|
||||
_GCMSender = GCMSender;
|
||||
_emailSender = emailSender;
|
||||
_googleSettings = googleSettings.Value;
|
||||
_userManager = userManager;
|
||||
_smtpSettings = smtpSettings.Value;
|
||||
_siteSettings = siteSettings.Value;
|
||||
_localizer = localizer;
|
||||
_logger = loggerFactory.CreateLogger<CommandController>();
|
||||
}
|
||||
|
||||
// GET: Command
|
||||
public IActionResult Index()
|
||||
{
|
||||
return View(_context.BookQueries
|
||||
.Include(x=>x.Client)
|
||||
.Include(x=>x.PerformerProfile)
|
||||
.Include(x=>x.PerformerProfile.Performer)
|
||||
.Include(x=>x.Location)
|
||||
.Include(x=>x.Bill).ToList());
|
||||
}
|
||||
|
||||
// GET: Command/Details/5
|
||||
public IActionResult Details(long? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
BookQuery command = _context.BookQueries
|
||||
.Include(x=>x.Location)
|
||||
.Include(x=>x.PerformerProfile)
|
||||
.Single(m => m.Id == id);
|
||||
if (command == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
return View(command);
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
/// <summary>
|
||||
/// Gives a view on
|
||||
/// Creating a command for a specified performer
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <returns></returns>
|
||||
public IActionResult Create(string id)
|
||||
{
|
||||
var pro = _context.Performers.Include(
|
||||
x=>x.Performer).FirstOrDefault(
|
||||
x=>x.PerfomerId == id
|
||||
);
|
||||
if (pro==null)
|
||||
return HttpNotFound();
|
||||
|
||||
ViewBag.GoogleSettings = _googleSettings;
|
||||
var userid = User.GetUserId();
|
||||
var user = _userManager.FindByIdAsync(userid).Result;
|
||||
return View(new BookQuery{
|
||||
PerformerProfile = pro,
|
||||
PerformerId = pro.PerfomerId,
|
||||
ClientId = userid,
|
||||
Client = user,
|
||||
Location = new Location(),
|
||||
EventDate = DateTime.Now.AddHours(4)
|
||||
});
|
||||
}
|
||||
|
||||
// POST: Command/Create
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> Create(BookQuery command)
|
||||
{
|
||||
var pro = _context.Performers.FirstOrDefault(
|
||||
x=>x.PerfomerId == command.PerformerId
|
||||
);
|
||||
command.PerformerProfile = pro;
|
||||
var user = _userManager.FindByIdAsync(
|
||||
User.GetUserId()
|
||||
).Result;
|
||||
command.Client = user;
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
var yaev = command.CreateEvent(_localizer);
|
||||
MessageWithPayloadResponse grep=null;
|
||||
|
||||
_context.Attach<Location>(command.Location);
|
||||
_context.BookQueries.Add(command,GraphBehavior.IncludeDependents);
|
||||
_context.SaveChanges();
|
||||
if (command.PerformerProfile.AcceptNotifications
|
||||
&& command.PerformerProfile.AcceptPublicContact
|
||||
&& command.PerformerProfile.Performer.GoogleRegId!=null) {
|
||||
grep = await _GCMSender.NotifyAsync(_googleSettings,
|
||||
command.PerformerProfile.Performer.GoogleRegId,
|
||||
yaev
|
||||
);
|
||||
}
|
||||
// TODO setup a profile choice to allow notifications
|
||||
// both on mailbox and mobile
|
||||
// if (grep==null || grep.success<=0 || grep.failure>0)
|
||||
{
|
||||
await _emailSender.SendEmailAsync(
|
||||
_siteSettings, _smtpSettings,
|
||||
command.PerformerProfile.Performer.Email,
|
||||
yaev.Title,
|
||||
$"{yaev.Description}\r\n-- \r\n{yaev.Comment}\r\n"
|
||||
);
|
||||
|
||||
}
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
ViewBag.GoogleSettings = _googleSettings;
|
||||
return View(command);
|
||||
}
|
||||
|
||||
// GET: Command/Edit/5
|
||||
public IActionResult Edit(long? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
BookQuery command = _context.BookQueries.Single(m => m.Id == id);
|
||||
if (command == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
return View(command);
|
||||
}
|
||||
|
||||
// POST: Command/Edit/5
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult Edit(BookQuery command)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
_context.Update(command);
|
||||
_context.SaveChanges();
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
return View(command);
|
||||
}
|
||||
|
||||
// GET: Command/Delete/5
|
||||
[ActionName("Delete")]
|
||||
public IActionResult Delete(long? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
BookQuery command = _context.BookQueries.Single(m => m.Id == id);
|
||||
if (command == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
return View(command);
|
||||
}
|
||||
|
||||
// POST: Command/Delete/5
|
||||
[HttpPost, ActionName("Delete")]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult DeleteConfirmed(long id)
|
||||
{
|
||||
BookQuery command = _context.BookQueries.Single(m => m.Id == id);
|
||||
_context.BookQueries.Remove(command);
|
||||
_context.SaveChanges();
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
}
|
||||
}
|
||||
169
Yavsc/src/Controllers/EstimateController.cs
Normal file
169
Yavsc/src/Controllers/EstimateController.cs
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.FileProviders;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.Data.Entity;
|
||||
using Microsoft.Extensions.OptionsModel;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.Models;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
public class EstimateController : Controller
|
||||
{
|
||||
private ApplicationDbContext _context;
|
||||
private SiteSettings _site;
|
||||
|
||||
public EstimateController(ApplicationDbContext context, IOptions<SiteSettings> siteSettings)
|
||||
{
|
||||
_context = context;
|
||||
_site = siteSettings.Value;
|
||||
}
|
||||
|
||||
// GET: Estimate
|
||||
public IActionResult Index()
|
||||
{
|
||||
return View(_context.Estimates.ToList());
|
||||
}
|
||||
|
||||
// GET: Estimate/Details/5
|
||||
public IActionResult Details(long? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
Estimate estimate = _context.Estimates
|
||||
.Include(e => e.Command)
|
||||
.Include(e => e.Command.PerformerProfile)
|
||||
.Include(e => e.Command.PerformerProfile.Performer)
|
||||
.Single(m => m.Id == id);
|
||||
if (estimate == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
ViewBag.Files = estimate.GetFileContent(_site.UserFiles.RootDir);
|
||||
return View(estimate);
|
||||
}
|
||||
|
||||
|
||||
// GET: Estimate/Create
|
||||
public IActionResult Create()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
// POST: Estimate/Create
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult Create(Estimate estimate,
|
||||
ICollection<IFormFile> newGraphics,
|
||||
ICollection<IFormFile> newFiles
|
||||
)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
_context.Estimates
|
||||
.Add(estimate);
|
||||
_context.SaveChanges();
|
||||
|
||||
var perfomerProfile = _context.Performers
|
||||
.Include(
|
||||
perpr => perpr.Performer).FirstOrDefault(
|
||||
x=>x.PerfomerId == estimate.Command.PerformerId
|
||||
);
|
||||
var command = _context.Commands.FirstOrDefault(
|
||||
cmd => cmd.Id == estimate.CommandId
|
||||
);
|
||||
|
||||
var userdir = Path.Combine(
|
||||
_site.UserFiles.RootDir,
|
||||
perfomerProfile.Performer.UserName
|
||||
);
|
||||
|
||||
var fsp = new PhysicalFileProvider(userdir);
|
||||
var billsdir = Path.Combine(userdir,
|
||||
Constants.UserBillsFilesDir);
|
||||
|
||||
foreach (var gr in newGraphics)
|
||||
{
|
||||
gr.SaveAs(
|
||||
Path.Combine(
|
||||
Path.Combine(billsdir, estimate.Id.ToString()),
|
||||
gr.ContentDisposition));
|
||||
}
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
return View(estimate);
|
||||
}
|
||||
|
||||
|
||||
private void Save( ICollection<IFormFile> newGraphics,
|
||||
ICollection<IFormFile> newFiles) {
|
||||
|
||||
}
|
||||
// GET: Estimate/Edit/5
|
||||
public IActionResult Edit(long? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
Estimate estimate = _context.Estimates.Single(m => m.Id == id);
|
||||
if (estimate == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
ViewBag.Files = estimate.GetFileContent(_site.UserFiles.RootDir);
|
||||
return View(estimate);
|
||||
}
|
||||
|
||||
// POST: Estimate/Edit/5
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult Edit(Estimate estimate)
|
||||
{
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
_context.Update(estimate);
|
||||
_context.SaveChanges();
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
return View(estimate);
|
||||
}
|
||||
|
||||
// GET: Estimate/Delete/5
|
||||
[ActionName("Delete")]
|
||||
public IActionResult Delete(long? id)
|
||||
{
|
||||
if (id == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
Estimate estimate = _context.Estimates.Single(m => m.Id == id);
|
||||
if (estimate == null)
|
||||
{
|
||||
return HttpNotFound();
|
||||
}
|
||||
|
||||
return View(estimate);
|
||||
}
|
||||
|
||||
// POST: Estimate/Delete/5
|
||||
[HttpPost, ActionName("Delete")]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult DeleteConfirmed(long id)
|
||||
{
|
||||
Estimate estimate = _context.Estimates.Single(m => m.Id == id);
|
||||
_context.Estimates.Remove(estimate);
|
||||
_context.SaveChanges();
|
||||
return RedirectToAction("Index");
|
||||
}
|
||||
}
|
||||
}
|
||||
104
Yavsc/src/Controllers/FrontOfficeController.cs
Normal file
104
Yavsc/src/Controllers/FrontOfficeController.cs
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using Yavsc.Models;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.Data.Entity;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Yavsc.Models.Booking;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
[ServiceFilter(typeof(LanguageActionFilter)), AllowAnonymous,
|
||||
Route("do")]
|
||||
public class FrontOfficeController : Controller
|
||||
{
|
||||
ApplicationDbContext _context;
|
||||
UserManager<ApplicationUser> _userManager;
|
||||
|
||||
ILogger _logger;
|
||||
public FrontOfficeController(ApplicationDbContext context,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
ILoggerFactory loggerFactory)
|
||||
{
|
||||
_context = context;
|
||||
_userManager = userManager;
|
||||
_logger = loggerFactory.CreateLogger<FrontOfficeController>();
|
||||
}
|
||||
public ActionResult Index()
|
||||
{
|
||||
var latestPosts = _context.Blogspot.Where(
|
||||
x => x.visible == true
|
||||
).OrderBy(x => x.modified).Take(25).ToArray();
|
||||
return View(latestPosts);
|
||||
}
|
||||
|
||||
[Route("Book/{id?}"),HttpGet]
|
||||
|
||||
public ActionResult Book(string id)
|
||||
{
|
||||
if (id != null) {
|
||||
ViewBag.Activities = _context.ActivityItems(id);
|
||||
ViewBag.Activity = _context.Activities.FirstOrDefault(
|
||||
a => a.Code == id
|
||||
);
|
||||
|
||||
return View(
|
||||
_context.Performers.Include(p=>p.Performer).Where
|
||||
(p => p.ActivityCode == id && p.Active).OrderBy(
|
||||
x=>x.MinDailyCost
|
||||
)
|
||||
);
|
||||
}
|
||||
ViewBag.Activities = _context.ActivityItems(null);
|
||||
|
||||
return View (
|
||||
_context.Performers.Include(p=>p.Performer).Where
|
||||
(p => p.Active).OrderBy(
|
||||
x=>x.MinDailyCost
|
||||
));
|
||||
}
|
||||
|
||||
[Route("Book/{id}"),HttpPost]
|
||||
|
||||
public ActionResult Book(BookQuery bookQuery)
|
||||
{
|
||||
if (ModelState.IsValid) {
|
||||
var pro = _context.Performers.Include(
|
||||
pr => pr.Performer
|
||||
).FirstOrDefault(
|
||||
x=>x.PerfomerId == bookQuery.PerformerId
|
||||
);
|
||||
if (pro==null)
|
||||
return HttpNotFound();
|
||||
// Let's create a command
|
||||
if (bookQuery.Id==0)
|
||||
{
|
||||
_context.BookQueries.Add(bookQuery);
|
||||
}
|
||||
else {
|
||||
_context.BookQueries.Update(bookQuery);
|
||||
}
|
||||
_context.SaveChanges();
|
||||
// TODO Send sys notifications &
|
||||
// notify the user (make him a basket badge)
|
||||
return View("Index");
|
||||
}
|
||||
ViewBag.Activities = _context.ActivityItems(null);
|
||||
return View( _context.Performers.Include(p=>p.Performer).Where
|
||||
(p => p.Active).OrderBy(
|
||||
x=>x.MinDailyCost
|
||||
));
|
||||
}
|
||||
|
||||
[Produces("text/x-tex"), Authorize,
|
||||
Route("Release/Estimate-{id}.tex")]
|
||||
public Estimate Estimate(long id)
|
||||
{
|
||||
var estimate = _context.Estimates.Include(x=>x.Command).
|
||||
Include(x=>x.Command.Client).FirstOrDefault(x=>x.Id==id);
|
||||
var adc = estimate.Command.Client.UserName;
|
||||
return estimate;
|
||||
}
|
||||
}
|
||||
}
|
||||
61
Yavsc/src/Controllers/HomeController.cs
Normal file
61
Yavsc/src/Controllers/HomeController.cs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
using Microsoft.AspNet.Mvc.Localization;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.AspNet.Http.Features;
|
||||
using Microsoft.AspNet.Diagnostics;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using Microsoft.AspNet.Hosting;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
[ServiceFilter(typeof(LanguageActionFilter)),AllowAnonymous]
|
||||
public class HomeController : Controller
|
||||
{
|
||||
public IHostingEnvironment Hosting { get; set; }
|
||||
|
||||
private readonly IHtmlLocalizer _localizer;
|
||||
|
||||
public HomeController(IHtmlLocalizer<Startup> localizer, IHostingEnvironment hosting)
|
||||
{
|
||||
_localizer = localizer;
|
||||
Hosting = hosting;
|
||||
}
|
||||
|
||||
public IActionResult Index()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult About()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult Contact()
|
||||
{
|
||||
|
||||
return View();
|
||||
}
|
||||
|
||||
public ActionResult Chat()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
public IActionResult Error()
|
||||
{
|
||||
var feature = this.HttpContext.Features.Get<IExceptionHandlerFeature>();
|
||||
|
||||
return View("~/Views/Shared/Error.cshtml", feature?.Error);
|
||||
}
|
||||
public IActionResult Status(int id)
|
||||
{
|
||||
ViewBag.StatusCode = id;
|
||||
return View("~/Views/Shared/Status.cshtml");
|
||||
}
|
||||
public IActionResult Todo()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
586
Yavsc/src/Controllers/ManageController.cs
Normal file
586
Yavsc/src/Controllers/ManageController.cs
Normal file
|
|
@ -0,0 +1,586 @@
|
|||
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Security.Claims;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Services;
|
||||
using Yavsc.ViewModels.Manage;
|
||||
using Microsoft.Extensions.OptionsModel;
|
||||
using Microsoft.Data.Entity;
|
||||
using System;
|
||||
using PayPal.PayPalAPIInterfaceService;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using Yavsc.Helpers;
|
||||
using Yavsc.ViewModels.Calendar;
|
||||
using System.Net;
|
||||
using Microsoft.Extensions.Localization;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
[Authorize, ServiceFilter(typeof(LanguageActionFilter))]
|
||||
public class ManageController : Controller
|
||||
{
|
||||
private readonly UserManager<ApplicationUser> _userManager;
|
||||
private readonly SignInManager<ApplicationUser> _signInManager;
|
||||
private readonly IEmailSender _emailSender;
|
||||
private readonly ILogger _logger;
|
||||
private SiteSettings _siteSettings;
|
||||
|
||||
private ApplicationDbContext _dbContext;
|
||||
|
||||
private GoogleAuthSettings _googleSettings;
|
||||
|
||||
private PayPalSettings _payPalSettings;
|
||||
private IGoogleCloudMessageSender _GCMSender;
|
||||
private SIRENChecker _cchecker;
|
||||
private IStringLocalizer _SR;
|
||||
private CompanyInfoSettings _cinfoSettings;
|
||||
|
||||
public ManageController(
|
||||
ApplicationDbContext context,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
SignInManager<ApplicationUser> signInManager,
|
||||
IEmailSender emailSender,
|
||||
IGoogleCloudMessageSender GCMSender,
|
||||
IOptions<SiteSettings> siteSettings,
|
||||
IOptions<GoogleAuthSettings> googleSettings,
|
||||
IOptions<PayPalSettings> paypalSettings,
|
||||
IOptions<CompanyInfoSettings> cinfoSettings,
|
||||
IStringLocalizer <Yavsc.Resources.YavscLoc>SR,
|
||||
ILoggerFactory loggerFactory)
|
||||
{
|
||||
_dbContext = context;
|
||||
_userManager = userManager;
|
||||
_signInManager = signInManager;
|
||||
_emailSender = emailSender;
|
||||
_GCMSender = GCMSender;
|
||||
_siteSettings = siteSettings.Value;
|
||||
_googleSettings = googleSettings.Value;
|
||||
_payPalSettings = paypalSettings.Value;
|
||||
_cinfoSettings = cinfoSettings.Value;
|
||||
_cchecker = new SIRENChecker(cinfoSettings.Value);
|
||||
_SR = SR;
|
||||
_logger = loggerFactory.CreateLogger<ManageController>();
|
||||
}
|
||||
|
||||
//
|
||||
// GET: /Manage/Index
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Index(ManageMessageId? message = null)
|
||||
{
|
||||
ViewData["StatusMessage"] =
|
||||
message == ManageMessageId.ChangePasswordSuccess ? "Your password has been changed."
|
||||
: message == ManageMessageId.SetPasswordSuccess ? "Your password has been set."
|
||||
: message == ManageMessageId.SetTwoFactorSuccess ? "Your two-factor authentication provider has been set."
|
||||
: message == ManageMessageId.Error ? "An error has occurred."
|
||||
: message == ManageMessageId.AddPhoneSuccess ? "Your phone number was added."
|
||||
: message == ManageMessageId.RemovePhoneSuccess ? "Your phone number was removed."
|
||||
: message == ManageMessageId.ChangeNameSuccess ? "Your name was updated."
|
||||
: message == ManageMessageId.SetActivitySuccess ? "Your activity was set."
|
||||
: "";
|
||||
|
||||
var user = await GetCurrentUserAsync();
|
||||
long pc = _dbContext.Blogspot.Count(x => x.AuthorId == user.Id);
|
||||
var model = new IndexViewModel
|
||||
{
|
||||
HasPassword = await _userManager.HasPasswordAsync(user),
|
||||
PhoneNumber = await _userManager.GetPhoneNumberAsync(user),
|
||||
TwoFactor = await _userManager.GetTwoFactorEnabledAsync(user),
|
||||
Logins = await _userManager.GetLoginsAsync(user),
|
||||
BrowserRemembered = await _signInManager.IsTwoFactorClientRememberedAsync(user),
|
||||
UserName = user.UserName,
|
||||
PostsCounter = pc,
|
||||
Balance = user.AccountBalance,
|
||||
ActiveCommandCount = _dbContext.BookQueries.Count(x => (x.ClientId == user.Id) && (x.EventDate > DateTime.Now)),
|
||||
HasDedicatedCalendar = !string.IsNullOrEmpty(user.DedicatedGoogleCalendar)
|
||||
};
|
||||
if (_dbContext.Performers.Any(x => x.PerfomerId == user.Id))
|
||||
{
|
||||
var code = _dbContext.Performers.First(x => x.PerfomerId == user.Id).ActivityCode;
|
||||
model.Activity = _dbContext.Activities.First(x => x.Code == code);
|
||||
}
|
||||
return View(model);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// POST: /Manage/RemoveLogin
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> RemoveLogin(RemoveLoginViewModel account)
|
||||
{
|
||||
ManageMessageId? message = ManageMessageId.Error;
|
||||
var user = await GetCurrentUserAsync();
|
||||
if (user != null)
|
||||
{
|
||||
var result = await _userManager.RemoveLoginAsync(user, account.LoginProvider, account.ProviderKey);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
await _signInManager.SignInAsync(user, isPersistent: false);
|
||||
message = ManageMessageId.RemoveLoginSuccess;
|
||||
}
|
||||
}
|
||||
return RedirectToAction(nameof(ManageLogins), new { Message = message });
|
||||
}
|
||||
|
||||
//
|
||||
// GET: /Manage/AddPhoneNumber
|
||||
public IActionResult AddPhoneNumber()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
//
|
||||
// POST: /Manage/AddPhoneNumber
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> AddPhoneNumber(AddPhoneNumberViewModel model)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return View(model);
|
||||
}
|
||||
// Generate the token and send it
|
||||
var user = await GetCurrentUserAsync();
|
||||
var code = await _userManager.GenerateChangePhoneNumberTokenAsync(user, model.PhoneNumber);
|
||||
// TODO await _smsSender.SendSmsAsync(_twilioSettings, model.PhoneNumber, "Your security code is: " + code);
|
||||
|
||||
return RedirectToAction(nameof(VerifyPhoneNumber), new { PhoneNumber = model.PhoneNumber });
|
||||
}
|
||||
|
||||
//
|
||||
// POST: /Manage/EnableTwoFactorAuthentication
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> EnableTwoFactorAuthentication()
|
||||
{
|
||||
var user = await GetCurrentUserAsync();
|
||||
if (user != null)
|
||||
{
|
||||
await _userManager.SetTwoFactorEnabledAsync(user, true);
|
||||
await _signInManager.SignInAsync(user, isPersistent: false);
|
||||
_logger.LogInformation(1, "User enabled two-factor authentication.");
|
||||
}
|
||||
return RedirectToAction(nameof(Index), "Manage");
|
||||
}
|
||||
|
||||
//
|
||||
// POST: /Manage/DisableTwoFactorAuthentication
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> DisableTwoFactorAuthentication()
|
||||
{
|
||||
var user = await GetCurrentUserAsync();
|
||||
if (user != null)
|
||||
{
|
||||
await _userManager.SetTwoFactorEnabledAsync(user, false);
|
||||
await _signInManager.SignInAsync(user, isPersistent: false);
|
||||
_logger.LogInformation(2, "User disabled two-factor authentication.");
|
||||
}
|
||||
return RedirectToAction(nameof(Index), "Manage");
|
||||
}
|
||||
|
||||
//
|
||||
// GET: /Manage/VerifyPhoneNumber
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> VerifyPhoneNumber(string phoneNumber)
|
||||
{
|
||||
var code = await _userManager.GenerateChangePhoneNumberTokenAsync(await GetCurrentUserAsync(), phoneNumber);
|
||||
// Send an SMS to verify the phone number
|
||||
return phoneNumber == null ? View("Error") : View(new VerifyPhoneNumberViewModel { PhoneNumber = phoneNumber });
|
||||
}
|
||||
|
||||
//
|
||||
// POST: /Manage/VerifyPhoneNumber
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> VerifyPhoneNumber(VerifyPhoneNumberViewModel model)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return View(model);
|
||||
}
|
||||
var user = await GetCurrentUserAsync();
|
||||
if (user != null)
|
||||
{
|
||||
var result = await _userManager.ChangePhoneNumberAsync(user, model.PhoneNumber, model.Code);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
await _signInManager.SignInAsync(user, isPersistent: false);
|
||||
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.AddPhoneSuccess });
|
||||
}
|
||||
}
|
||||
// If we got this far, something failed, redisplay the form
|
||||
ModelState.AddModelError(string.Empty, "Failed to verify phone number");
|
||||
return View(model);
|
||||
}
|
||||
|
||||
//
|
||||
// GET: /Manage/RemovePhoneNumber
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> RemovePhoneNumber()
|
||||
{
|
||||
var user = await GetCurrentUserAsync();
|
||||
if (user != null)
|
||||
{
|
||||
var result = await _userManager.SetPhoneNumberAsync(user, null);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
await _signInManager.SignInAsync(user, isPersistent: false);
|
||||
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.RemovePhoneSuccess });
|
||||
}
|
||||
}
|
||||
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
|
||||
}
|
||||
|
||||
//
|
||||
// GET: /Manage/ChangePassword
|
||||
[HttpGet]
|
||||
public IActionResult ChangePassword()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
[HttpGet]
|
||||
public IActionResult AddMobileApp(GoogleCloudMobileDeclaration model)
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
[HttpGet, Authorize]
|
||||
public async Task<IActionResult> SetGoogleCalendar(string returnUrl)
|
||||
{
|
||||
var credential = await _userManager.GetCredentialForGoogleApiAsync(
|
||||
_dbContext, User.GetUserId());
|
||||
if (credential==null)
|
||||
return RedirectToAction("LinkLogin",new { provider = "Google" });
|
||||
|
||||
try {
|
||||
ViewBag.Calendars = new GoogleApis.CalendarApi(_googleSettings.ApiKey)
|
||||
.GetCalendars(credential);
|
||||
}
|
||||
catch (WebException ex)
|
||||
{
|
||||
// a bug
|
||||
_logger.LogError("Google token, an Forbidden calendar");
|
||||
if (ex.HResult == (int) HttpStatusCode.Forbidden)
|
||||
{
|
||||
return RedirectToAction("LinkLogin",new { provider = "Google" });
|
||||
}
|
||||
}
|
||||
return View(new SetGoogleCalendarViewModel { ReturnUrl=returnUrl });
|
||||
}
|
||||
|
||||
[HttpPost,ValidateAntiForgeryToken,
|
||||
Authorize]
|
||||
public async Task<IActionResult> SetGoogleCalendar(SetGoogleCalendarViewModel model)
|
||||
{
|
||||
var user = _dbContext.Users.FirstOrDefault(u=>u.Id == User.GetUserId());
|
||||
user.DedicatedGoogleCalendar = model.GoogleCalendarId;
|
||||
await _dbContext.SaveChangesAsync();
|
||||
if (string.IsNullOrEmpty(model.ReturnUrl))
|
||||
return RedirectToAction("Index");
|
||||
else return Redirect(model.ReturnUrl);
|
||||
}
|
||||
|
||||
//
|
||||
// POST: /Manage/ChangePassword
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> ChangePassword(ChangePasswordViewModel model)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return View(model);
|
||||
}
|
||||
var user = await GetCurrentUserAsync();
|
||||
if (user != null)
|
||||
{
|
||||
var result = await _userManager.ChangePasswordAsync(user, model.OldPassword, model.NewPassword);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
await _signInManager.SignInAsync(user, isPersistent: false);
|
||||
_logger.LogInformation(3, "User changed their password successfully.");
|
||||
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ChangePasswordSuccess });
|
||||
}
|
||||
AddErrors(result);
|
||||
return View(model);
|
||||
}
|
||||
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
|
||||
}
|
||||
|
||||
//
|
||||
// GET: /Manage/ChangeUserName
|
||||
public IActionResult ChangeUserName()
|
||||
{
|
||||
return View(new ChangeUserNameViewModel() { NewUserName = User.Identity.Name });
|
||||
}
|
||||
|
||||
public IActionResult CHUN()
|
||||
{
|
||||
return View(new ChangeUserNameViewModel() { NewUserName = User.Identity.Name });
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public async Task<IActionResult> CHUN(ChangeUserNameViewModel model)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return View(model);
|
||||
}
|
||||
var user = await GetCurrentUserAsync();
|
||||
if (user != null)
|
||||
{
|
||||
var oldUserName = user.UserName;
|
||||
|
||||
var result = await this._userManager.SetUserNameAsync(user, model.NewUserName);
|
||||
|
||||
if (result.Succeeded)
|
||||
{
|
||||
var userdirinfo = new DirectoryInfo(
|
||||
Path.Combine(_siteSettings.UserFiles.RootDir,
|
||||
oldUserName));
|
||||
var newdir = Path.Combine(_siteSettings.UserFiles.RootDir,
|
||||
model.NewUserName);
|
||||
|
||||
if (userdirinfo.Exists)
|
||||
userdirinfo.MoveTo(newdir);
|
||||
|
||||
await _signInManager.SignInAsync(user, isPersistent: false);
|
||||
_logger.LogInformation(3, "User changed his user name successfully.");
|
||||
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.ChangeNameSuccess });
|
||||
}
|
||||
AddErrors(result);
|
||||
return View(model);
|
||||
}
|
||||
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
|
||||
}
|
||||
|
||||
//
|
||||
// GET: /Manage/SetPassword
|
||||
[HttpGet]
|
||||
public IActionResult SetPassword()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
|
||||
//
|
||||
// POST: /Manage/SetPassword
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> SetPassword(SetPasswordViewModel model)
|
||||
{
|
||||
if (!ModelState.IsValid)
|
||||
{
|
||||
return View(model);
|
||||
}
|
||||
|
||||
var user = await GetCurrentUserAsync();
|
||||
if (user != null)
|
||||
{
|
||||
var result = await _userManager.AddPasswordAsync(user, model.NewPassword);
|
||||
if (result.Succeeded)
|
||||
{
|
||||
await _signInManager.SignInAsync(user, isPersistent: false);
|
||||
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.SetPasswordSuccess });
|
||||
}
|
||||
AddErrors(result);
|
||||
return View(model);
|
||||
}
|
||||
return RedirectToAction(nameof(Index), new { Message = ManageMessageId.Error });
|
||||
}
|
||||
|
||||
//GET: /Manage/ManageLogins
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> ManageLogins(ManageMessageId? message = null)
|
||||
{
|
||||
ViewData["StatusMessage"] =
|
||||
message == ManageMessageId.RemoveLoginSuccess ? "The external login was removed."
|
||||
: message == ManageMessageId.AddLoginSuccess ? "The external login was added."
|
||||
: message == ManageMessageId.Error ? "An error has occurred."
|
||||
: "";
|
||||
var user = await GetCurrentUserAsync();
|
||||
if (user == null)
|
||||
{
|
||||
return View("Error");
|
||||
}
|
||||
var userLogins = await _userManager.GetLoginsAsync(user);
|
||||
var otherLogins = _signInManager.GetExternalAuthenticationSchemes().Where(auth => userLogins.All(ul => auth.AuthenticationScheme != ul.LoginProvider)).ToList();
|
||||
ViewData["ShowRemoveButton"] = user.PasswordHash != null || userLogins.Count > 1;
|
||||
|
||||
return View(new ManageLoginsViewModel
|
||||
{
|
||||
CurrentLogins = userLogins,
|
||||
OtherLogins = otherLogins
|
||||
});
|
||||
}
|
||||
|
||||
//
|
||||
// POST: /Manage/LinkLogin
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken]
|
||||
public IActionResult LinkLogin(string provider)
|
||||
{
|
||||
// Request a redirect to the external login provider to link a login for the current user
|
||||
var redirectUrl = Url.Action("LinkLoginCallback", "Manage");
|
||||
var properties = _signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, User.GetUserId());
|
||||
return new ChallengeResult(provider, properties);
|
||||
}
|
||||
|
||||
//
|
||||
// GET: /Manage/LinkLoginCallback
|
||||
[HttpGet]
|
||||
public async Task<ActionResult> LinkLoginCallback()
|
||||
{
|
||||
var user = await GetCurrentUserAsync();
|
||||
if (user == null)
|
||||
{
|
||||
return View("Error");
|
||||
}
|
||||
var info = await _signInManager.GetExternalLoginInfoAsync(User.GetUserId());
|
||||
if (info == null)
|
||||
{
|
||||
return RedirectToAction(nameof(ManageLogins), new { Message = ManageMessageId.Error });
|
||||
}
|
||||
var result = await _userManager.AddLoginAsync(user, info);
|
||||
var message = result.Succeeded ? ManageMessageId.AddLoginSuccess : ManageMessageId.Error;
|
||||
return RedirectToAction(nameof(ManageLogins), new { Message = message });
|
||||
}
|
||||
|
||||
[HttpGet, Authorize]
|
||||
public IActionResult SetActivity()
|
||||
{
|
||||
var user = GetCurrentUserAsync().Result;
|
||||
var uid = user.Id;
|
||||
bool existing = _dbContext.Performers.Any(x => x.PerfomerId == uid);
|
||||
ViewBag.Activities = _dbContext.ActivityItems(null);
|
||||
ViewBag.GoogleSettings = _googleSettings;
|
||||
if (existing)
|
||||
{
|
||||
var currentProfile = _dbContext.Performers.Include(x => x.OrganisationAddress)
|
||||
.First(x => x.PerfomerId == uid);
|
||||
string currentCode = currentProfile.ActivityCode;
|
||||
return View(currentProfile);
|
||||
}
|
||||
return View(new PerformerProfile
|
||||
{
|
||||
PerfomerId = user.Id,
|
||||
OrganisationAddress = new Location()
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
[HttpPost]
|
||||
[ValidateAntiForgeryToken, Authorize]
|
||||
public async Task<IActionResult> SetActivity(PerformerProfile model)
|
||||
{
|
||||
var user = GetCurrentUserAsync().Result;
|
||||
var uid = user.Id;
|
||||
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
var taskCheck = await _cchecker.CheckAsync(model.SIREN);
|
||||
if (!taskCheck.success) {
|
||||
ModelState.AddModelError(
|
||||
"SIREN",
|
||||
_SR["Invalid company number"]+" ("+taskCheck.errorCode+")"
|
||||
);
|
||||
_logger.LogWarning("Invalid company number, using key:"+_cinfoSettings.ApiKey);
|
||||
}
|
||||
}
|
||||
if (ModelState.IsValid)
|
||||
{
|
||||
if (uid == model.PerfomerId)
|
||||
{
|
||||
bool addrexists = _dbContext.Map.Any(x => model.OrganisationAddress.Id == x.Id);
|
||||
if (!addrexists)
|
||||
{
|
||||
_dbContext.Map.Add(model.OrganisationAddress);
|
||||
}
|
||||
bool existing = _dbContext.Performers.Any(x => x.PerfomerId == uid);
|
||||
if (existing)
|
||||
{
|
||||
_dbContext.Update(model);
|
||||
}
|
||||
else _dbContext.Performers.Add(model);
|
||||
_dbContext.SaveChanges();
|
||||
var message = ManageMessageId.SetActivitySuccess;
|
||||
|
||||
return RedirectToAction(nameof(Index), new { Message = message });
|
||||
|
||||
}
|
||||
else ModelState.AddModelError(string.Empty, "Acces denied");
|
||||
}
|
||||
ViewBag.GoogleSettings = _googleSettings;
|
||||
ViewBag.Activities = _dbContext.ActivityItems(model.ActivityCode);
|
||||
return View(model);
|
||||
}
|
||||
|
||||
[HttpPost, Authorize]
|
||||
public IActionResult UnsetActivity()
|
||||
{
|
||||
var user = GetCurrentUserAsync().Result;
|
||||
var uid = user.Id;
|
||||
bool existing = _dbContext.Performers.Any(x => x.PerfomerId == uid);
|
||||
if (existing)
|
||||
{
|
||||
_dbContext.Performers.Remove(
|
||||
_dbContext.Performers.First(x => x.PerfomerId == uid)
|
||||
);
|
||||
_dbContext.SaveChanges();
|
||||
}
|
||||
var message = ManageMessageId.UnsetActivitySuccess;
|
||||
return RedirectToAction(nameof(Index), new { Message = message });
|
||||
}
|
||||
|
||||
[HttpGet, Route("/Manage/Credits")]
|
||||
public IActionResult Credits()
|
||||
{
|
||||
Dictionary<string, string> config = new Dictionary<string, string>();
|
||||
config.Add("mode", "sandbox");
|
||||
config.Add("account1.apiUsername", _payPalSettings.UserId);
|
||||
config.Add("account1.apiPassword", _payPalSettings.Secret);
|
||||
config.Add("account1.apiSignature", _payPalSettings.Signature);
|
||||
PayPalAPIInterfaceServiceService s = new PayPalAPIInterfaceServiceService(config);
|
||||
|
||||
return View();
|
||||
}
|
||||
|
||||
#region Helpers
|
||||
|
||||
private void AddErrors(IdentityResult result)
|
||||
{
|
||||
foreach (var error in result.Errors)
|
||||
{
|
||||
ModelState.AddModelError(string.Empty, error.Description);
|
||||
}
|
||||
}
|
||||
|
||||
public enum ManageMessageId
|
||||
{
|
||||
AddPhoneSuccess,
|
||||
AddLoginSuccess,
|
||||
ChangePasswordSuccess,
|
||||
ChangeNameSuccess,
|
||||
SetTwoFactorSuccess,
|
||||
SetPasswordSuccess,
|
||||
RemoveLoginSuccess,
|
||||
RemovePhoneSuccess,
|
||||
SetActivitySuccess,
|
||||
UnsetActivitySuccess,
|
||||
Error
|
||||
}
|
||||
|
||||
|
||||
private async Task<ApplicationUser> GetCurrentUserAsync()
|
||||
{
|
||||
return await _userManager.FindByIdAsync(HttpContext.User.GetUserId());
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
347
Yavsc/src/Controllers/OAuthController.cs
Normal file
347
Yavsc/src/Controllers/OAuthController.cs
Normal file
|
|
@ -0,0 +1,347 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using AspNet.Security.OpenIdConnect.Extensions;
|
||||
using AspNet.Security.OpenIdConnect.Server;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.DataProtection.KeyManagement;
|
||||
using Microsoft.AspNet.Http.Authentication;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
using Microsoft.Data.Entity;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.OptionsModel;
|
||||
using Microsoft.IdentityModel.Protocols.OpenIdConnect;
|
||||
using Yavsc.Extensions;
|
||||
using Yavsc.Models;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
[AllowAnonymous]
|
||||
public class OAuthController : Controller
|
||||
{
|
||||
ApplicationDbContext _context;
|
||||
UserManager<ApplicationUser> _userManager;
|
||||
|
||||
ILogger _logger;
|
||||
private readonly SignInManager<ApplicationUser> _signInManager;
|
||||
private TokenAuthOptions _tokenOptions;
|
||||
|
||||
public OAuthController(ApplicationDbContext context, SignInManager<ApplicationUser> signInManager, IKeyManager keyManager,
|
||||
IOptions<TokenAuthOptions> tokenOptions,
|
||||
UserManager<ApplicationUser> userManager,
|
||||
ILoggerFactory loggerFactory
|
||||
)
|
||||
{
|
||||
_context = context;
|
||||
_signInManager = signInManager;
|
||||
_tokenOptions = tokenOptions.Value;
|
||||
_userManager = userManager;
|
||||
_logger = loggerFactory.CreateLogger<OAuthController>();
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("~/signin")]
|
||||
public ActionResult SignIn(string returnUrl = null) {
|
||||
// Note: the "returnUrl" parameter corresponds to the endpoint the user agent
|
||||
// will be redirected to after a successful authentication and not
|
||||
// the redirect_uri of the requesting client application.
|
||||
if (returnUrl==null) returnUrl="/";
|
||||
ViewBag.ReturnUrl = returnUrl;
|
||||
|
||||
// Note: in a real world application, you'd probably prefer creating a specific view model.
|
||||
return View("SignIn", HttpContext.GetExternalProviders());
|
||||
}
|
||||
|
||||
[HttpPost("~/signin")]
|
||||
public IActionResult SignIn( string Provider, string ReturnUrl ) {
|
||||
// Note: the "provider" parameter corresponds to the external
|
||||
// authentication provider choosen by the user agent.
|
||||
if (string.IsNullOrEmpty(Provider)) {
|
||||
_logger.LogWarning("Provider not specified");
|
||||
return HttpBadRequest();
|
||||
}
|
||||
|
||||
if (!_signInManager.GetExternalAuthenticationSchemes().Any(x=>x.AuthenticationScheme==Provider)) {
|
||||
_logger.LogWarning($"Provider not found : {Provider}");
|
||||
return HttpBadRequest();
|
||||
}
|
||||
|
||||
// Note: the "returnUrl" parameter corresponds to the endpoint the user agent
|
||||
// will be redirected to after a successful authentication and not
|
||||
// the redirect_uri of the requesting client application.
|
||||
if (string.IsNullOrEmpty(ReturnUrl)) {
|
||||
_logger.LogWarning("ReturnUrl not specified");
|
||||
return HttpBadRequest();
|
||||
}
|
||||
|
||||
// Instruct the middleware corresponding to the requested external identity
|
||||
// provider to redirect the user agent to its own authorization endpoint.
|
||||
// Note: the authenticationScheme parameter must match the value configured in Startup.cs
|
||||
var redirectUrl = Url.Action("ExternalLoginCallback", "Account", new { ReturnUrl = ReturnUrl });
|
||||
var properties = _signInManager.ConfigureExternalAuthenticationProperties(Provider, redirectUrl);
|
||||
return new ChallengeResult(Provider, properties);
|
||||
}
|
||||
|
||||
|
||||
|
||||
[HttpGet("~/signout"), HttpPost("~/signout")]
|
||||
public async Task SignOut() {
|
||||
// Instruct the cookies middleware to delete the local cookie created
|
||||
// when the user agent is redirected from the external identity provider
|
||||
// after a successful authentication flow (e.g Google or Facebook).
|
||||
|
||||
await HttpContext.Authentication.SignOutAsync("ServerCookie");
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
[HttpGet("~/api/getclaims"), Produces("application/json")]
|
||||
|
||||
public IActionResult GetClaims()
|
||||
{
|
||||
var identity = User.Identity as ClaimsIdentity;
|
||||
|
||||
var claims = from c in identity.Claims
|
||||
select new
|
||||
{
|
||||
subject = c.Subject.Name,
|
||||
type = c.Type,
|
||||
value = c.Value
|
||||
};
|
||||
|
||||
return Ok(claims);
|
||||
}
|
||||
|
||||
|
||||
[HttpGet("~/connect/authorize"), HttpPost("~/connect/authorize")]
|
||||
public async Task<IActionResult> Authorize(CancellationToken cancellationToken) {
|
||||
// Note: when a fatal error occurs during the request processing, an OpenID Connect response
|
||||
// is prematurely forged and added to the ASP.NET context by OpenIdConnectServerHandler.
|
||||
// You can safely remove this part and let ASOS automatically handle the unrecoverable errors
|
||||
// by switching ApplicationCanDisplayErrors to false in Startup.cs.
|
||||
var response = HttpContext.GetOpenIdConnectResponse();
|
||||
if (response != null) {
|
||||
return View("OidcError", response);
|
||||
}
|
||||
|
||||
// Extract the authorization request from the ASP.NET environment.
|
||||
var request = HttpContext.GetOpenIdConnectRequest();
|
||||
if (request == null) {
|
||||
return View("OidcError", new OpenIdConnectMessage {
|
||||
Error = OpenIdConnectConstants.Errors.ServerError,
|
||||
ErrorDescription = "An internal error has occurred"
|
||||
});
|
||||
}
|
||||
|
||||
// Note: authentication could be theorically enforced at the filter level via AuthorizeAttribute
|
||||
// but this authorization endpoint accepts both GET and POST requests while the cookie middleware
|
||||
// only uses 302 responses to redirect the user agent to the login page, making it incompatible with POST.
|
||||
// To work around this limitation, the OpenID Connect request is automatically saved in the cache and will be
|
||||
// restored by the OpenID Connect server middleware after the external authentication process has been completed.
|
||||
if (!User.Identities.Any(identity => identity.IsAuthenticated)) {
|
||||
return new ChallengeResult(new AuthenticationProperties {
|
||||
RedirectUri = Url.Action(nameof(Authorize), new {
|
||||
request_id = request.GetUniqueIdentifier()
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// Note: ASOS automatically ensures that an application corresponds to the client_id specified
|
||||
// in the authorization request by calling IOpenIdConnectServerProvider.ValidateAuthorizationRequest.
|
||||
// In theory, this null check shouldn't be needed, but a race condition could occur if you
|
||||
// manually removed the application details from the database after the initial check made by ASOS.
|
||||
var application = await GetApplicationAsync(request.ClientId, cancellationToken);
|
||||
if (application == null) {
|
||||
return View("OidcError", new OpenIdConnectMessage {
|
||||
Error = OpenIdConnectConstants.Errors.InvalidClient,
|
||||
ErrorDescription = "Details concerning the calling client application cannot be found in the database"
|
||||
});
|
||||
}
|
||||
|
||||
// Note: in a real world application, you'd probably prefer creating a specific view model.
|
||||
return View("Authorize", Tuple.Create(request, application));
|
||||
}
|
||||
|
||||
[Authorize, HttpPost("~/connect/authorize/accept"), ValidateAntiForgeryToken]
|
||||
public async Task<IActionResult> Accept(CancellationToken cancellationToken) {
|
||||
var response = HttpContext.GetOpenIdConnectResponse();
|
||||
if (response != null) {
|
||||
return View("OidcError", response);
|
||||
}
|
||||
|
||||
var request = HttpContext.GetOpenIdConnectRequest();
|
||||
if (request == null) {
|
||||
return View("OidcError", new OpenIdConnectMessage {
|
||||
Error = OpenIdConnectConstants.Errors.ServerError,
|
||||
ErrorDescription = "An internal error has occurred"
|
||||
});
|
||||
}
|
||||
|
||||
// Create a new ClaimsIdentity containing the claims that
|
||||
// will be used to create an id_token, a token or a code.
|
||||
var identity = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme);
|
||||
|
||||
// Copy the claims retrieved from the external identity provider
|
||||
// (e.g Google, Facebook, a WS-Fed provider or another OIDC server).
|
||||
foreach (var claim in HttpContext.User.Claims) {
|
||||
// Allow ClaimTypes.Name to be added in the id_token.
|
||||
// ClaimTypes.NameIdentifier is automatically added, even if its
|
||||
// destination is not defined or doesn't include "id_token".
|
||||
// The other claims won't be visible for the client application.
|
||||
/*
|
||||
if (claim.Type == ClaimTypes.Name) {
|
||||
claim.SetDestinations(OpenIdConnectConstants.Destinations.AccessToken,
|
||||
OpenIdConnectConstants.Destinations.IdentityToken);
|
||||
}
|
||||
*/
|
||||
if (claim.Type == ClaimTypes.Name) {
|
||||
claim.WithDestination("code");
|
||||
claim.WithDestination("id_token");
|
||||
}
|
||||
identity.AddClaim(claim);
|
||||
}
|
||||
|
||||
var application = await GetApplicationAsync(request.ClientId, cancellationToken);
|
||||
if (application == null) {
|
||||
return View("OidcError", new OpenIdConnectMessage {
|
||||
Error = OpenIdConnectConstants.Errors.InvalidClient,
|
||||
ErrorDescription = "Details concerning the calling client application cannot be found in the database"
|
||||
});
|
||||
}
|
||||
|
||||
// Create a new ClaimsIdentity containing the claims associated with the application.
|
||||
// Note: setting identity.Actor is not mandatory but can be useful to access
|
||||
// the whole delegation chain from the resource server (see ResourceController.cs).
|
||||
identity.Actor = new ClaimsIdentity(OpenIdConnectServerDefaults.AuthenticationScheme);
|
||||
identity.Actor.AddClaim(ClaimTypes.NameIdentifier, application.ApplicationID);
|
||||
identity.Actor.AddClaim(ClaimTypes.Name, application.DisplayName,"code id_token");
|
||||
|
||||
var properties = new AuthenticationProperties();
|
||||
|
||||
// Note: you can change the list of scopes granted
|
||||
// to the client application using SetScopes:
|
||||
properties.SetScopes(new[] {
|
||||
/* openid: */ OpenIdConnectConstants.Scopes.OpenId,
|
||||
/* email: */ OpenIdConnectConstants.Scopes.Email,
|
||||
/* profile: */ OpenIdConnectConstants.Scopes.Profile,
|
||||
/* api-resource-controller: */ "api-resource-controller"
|
||||
});
|
||||
|
||||
// You can also limit the resources endpoints
|
||||
// the access token should be issued for:
|
||||
properties.SetResources(new[] {
|
||||
"http://localhost:54540/"
|
||||
});
|
||||
|
||||
// This call will instruct AspNet.Security.OpenIdConnect.Server to serialize
|
||||
// the specified identity to build appropriate tokens (id_token and token).
|
||||
// Note: you should always make sure the identities you return contain either
|
||||
// a 'sub' or a 'ClaimTypes.NameIdentifier' claim. In this case, the returned
|
||||
// identities always contain the name identifier returned by the external provider.
|
||||
// Note: the authenticationScheme parameter must match the value configured in Startup.cs.
|
||||
await HttpContext.Authentication.SignInAsync(
|
||||
OpenIdConnectServerDefaults.AuthenticationScheme,
|
||||
new ClaimsPrincipal(identity), properties);
|
||||
|
||||
return new EmptyResult();
|
||||
}
|
||||
|
||||
[Authorize, HttpPost("~/connect/authorize/deny"), ValidateAntiForgeryToken]
|
||||
public IActionResult Deny(CancellationToken cancellationToken) {
|
||||
var response = HttpContext.GetOpenIdConnectResponse();
|
||||
if (response != null) {
|
||||
return View("OidcError", response);
|
||||
}
|
||||
|
||||
var request = HttpContext.GetOpenIdConnectRequest();
|
||||
if (request == null) {
|
||||
return View("OidcError", new OpenIdConnectMessage {
|
||||
Error = OpenIdConnectConstants.Errors.ServerError,
|
||||
ErrorDescription = "An internal error has occurred"
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Notify AspNet.Security.OpenIdConnect.Server that the authorization grant has been denied.
|
||||
// Note: OpenIdConnectServerHandler will automatically take care of redirecting
|
||||
// the user agent to the client application using the appropriate response_mode.
|
||||
HttpContext.SetOpenIdConnectResponse(new OpenIdConnectMessage {
|
||||
Error = "access_denied",
|
||||
ErrorDescription = "The authorization grant has been denied by the resource owner",
|
||||
RedirectUri = request.RedirectUri,
|
||||
State = request.State
|
||||
});
|
||||
|
||||
|
||||
return new EmptyResult();
|
||||
}
|
||||
|
||||
[HttpGet("~/connect/logout")]
|
||||
public async Task<ActionResult> Logout() {
|
||||
var response = HttpContext.GetOpenIdConnectResponse();
|
||||
if (response != null) {
|
||||
return View("OidcError", response);
|
||||
}
|
||||
|
||||
// When invoked, the logout endpoint might receive an unauthenticated request if the server cookie has expired.
|
||||
// When the client application sends an id_token_hint parameter, the corresponding identity can be retrieved
|
||||
// using AuthenticateAsync or using User when the authorization server is declared as AuthenticationMode.Active.
|
||||
var identity = await HttpContext.Authentication.AuthenticateAsync(OpenIdConnectServerDefaults.AuthenticationScheme);
|
||||
|
||||
var request = HttpContext.GetOpenIdConnectRequest();
|
||||
if (request == null) {
|
||||
return View("OidcError", new OpenIdConnectMessage {
|
||||
Error = OpenIdConnectConstants.Errors.ServerError,
|
||||
ErrorDescription = "An internal error has occurred"
|
||||
});
|
||||
}
|
||||
|
||||
return View("Logout", Tuple.Create(request, identity));
|
||||
}
|
||||
|
||||
[HttpPost("~/connect/logout")]
|
||||
[ValidateAntiForgeryToken]
|
||||
public async Task Logout(CancellationToken cancellationToken) {
|
||||
// Instruct the cookies middleware to delete the local cookie created
|
||||
// when the user agent is redirected from the external identity provider
|
||||
// after a successful authentication flow (e.g Google or Facebook).
|
||||
await HttpContext.Authentication.SignOutAsync("ServerCookie");
|
||||
|
||||
// This call will instruct AspNet.Security.OpenIdConnect.Server to serialize
|
||||
// the specified identity to build appropriate tokens (id_token and token).
|
||||
// Note: you should always make sure the identities you return contain either
|
||||
// a 'sub' or a 'ClaimTypes.NameIdentifier' claim. In this case, the returned
|
||||
// identities always contain the name identifier returned by the external provider.
|
||||
await HttpContext.Authentication.SignOutAsync(OpenIdConnectServerDefaults.AuthenticationScheme);
|
||||
}
|
||||
|
||||
protected virtual Task<Application> GetApplicationAsync(string identifier, CancellationToken cancellationToken)
|
||||
{
|
||||
// Retrieve the application details corresponding to the requested client_id.
|
||||
return (from application in _context.Applications
|
||||
where application.ApplicationID == identifier
|
||||
select application).SingleOrDefaultAsync(cancellationToken);
|
||||
}
|
||||
private async Task<ApplicationUser> GetCurrentUserAsync()
|
||||
{
|
||||
return await _userManager.FindByIdAsync(HttpContext.User.GetUserId());
|
||||
}
|
||||
|
||||
private IActionResult RedirectToLocal(string returnUrl)
|
||||
{
|
||||
if (Url.IsLocalUrl(returnUrl))
|
||||
{
|
||||
return Redirect(returnUrl);
|
||||
}
|
||||
else
|
||||
{
|
||||
return RedirectToAction(nameof(HomeController.Index), "Home");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Yavsc/src/Controllers/UserFilesController.cs
Normal file
11
Yavsc/src/Controllers/UserFilesController.cs
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
using Microsoft.AspNet.Authorization;
|
||||
using Microsoft.AspNet.Mvc;
|
||||
|
||||
namespace Yavsc.Controllers
|
||||
{
|
||||
[Authorize, ServiceFilter(typeof(LanguageActionFilter))]
|
||||
public class UserFilesController : Controller
|
||||
{
|
||||
}
|
||||
}
|
||||
39
Yavsc/src/Extensions/AppBuilderExtensions.cs
Normal file
39
Yavsc/src/Extensions/AppBuilderExtensions.cs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
using System;
|
||||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.AspNet.Http;
|
||||
|
||||
namespace Yavsc.Extensions {
|
||||
public static class AppBuilderExtensions {
|
||||
public static IApplicationBuilder UseWhen(this IApplicationBuilder app,
|
||||
Func<HttpContext, bool> condition, Action<IApplicationBuilder> configuration) {
|
||||
if (app == null) {
|
||||
throw new ArgumentNullException(nameof(app));
|
||||
}
|
||||
|
||||
if (condition == null) {
|
||||
throw new ArgumentNullException(nameof(condition));
|
||||
}
|
||||
|
||||
if (configuration == null) {
|
||||
throw new ArgumentNullException(nameof(configuration));
|
||||
}
|
||||
|
||||
var builder = app.New();
|
||||
configuration(builder);
|
||||
|
||||
return app.Use(next => {
|
||||
builder.Run(next);
|
||||
|
||||
var branch = builder.Build();
|
||||
|
||||
return context => {
|
||||
if (condition(context)) {
|
||||
return branch(context);
|
||||
}
|
||||
|
||||
return next(context);
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
45
Yavsc/src/Extensions/SignalRBuilderExtension.cs
Normal file
45
Yavsc/src/Extensions/SignalRBuilderExtension.cs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
using Microsoft.AspNet.Builder;
|
||||
using Microsoft.Owin.Builder;
|
||||
using Owin;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yavsc
|
||||
{
|
||||
using Microsoft.AspNet.SignalR;
|
||||
using AppFunc = Func<IDictionary<string, object>, Task>;
|
||||
|
||||
public static class BuilderExtensions
|
||||
{
|
||||
public static IApplicationBuilder UseAppBuilder(
|
||||
this IApplicationBuilder app,
|
||||
Action<IAppBuilder> configure)
|
||||
{
|
||||
app.UseOwin(addToPipeline =>
|
||||
{
|
||||
addToPipeline(next =>
|
||||
{
|
||||
var appBuilder = new AppBuilder();
|
||||
appBuilder.Properties["builder.DefaultApp"] = next;
|
||||
|
||||
configure(appBuilder);
|
||||
|
||||
return appBuilder.Build<AppFunc>();
|
||||
});
|
||||
});
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
public static void UseSignalR(this IApplicationBuilder app)
|
||||
{
|
||||
app.UseAppBuilder(appBuilder => appBuilder.MapSignalR(
|
||||
new HubConfiguration() {
|
||||
EnableDetailedErrors = true,
|
||||
EnableJSONP = true
|
||||
}
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
38
Yavsc/src/Formatters/PdfFormatter.cs
Normal file
38
Yavsc/src/Formatters/PdfFormatter.cs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Mvc.Formatters;
|
||||
using Microsoft.Extensions.WebEncoders;
|
||||
|
||||
|
||||
namespace Yavsc.Formatters {
|
||||
public class PdfFormatter : OutputFormatter
|
||||
{
|
||||
public override Task WriteResponseBodyAsync(OutputFormatterWriteContext context)
|
||||
{
|
||||
|
||||
throw new NotImplementedException();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public class TexEncoder : IHtmlEncoder
|
||||
{
|
||||
public string HtmlEncode(string value)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public void HtmlEncode(string value, int startIndex, int charCount, TextWriter output)
|
||||
{
|
||||
output.Write(value.Substring(startIndex,charCount));
|
||||
}
|
||||
|
||||
public void HtmlEncode(char[] value, int startIndex, int charCount, TextWriter output)
|
||||
{
|
||||
output.Write(value,startIndex,charCount);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
140
Yavsc/src/GoogleApis/CalendarApi.cs
Normal file
140
Yavsc/src/GoogleApis/CalendarApi.cs
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
//
|
||||
// Calendar.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// 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.Net;
|
||||
using System.IO;
|
||||
using System.Web;
|
||||
using Yavsc.Models.Google;
|
||||
using Yavsc.Models.Auth;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Yavsc.GoogleApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Google Calendar API client.
|
||||
/// </summary>
|
||||
public class CalendarApi
|
||||
{
|
||||
protected static string scopeCalendar = "https://www.googleapis.com/auth/calendar";
|
||||
private string _ApiKey;
|
||||
|
||||
public CalendarApi(string ApiKey)
|
||||
{
|
||||
_ApiKey = ApiKey;
|
||||
}
|
||||
/// <summary>
|
||||
/// The get cal list URI.
|
||||
/// </summary>
|
||||
protected static string getCalListUri = "https://www.googleapis.com/calendar/v3/users/me/calendarList";
|
||||
/// <summary>
|
||||
/// The get cal entries URI.
|
||||
/// </summary>
|
||||
protected static string getCalEntriesUri = "https://www.googleapis.com/calendar/v3/calendars/{0}/events";
|
||||
|
||||
/// <summary>
|
||||
/// The date format.
|
||||
/// </summary>
|
||||
private static string dateFormat = "yyyy-MM-ddTHH:mm:ss";
|
||||
|
||||
/// <summary>
|
||||
/// The time zone. TODO Fixme with machine time zone
|
||||
/// </summary>
|
||||
private string timeZone = "+01:00";
|
||||
|
||||
/// <summary>
|
||||
/// Gets the calendar list.
|
||||
/// </summary>
|
||||
/// <returns>The calendars.</returns>
|
||||
/// <param name="cred">Cred.</param>
|
||||
public CalendarList GetCalendars (UserCredential creds)
|
||||
{
|
||||
if (creds==null)
|
||||
throw new InvalidOperationException("No credential");
|
||||
CalendarList res = null;
|
||||
HttpWebRequest webreq = WebRequest.CreateHttp (getCalListUri);
|
||||
webreq.Headers.Add (HttpRequestHeader.Authorization, creds.GetHeader());
|
||||
webreq.Method = "GET";
|
||||
webreq.ContentType = "application/http";
|
||||
using (WebResponse resp = webreq.GetResponse ()) {
|
||||
using (Stream respstream = resp.GetResponseStream ()) {
|
||||
using (var rdr = new StreamReader(respstream)) {
|
||||
res = JsonConvert.DeserializeObject<CalendarList>(rdr.ReadToEnd());
|
||||
}
|
||||
}
|
||||
resp.Close ();
|
||||
}
|
||||
webreq.Abort ();
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets a calendar event list, between the given dates.
|
||||
/// </summary>
|
||||
/// <returns>The calendar.</returns>
|
||||
/// <param name="calid">Calendar identifier.</param>
|
||||
/// <param name="mindate">Mindate.</param>
|
||||
/// <param name="maxdate">Maxdate.</param>
|
||||
/// <param name="cred">credential string.</param>
|
||||
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=" + _ApiKey,
|
||||
HttpUtility.UrlEncode (mindate.ToString (dateFormat) + timeZone),
|
||||
HttpUtility.UrlEncode (maxdate.ToString (dateFormat) + timeZone));
|
||||
|
||||
HttpWebRequest webreq = WebRequest.CreateHttp (uri);
|
||||
|
||||
webreq.Headers.Add (HttpRequestHeader.Authorization, cred);
|
||||
webreq.Method = "GET";
|
||||
webreq.ContentType = "application/http";
|
||||
CalendarEventList res = null;
|
||||
try {
|
||||
using (WebResponse resp = webreq.GetResponse ()) {
|
||||
using (Stream respstream = resp.GetResponseStream ()) {
|
||||
try {
|
||||
using (var rdr = new StreamReader(respstream)) {
|
||||
res= JsonConvert.DeserializeObject<CalendarEventList>(rdr.ReadToEnd());
|
||||
}
|
||||
} catch (Exception ) {
|
||||
respstream.Close ();
|
||||
resp.Close ();
|
||||
webreq.Abort ();
|
||||
throw ;
|
||||
}
|
||||
}
|
||||
resp.Close ();
|
||||
}
|
||||
} catch (WebException ) {
|
||||
webreq.Abort ();
|
||||
throw;
|
||||
}
|
||||
webreq.Abort ();
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
82
Yavsc/src/GoogleApis/MapTracks.cs
Normal file
82
Yavsc/src/GoogleApis/MapTracks.cs
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
//
|
||||
// Google.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// 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 Yavsc.Model;
|
||||
using Yavsc.Models.Google;
|
||||
|
||||
namespace Yavsc.GoogleApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Google Map tracks Api client.
|
||||
/// </summary>
|
||||
public class MapTracks {
|
||||
protected static string scopeTracks = "https://www.googleapis.com/auth/tracks";
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Yavsc.Helpers.Google.Api.MapTracks"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authType">Auth type.</param>
|
||||
/// <param name="redirectUri">Redirect URI.</param>
|
||||
public MapTracks()
|
||||
{}
|
||||
/// <summary>
|
||||
/// The google map tracks path (uri of the service).
|
||||
/// </summary>
|
||||
protected static string googleMapTracksPath = "https://www.googleapis.com/tracks/v1/";
|
||||
// entities/[create|list|delete]
|
||||
// collections/[list|create|[add|remove]entities|delete]
|
||||
// crumbs/[record|getrecent|gethistory|report|summarize|getlocationinfo|delete
|
||||
|
||||
|
||||
// entities/[create|list|delete]
|
||||
// collections/[list|create|[add|remove]entities|delete]
|
||||
// crumbs/[record|getrecent|gethistory|report|summarize|getlocationinfo|delete
|
||||
|
||||
/// <summary>
|
||||
/// Creates the entity.
|
||||
/// </summary>
|
||||
/// <returns>The entity.</returns>
|
||||
/// <param name="entities">Entities.</param>
|
||||
public static string [] CreateEntity( Entity[] entities ) {
|
||||
string [] ans = null;
|
||||
using (SimpleJsonPostMethod< Entity[] ,string []> wr =
|
||||
new SimpleJsonPostMethod< Entity[] ,string[]> (googleMapTracksPath + "entities/create"))
|
||||
{
|
||||
ans = wr.Invoke (entities);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Lists the entities.
|
||||
/// </summary>
|
||||
/// <returns>The entities.</returns>
|
||||
/// <param name="eq">Eq.</param>
|
||||
static Entity[] ListEntities (EntityQuery eq)
|
||||
{
|
||||
Entity [] ans = null;
|
||||
using (SimpleJsonPostMethod<EntityQuery,Entity[]> wr =
|
||||
new SimpleJsonPostMethod<EntityQuery,Entity[]> (googleMapTracksPath + "entities/create"))
|
||||
{
|
||||
ans = wr.Invoke (eq);
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
}
|
||||
}
|
||||
78
Yavsc/src/GoogleApis/PeopleApi.cs
Normal file
78
Yavsc/src/GoogleApis/PeopleApi.cs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// PeopleApi.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.IO;
|
||||
using System.Net;
|
||||
using Newtonsoft.Json;
|
||||
using Yavsc.Models.Google;
|
||||
|
||||
namespace Yavsc.GoogleApis
|
||||
{
|
||||
/// <summary>
|
||||
/// Google People API.
|
||||
/// </summary>
|
||||
public class PeopleApi
|
||||
{
|
||||
/// <summary>
|
||||
/// The get people URI.
|
||||
/// </summary>
|
||||
protected static string getPeopleUri = "https://www.googleapis.com/plus/v1/people";
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Yavsc.Helpers.Google.Api.PeopleApi"/> class.
|
||||
/// </summary>
|
||||
/// <param name="authType">Auth type.</param>
|
||||
/// <param name="redirectUri">Redirect URI.</param>
|
||||
public PeopleApi()
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the People object associated to the given Google Access Token
|
||||
/// </summary>
|
||||
/// <returns>The me.</returns>
|
||||
/// <param name="gat">The Google Access Token object <see cref="AuthToken"/> class.</param>
|
||||
public People GetMe(AuthToken gat)
|
||||
{
|
||||
People me;
|
||||
|
||||
HttpWebRequest webreppro = WebRequest.CreateHttp(getPeopleUri + "/me");
|
||||
webreppro.ContentType = "application/http";
|
||||
webreppro.Headers.Add(HttpRequestHeader.Authorization, gat.token_type + " " + gat.access_token);
|
||||
webreppro.Method = "GET";
|
||||
using (WebResponse proresp = webreppro.GetResponse())
|
||||
{
|
||||
using (Stream prresponseStream = proresp.GetResponseStream())
|
||||
{
|
||||
using (StreamReader rdr = new StreamReader(prresponseStream))
|
||||
{
|
||||
me = JsonConvert.DeserializeObject<People>(rdr.ReadToEnd());
|
||||
prresponseStream.Close();
|
||||
}
|
||||
proresp.Close();
|
||||
}
|
||||
webreppro.Abort();
|
||||
return me;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
29
Yavsc/src/Helpers/AuthHelpers.cs
Normal file
29
Yavsc/src/Helpers/AuthHelpers.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNet.Http;
|
||||
using Microsoft.AspNet.Http.Authentication;
|
||||
|
||||
namespace Yavsc.Extensions {
|
||||
public static class HttpContextExtensions {
|
||||
public static IEnumerable<AuthenticationDescription> GetExternalProviders(this HttpContext context) {
|
||||
if (context == null) {
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
return from description in context.Authentication.GetAuthenticationSchemes()
|
||||
where !string.IsNullOrEmpty(description.DisplayName)
|
||||
select description;
|
||||
}
|
||||
|
||||
public static bool IsProviderSupported(this HttpContext context, string provider) {
|
||||
if (context == null) {
|
||||
throw new ArgumentNullException(nameof(context));
|
||||
}
|
||||
|
||||
return (from description in context.GetExternalProviders()
|
||||
where string.Equals(description.AuthenticationScheme, provider, StringComparison.OrdinalIgnoreCase)
|
||||
select description).Any();
|
||||
}
|
||||
}
|
||||
}
|
||||
21
Yavsc/src/Helpers/CompanyInfoHelpers.cs
Normal file
21
Yavsc/src/Helpers/CompanyInfoHelpers.cs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Yavsc.Model.societe.com;
|
||||
|
||||
namespace Yavsc.Helpers
|
||||
{
|
||||
public static class ComapnyInfoHelpers {
|
||||
public static async Task<CompanyInfoMessage> CheckSiren(this HttpClient web,
|
||||
string siren, CompanyInfoSettings api)
|
||||
{
|
||||
using (var request = new HttpRequestMessage(HttpMethod.Get,
|
||||
string.Format(Constants.CompanyInfoUrl,siren,api.ApiKey))) {
|
||||
using (var response = await web.SendAsync(request)) {
|
||||
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
|
||||
return payload.ToObject<CompanyInfoMessage>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
24
Yavsc/src/Helpers/EventHelpers.cs
Normal file
24
Yavsc/src/Helpers/EventHelpers.cs
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
using Microsoft.Extensions.Localization;
|
||||
using Yavsc.Models.Booking;
|
||||
using Yavsc.Models.Messaging;
|
||||
|
||||
namespace Yavsc.Helpers
|
||||
{
|
||||
public static class EventHelpers
|
||||
{
|
||||
public static YaEvent CreateEvent(this BookQuery query,
|
||||
IStringLocalizer SR)
|
||||
{
|
||||
var yaev = new YaEvent
|
||||
{
|
||||
Title = query.Client.UserName + SR["is asking you for a date"],
|
||||
Comment = (query.Previsional != null) ?
|
||||
SR["Deposit"] + string.Format(": {0:00}",
|
||||
query.Previsional) : SR["No deposit."],
|
||||
Description = SR["Address"] + ": " + query.Location.Address + "\n" +
|
||||
SR["Date"] + ": " + query.EventDate.ToString("D")
|
||||
};
|
||||
return yaev;
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Yavsc/src/Helpers/FileSystemHelpers.cs
Normal file
23
Yavsc/src/Helpers/FileSystemHelpers.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
using System.IO;
|
||||
using Microsoft.AspNet.FileProviders;
|
||||
using Yavsc.Models;
|
||||
|
||||
namespace Yavsc.Helpers
|
||||
{
|
||||
public static class FileSystemHelpers {
|
||||
public static IDirectoryContents GetFileContent(this Estimate estimate, string userFileDir)
|
||||
{
|
||||
if (estimate?.Command?.PerformerProfile?.Performer == null)
|
||||
return null;
|
||||
var fsp = new PhysicalFileProvider(
|
||||
Path.Combine(
|
||||
userFileDir,
|
||||
estimate.Command.PerformerProfile.Performer.UserName
|
||||
));
|
||||
return fsp.GetDirectoryContents(
|
||||
Path.Combine(Constants.UserBillsFilesDir, estimate.Id.ToString())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
110
Yavsc/src/Helpers/GoogleHelpers.cs
Normal file
110
Yavsc/src/Helpers/GoogleHelpers.cs
Normal file
|
|
@ -0,0 +1,110 @@
|
|||
//
|
||||
// GoogleHelpers.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.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Identity;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Yavsc.Models;
|
||||
using Yavsc.Models.Auth;
|
||||
using Yavsc.Models.Google.Messaging;
|
||||
using Yavsc.Models.Messaging;
|
||||
namespace Yavsc.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// Google helpers.
|
||||
/// </summary>
|
||||
public static class GoogleHelpers
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Notifies the event.
|
||||
/// </summary>
|
||||
/// <returns>The event.</returns>
|
||||
/// <param name="evpub">Evpub.</param>
|
||||
public static async Task<MessageWithPayloadResponse> NotifyEvent
|
||||
(this HttpClient channel, GoogleAuthSettings googleSettings, CircleEvent evpub) {
|
||||
// ASSERT ModelState.IsValid implies evpub.Circles != null
|
||||
//send a MessageWithPayload<YaEvent> to circle members
|
||||
// receive MessageWithPayloadResponse
|
||||
// "https://gcm-http.googleapis.com/gcm/send"
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, Constants.GCMNotificationUrl);
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Key", googleSettings.ApiKey);
|
||||
|
||||
var regids = new List<string> ();
|
||||
var to = new List<string> ();
|
||||
foreach (var c in evpub.Circles)
|
||||
foreach (var u in c.Members) {
|
||||
if (u.Member.GoogleRegId == null)
|
||||
to.Add (u.Member.Email);
|
||||
else
|
||||
regids.Add ((string)u.Member.GoogleRegId);
|
||||
}
|
||||
|
||||
if (regids.Count == 0)
|
||||
throw new InvalidOperationException
|
||||
("No recipient where found for this circle list");
|
||||
|
||||
var msg = new MessageWithPayload<YaEvent> () {
|
||||
notification = new Notification() { title = evpub.Title, body = evpub.Description, icon = "event" },
|
||||
data = evpub , registration_ids = regids.ToArray() };
|
||||
|
||||
var response = await channel.SendAsync(request);
|
||||
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
|
||||
return payload.Value<MessageWithPayloadResponse>();
|
||||
}
|
||||
|
||||
public static async Task<MessageWithPayloadResponse> NotifyEvent<Event>
|
||||
(this HttpClient channel, GoogleAuthSettings googleSettings, string regid, Event ev)
|
||||
where Event : YaEvent
|
||||
{
|
||||
if (regid == null)
|
||||
throw new NotImplementedException ("Notify & No GCM reg id");
|
||||
var request = new HttpRequestMessage(HttpMethod.Get, Constants.GCMNotificationUrl);
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Key", googleSettings.ApiKey);
|
||||
var msg = new MessageWithPayload<Event> () {
|
||||
notification = new Notification() { title = ev.Title,
|
||||
body = ev.Description + ev.Comment==null?
|
||||
"":"("+ev.Comment+")", icon = "icon" },
|
||||
data = ev, registration_ids = new string[] { regid } };
|
||||
|
||||
var response = await channel.SendAsync(request);
|
||||
var payload = JObject.Parse(await response.Content.ReadAsStringAsync());
|
||||
return payload.Value<MessageWithPayloadResponse>();
|
||||
}
|
||||
public static async Task<UserCredential> GetCredentialForGoogleApiAsync(this UserManager<ApplicationUser> userManager, ApplicationDbContext context, string uid)
|
||||
{
|
||||
var user = await userManager.FindByIdAsync(uid);
|
||||
var googleId = context.UserLogins.FirstOrDefault(
|
||||
x => x.UserId == uid
|
||||
).ProviderKey;
|
||||
if (string.IsNullOrEmpty(googleId))
|
||||
throw new InvalidOperationException("No Google login");
|
||||
var token = await context.GetTokensAsync(googleId);
|
||||
return new UserCredential(uid, token);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
28
Yavsc/src/Helpers/ListItemHelpers.cs
Normal file
28
Yavsc/src/Helpers/ListItemHelpers.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNet.Mvc.Rendering;
|
||||
using Yavsc.Models;
|
||||
|
||||
namespace Yavsc {
|
||||
public static class ListItemHelpers {
|
||||
|
||||
public static List<SelectListItem> ActivityItems(
|
||||
this ApplicationDbContext _dbContext, string selectedCode)
|
||||
{
|
||||
var codeIsNull = (string.IsNullOrEmpty(selectedCode));
|
||||
List<SelectListItem> items;
|
||||
if (codeIsNull) items = _dbContext.Activities.Select(
|
||||
x=> new SelectListItem() {
|
||||
Value=x.Code, Text=x.Name
|
||||
} ).ToList();
|
||||
else items =
|
||||
_dbContext.Activities.Select(
|
||||
x=> new SelectListItem() {
|
||||
Value=x.Code, Text=x.Name,
|
||||
Selected = (x.Code == selectedCode)
|
||||
} ).ToList();
|
||||
return items;
|
||||
}
|
||||
}
|
||||
}
|
||||
106
Yavsc/src/Helpers/SimpleJsonPostMethod.cs
Normal file
106
Yavsc/src/Helpers/SimpleJsonPostMethod.cs
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
//
|
||||
// PostJson.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// 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.Net;
|
||||
using System.IO;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Yavsc.Model
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple json post method.
|
||||
/// </summary>
|
||||
public class SimpleJsonPostMethod<TQuery,TAnswer>: IDisposable
|
||||
{
|
||||
internal HttpWebRequest request = null;
|
||||
internal HttpWebRequest Request { get { return request; } }
|
||||
|
||||
string CharSet {
|
||||
get { return Request.TransferEncoding; }
|
||||
set { Request.TransferEncoding=value;}
|
||||
}
|
||||
string Method { get { return Request.Method; } }
|
||||
/// <summary>
|
||||
/// Gets the path.
|
||||
/// </summary>
|
||||
/// <value>The path.</value>
|
||||
public string Path {
|
||||
get{ return Request.RequestUri.ToString(); }
|
||||
}
|
||||
/// <summary>
|
||||
/// Sets the credential.
|
||||
/// </summary>
|
||||
/// <param name="cred">Cred.</param>
|
||||
public void SetCredential(string cred) {
|
||||
Request.Headers.Set(HttpRequestHeader.Authorization,cred);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the Yavsc.Helpers.SimpleJsonPostMethod class.
|
||||
/// </summary>
|
||||
/// <param name="pathToMethod">Path to method.</param>
|
||||
public SimpleJsonPostMethod (string pathToMethod)
|
||||
{
|
||||
// ASSERT Request == null
|
||||
request = (HttpWebRequest) WebRequest.Create (pathToMethod);
|
||||
|
||||
Request.Method = "POST";
|
||||
Request.Accept = "application/json";
|
||||
Request.ContentType = "application/json";
|
||||
Request.SendChunked = true;
|
||||
Request.TransferEncoding = "UTF-8";
|
||||
}
|
||||
/// <summary>
|
||||
/// Invoke the specified query.
|
||||
/// </summary>
|
||||
/// <param name="query">Query.</param>
|
||||
public TAnswer Invoke(TQuery query)
|
||||
{
|
||||
|
||||
using (Stream streamQuery = request.GetRequestStream()) {
|
||||
using (StreamWriter writer = new StreamWriter(streamQuery)) {
|
||||
writer.Write (JsonConvert.SerializeObject(query));
|
||||
}}
|
||||
TAnswer ans = default (TAnswer);
|
||||
using (WebResponse response = Request.GetResponse ()) {
|
||||
using (Stream responseStream = response.GetResponseStream ()) {
|
||||
using (StreamReader rdr = new StreamReader (responseStream)) {
|
||||
ans = (TAnswer) JsonConvert.DeserializeObject<TAnswer> (rdr.ReadToEnd ());
|
||||
}
|
||||
}
|
||||
response.Close();
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
|
||||
#region IDisposable implementation
|
||||
|
||||
/// <summary>
|
||||
/// Releases all resource used by the Yavsc.Helpers.SimpleJsonPostMethod object.
|
||||
/// </summary>
|
||||
public void Dispose ()
|
||||
{
|
||||
if (Request != null) Request.Abort ();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
125
Yavsc/src/Helpers/TagHelpers.cs
Normal file
125
Yavsc/src/Helpers/TagHelpers.cs
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
|
||||
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using MarkdownDeep;
|
||||
using Microsoft.AspNet.Mvc.Rendering;
|
||||
using Microsoft.AspNet.Razor.TagHelpers;
|
||||
|
||||
namespace Yavsc.Helpers
|
||||
{
|
||||
[HtmlTargetElement("div", Attributes = MarkdownContentAttributeName)]
|
||||
[HtmlTargetElement("p", Attributes = "ismarkdown")]
|
||||
[HtmlTargetElement("markdown")]
|
||||
[OutputElementHint("p")]
|
||||
public class MarkdownTagHelper : TagHelper
|
||||
{
|
||||
private const string MarkdownContentAttributeName = "markdown";
|
||||
private const string MarkdownMarkAttributeName = "ismarkdown";
|
||||
|
||||
[HtmlAttributeName("site")]
|
||||
public SiteSettings Site { get; set; }
|
||||
|
||||
[HtmlAttributeName("base")]
|
||||
public string Base { get; set; }
|
||||
|
||||
[HtmlAttributeName(MarkdownContentAttributeName)]
|
||||
public string MarkdownContent { get; set; }
|
||||
|
||||
static Regex rxExtractLanguage = new Regex("^({{(.+)}}[\r\n])", RegexOptions.Compiled);
|
||||
private static string FormatCodePrettyPrint(MarkdownDeep.Markdown m, string code)
|
||||
{
|
||||
// Try to extract the language from the first line
|
||||
var match = rxExtractLanguage.Match(code);
|
||||
string language = null;
|
||||
|
||||
if (match.Success)
|
||||
{
|
||||
// Save the language
|
||||
var g = (Group)match.Groups[2];
|
||||
language = g.ToString();
|
||||
|
||||
// Remove the first line
|
||||
code = code.Substring(match.Groups[1].Length);
|
||||
}
|
||||
|
||||
// If not specified, look for a link definition called "default_syntax" and
|
||||
// grab the language from its title
|
||||
if (language == null)
|
||||
{
|
||||
var d = m.GetLinkDefinition("default_syntax");
|
||||
if (d != null)
|
||||
language = d.title;
|
||||
}
|
||||
|
||||
// Common replacements
|
||||
if (language == "C#")
|
||||
language = "csharp";
|
||||
if (language == "C++")
|
||||
language = "cpp";
|
||||
|
||||
// Wrap code in pre/code tags and add PrettyPrint attributes if necessary
|
||||
if (string.IsNullOrEmpty(language))
|
||||
return string.Format("<pre><code>{0}</code></pre>\n", code);
|
||||
else
|
||||
return string.Format("<pre class=\"prettyprint lang-{0}\"><code>{1}</code></pre>\n",
|
||||
language.ToLowerInvariant(), code);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Transforms a string of Markdown into HTML.
|
||||
/// </summary>
|
||||
/// <param name="helper">HtmlHelper - Not used, but required to make this an extension method.</param>
|
||||
/// <param name="text">The Markdown that should be transformed.</param>
|
||||
/// <param name="urlBaseLocation">The url Base Location.</param>
|
||||
/// <returns>The HTML representation of the supplied Markdown.</returns>
|
||||
public string Markdown(string text, string urlBaseLocation = "")
|
||||
{
|
||||
// Transform the supplied text (Markdown) into HTML.
|
||||
var markdownTransformer = GetMarkdownTransformer();
|
||||
markdownTransformer.UrlBaseLocation = urlBaseLocation;
|
||||
string html = markdownTransformer.Transform(text);
|
||||
// Wrap the html in an MvcHtmlString otherwise it'll be HtmlEncoded and displayed to the user as HTML :(
|
||||
return html;
|
||||
}
|
||||
|
||||
internal Markdown GetMarkdownTransformer()
|
||||
{
|
||||
var markdownTransformer = new Markdown();
|
||||
markdownTransformer.ExtraMode = true;
|
||||
markdownTransformer.NoFollowLinks = true;
|
||||
markdownTransformer.SafeMode = false;
|
||||
markdownTransformer.FormatCodeBlock = FormatCodePrettyPrint;
|
||||
markdownTransformer.ExtractHeadBlocks = true;
|
||||
markdownTransformer.UserBreaks = true;
|
||||
return markdownTransformer;
|
||||
}
|
||||
|
||||
public ModelExpression Content { get; set; }
|
||||
public async override Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
|
||||
{
|
||||
if (output.TagName == "markdown")
|
||||
{
|
||||
output.TagName = null;
|
||||
}
|
||||
output.Attributes.RemoveAll("markdown");
|
||||
|
||||
var content = await GetContent(output);
|
||||
var markdown = content;
|
||||
var basePath = Base?.StartsWith("~") ?? false ? Constants.UserFilesRequestPath+
|
||||
Base.Substring(1) : Base;
|
||||
var html = Markdown(markdown, basePath);
|
||||
output.Content.SetHtmlContent(html ?? "");
|
||||
}
|
||||
private async Task<string> GetContent(TagHelperOutput output)
|
||||
{
|
||||
if (MarkdownContent != null)
|
||||
return MarkdownContent;
|
||||
if (Content != null)
|
||||
return Content.Model?.ToString();
|
||||
return (await output.GetChildContentAsync(false)).GetContent();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
63
Yavsc/src/Hubs/ChatHub.cs
Normal file
63
Yavsc/src/Hubs/ChatHub.cs
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
//
|
||||
// MyHub.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paul@pschneider.fr>
|
||||
//
|
||||
// Copyright (c) 2016 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.Threading.Tasks;
|
||||
using Microsoft.AspNet.SignalR;
|
||||
|
||||
namespace Yavsc
|
||||
{
|
||||
|
||||
public class ChatHub : Hub
|
||||
{
|
||||
public override Task OnConnected()
|
||||
{
|
||||
if (Context.User!=null) {
|
||||
var group = (Context.User.Identity.IsAuthenticated)?
|
||||
"authenticated":"anonymous";
|
||||
// Log ("Cx: " + group);
|
||||
Groups.Add(Context.ConnectionId, group);
|
||||
} else Groups.Add(Context.ConnectionId, "anonymous");
|
||||
return base.OnConnected ();
|
||||
}
|
||||
public override Task OnDisconnected (bool stopCalled)
|
||||
{
|
||||
return base.OnDisconnected (stopCalled);
|
||||
}
|
||||
|
||||
public override Task OnReconnected ()
|
||||
{
|
||||
return base.OnReconnected ();
|
||||
}
|
||||
|
||||
public void Send(string name, string message)
|
||||
{
|
||||
|
||||
Clients.All.addMessage(name,message);
|
||||
}
|
||||
|
||||
[Authorize]
|
||||
public void AuthSend (string name, string message)
|
||||
{
|
||||
Clients.All.addMessage("#"+name,message);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
16
Yavsc/src/Interfaces/IDataStore.cs
Normal file
16
Yavsc/src/Interfaces/IDataStore.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
using System.Threading.Tasks;
|
||||
|
||||
namespace Yavsc.Interfaces {
|
||||
|
||||
public interface IDataStore<T> {
|
||||
|
||||
Task StoreAsync (string key, T value);
|
||||
|
||||
Task DeleteAsync (string key);
|
||||
|
||||
Task<T> GetAsync (string key);
|
||||
|
||||
Task ClearAsync ();
|
||||
|
||||
}
|
||||
}
|
||||
36
Yavsc/src/Interfaces/IIdentified.cs
Normal file
36
Yavsc/src/Interfaces/IIdentified.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// IIdentified.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/>.
|
||||
|
||||
namespace Yavsc.Interfaces
|
||||
{
|
||||
/// <summary>
|
||||
/// I identified.
|
||||
/// </summary>
|
||||
public interface IIdentified<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the identifier.
|
||||
/// </summary>
|
||||
/// <value>The identifier.</value>
|
||||
T Id { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
28
Yavsc/src/Interfaces/IPerformerSpecified.cs
Normal file
28
Yavsc/src/Interfaces/IPerformerSpecified.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
//
|
||||
// INominative.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/>.
|
||||
|
||||
namespace Yavsc.Interfaces
|
||||
{
|
||||
public interface IPerformerSpecified {
|
||||
string PerformerName { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
36
Yavsc/src/Interfaces/IRating.cs
Normal file
36
Yavsc/src/Interfaces/IRating.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// IIdentified.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/>.
|
||||
namespace Yavsc.Interfaces
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// I rating.
|
||||
/// </summary>
|
||||
public interface IRating: IIdentified<long>
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the rate.
|
||||
/// </summary>
|
||||
/// <value>The rate.</value>
|
||||
int Rate { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
28
Yavsc/src/Interfaces/ITitle.cs
Normal file
28
Yavsc/src/Interfaces/ITitle.cs
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
//
|
||||
// ITitle.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/>.
|
||||
namespace Yavsc.Interfaces
|
||||
{
|
||||
public interface ITitle
|
||||
{
|
||||
string Title { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
61
Yavsc/src/LanguageActionFilter.cs
Normal file
61
Yavsc/src/LanguageActionFilter.cs
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
using System.Globalization;
|
||||
|
||||
namespace Yavsc
|
||||
{
|
||||
using Microsoft.AspNet.Mvc.Filters;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
public class LanguageActionFilter : ActionFilterAttribute
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
|
||||
public LanguageActionFilter(ILoggerFactory loggerFactory)
|
||||
{
|
||||
_logger = loggerFactory.CreateLogger("LanguageActionFilter");
|
||||
}
|
||||
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
string culture = null;
|
||||
var routedCulture = context.RouteData.Values["culture"];
|
||||
if (routedCulture != null) {
|
||||
culture = routedCulture.ToString();
|
||||
_logger.LogInformation($"Setting the culture from the URL: {culture}");
|
||||
|
||||
}
|
||||
else {
|
||||
if (context.HttpContext.Request.Headers.ContainsKey("accept-language"))
|
||||
{
|
||||
// fr,en-US;q=0.7,en;q=0.3
|
||||
string spec = context.HttpContext.Request.Headers["accept-language"];
|
||||
_logger.LogInformation($"Setting the culture from language header spec: {spec}");
|
||||
|
||||
string firstpart = spec.Split(';')[0];
|
||||
foreach (string lang in firstpart.Split(','))
|
||||
{
|
||||
// TODO do it from the given options ...
|
||||
// just take the main part :-)
|
||||
string mainlang = lang.Split('-')[0];
|
||||
if (mainlang=="fr"||mainlang=="en") {
|
||||
culture = mainlang;
|
||||
_logger.LogInformation($"Setting the culture from header: {culture}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (culture != null) {
|
||||
#if DNX451
|
||||
System.Threading.Thread.CurrentThread.CurrentCulture = new CultureInfo(culture);
|
||||
System.Threading.Thread.CurrentThread.CurrentUICulture = new CultureInfo(culture);
|
||||
#else
|
||||
CultureInfo.CurrentCulture = new CultureInfo(culture);
|
||||
CultureInfo.CurrentUICulture = new CultureInfo(culture);
|
||||
#endif
|
||||
}
|
||||
base.OnActionExecuting(context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
1
Yavsc/src/Model/Access/PerformerIM.cs
Normal file
1
Yavsc/src/Model/Access/PerformerIM.cs
Normal file
|
|
@ -0,0 +1 @@
|
|||
|
||||
50
Yavsc/src/Model/Access/Publishing.cs
Normal file
50
Yavsc/src/Model/Access/Publishing.cs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
//
|
||||
// Publishing.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// 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/>.
|
||||
|
||||
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Publishing.
|
||||
/// </summary>
|
||||
public enum Publishing {
|
||||
/// <summary>
|
||||
/// In the context of immediate use, with no related stored content.
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// In the context of private use of an uploaded content.
|
||||
/// </summary>
|
||||
Private,
|
||||
/// <summary>
|
||||
/// In the context of restricted access areas, like circle members views.
|
||||
/// </summary>
|
||||
Restricted,
|
||||
/// <summary>
|
||||
/// Publishing a content in a public access area.
|
||||
/// </summary>
|
||||
Public
|
||||
}
|
||||
|
||||
}
|
||||
10
Yavsc/src/Model/Access/Rule.cs
Normal file
10
Yavsc/src/Model/Access/Rule.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
using Microsoft.AspNet.Authorization;
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
public abstract class Rule<TResource> where TResource : IAuthorizationRequirement
|
||||
{
|
||||
public virtual bool Mandatory { get; set; }
|
||||
public abstract bool Allow(ApplicationUser user);
|
||||
}
|
||||
}
|
||||
16
Yavsc/src/Model/Access/RuleSet.cs
Normal file
16
Yavsc/src/Model/Access/RuleSet.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Microsoft.AspNet.Authorization;
|
||||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
|
||||
public class RuleSet <TResource>:List<Rule<TResource>> where TResource : IAuthorizationRequirement{
|
||||
|
||||
bool Allow(ApplicationUser user)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
8
Yavsc/src/Model/Access/WhiteCard.cs
Normal file
8
Yavsc/src/Model/Access/WhiteCard.cs
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
namespace Yavsc.Models.Access
|
||||
{
|
||||
|
||||
public class WhiteCard {
|
||||
|
||||
}
|
||||
}
|
||||
143
Yavsc/src/Model/ApplicationDbContext.cs
Normal file
143
Yavsc/src/Model/ApplicationDbContext.cs
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Authentication.OAuth;
|
||||
using Microsoft.AspNet.Identity.EntityFramework;
|
||||
using Microsoft.Data.Entity;
|
||||
using Yavsc.Models.Booking;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
|
||||
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
|
||||
{
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
base.OnModelCreating(builder);
|
||||
// Customize the ASP.NET Identity model and override the defaults if needed.
|
||||
// For example, you can rename the ASP.NET Identity table names and more.
|
||||
// Add your customizations after calling base.OnModelCreating(builder);
|
||||
builder.Entity<Contact>().HasKey(x => new { x.OwnerId, x.UserId });
|
||||
builder.Entity<BookQuery>().Property(x=>x.CreationDate).HasDefaultValueSql("LOCALTIMESTAMP");
|
||||
}
|
||||
public DbSet<Application> Applications { get; set; }
|
||||
/// <summary>
|
||||
/// Activities referenced on this site
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public DbSet<Activity> Activities { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Users posts
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public DbSet<Blog> Blogspot { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Skills propulsed by this site
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public DbSet<Skill> SiteSkills { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Circle members
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public DbSet<CircleMember> CircleMembers { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Commands, from an user, to a performer
|
||||
/// (A performer is an user who's actived a main activity
|
||||
/// on his profile).
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public DbSet<Command> Commands { get; set; }
|
||||
/// <summary>
|
||||
/// Special commands, talking about
|
||||
/// a given place and date.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public DbSet<Booking.BookQuery> BookQueries { get; set; }
|
||||
public DbSet<PerformerProfile> Performers { get; set; }
|
||||
public DbSet<Estimate> Estimates { get; set; }
|
||||
public DbSet<AccountBalance> BankStatus { get; set; }
|
||||
public DbSet<BalanceImpact> BankBook { get; set; }
|
||||
public DbSet<Location> Map { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Google Calendar offline
|
||||
/// open auth tokens
|
||||
/// </summary>
|
||||
/// <returns>tokens</returns>
|
||||
public DbSet<OAuth2Tokens> Tokens { get; set; }
|
||||
|
||||
public Task ClearTokensAsync()
|
||||
{
|
||||
Tokens.RemoveRange(this.Tokens);
|
||||
SaveChanges();
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task DeleteTokensAsync(string email)
|
||||
{
|
||||
if (string.IsNullOrEmpty(email))
|
||||
{
|
||||
throw new ArgumentException("email MUST have a value");
|
||||
}
|
||||
|
||||
var item = this.Tokens.FirstOrDefault(x => x.UserId == email);
|
||||
if (item != null)
|
||||
{
|
||||
Tokens.Remove(item);
|
||||
SaveChanges();
|
||||
}
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
|
||||
public Task<OAuth2Tokens> GetTokensAsync(string googleUserId)
|
||||
{
|
||||
if (string.IsNullOrEmpty(googleUserId))
|
||||
{
|
||||
throw new ArgumentException("email MUST have a value");
|
||||
}
|
||||
|
||||
using (var context = new ApplicationDbContext())
|
||||
{
|
||||
var item = this.Tokens.FirstOrDefault(x => x.UserId == googleUserId);
|
||||
return Task.FromResult(item);
|
||||
}
|
||||
}
|
||||
|
||||
public Task StoreTokenAsync(string googleUserId, OAuthTokenResponse value)
|
||||
{
|
||||
if (string.IsNullOrEmpty(googleUserId))
|
||||
{
|
||||
throw new ArgumentException("googleUserId MUST have a value");
|
||||
}
|
||||
|
||||
var item = this.Tokens.SingleOrDefaultAsync(x => x.UserId == googleUserId).Result;
|
||||
if (item == null)
|
||||
{
|
||||
Tokens.Add(new OAuth2Tokens
|
||||
{
|
||||
TokenType = "Bearer", // FIXME why value.TokenType would be null?
|
||||
AccessToken = value.AccessToken,
|
||||
RefreshToken = value.RefreshToken,
|
||||
Expiration = DateTime.Now.AddSeconds(int.Parse(value.ExpiresIn)),
|
||||
UserId = googleUserId
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
item.AccessToken = value.AccessToken;
|
||||
item.Expiration = DateTime.Now.AddMinutes(int.Parse(value.ExpiresIn));
|
||||
if (value.RefreshToken != null)
|
||||
item.RefreshToken = value.RefreshToken;
|
||||
Tokens.Update(item);
|
||||
}
|
||||
SaveChanges();
|
||||
return Task.FromResult(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
12
Yavsc/src/Model/Auth/Application.cs
Normal file
12
Yavsc/src/Model/Auth/Application.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
namespace Yavsc
|
||||
{
|
||||
public class Application
|
||||
{
|
||||
public string ApplicationID { get; set; }
|
||||
public string DisplayName { get; set; }
|
||||
public string RedirectUri { get; set; }
|
||||
public string LogoutRedirectUri { get; set; }
|
||||
public string Secret { get; set; }
|
||||
}
|
||||
}
|
||||
10
Yavsc/src/Model/Auth/Scope.cs
Normal file
10
Yavsc/src/Model/Auth/Scope.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
namespace Yavsc.Models.Auth {
|
||||
public class Scope {
|
||||
|
||||
public string Id { get; set; }
|
||||
|
||||
public string Description { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
20
Yavsc/src/Model/Auth/UserCredentials.cs
Normal file
20
Yavsc/src/Model/Auth/UserCredentials.cs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
namespace Yavsc.Models.Auth {
|
||||
|
||||
public class UserCredential {
|
||||
public string UserId { get; set; }
|
||||
|
||||
public OAuth2Tokens Tokens { get; set; }
|
||||
public UserCredential(string userId, OAuth2Tokens tokens)
|
||||
{
|
||||
UserId = userId;
|
||||
Tokens = tokens;
|
||||
}
|
||||
|
||||
public string GetHeader()
|
||||
{
|
||||
return Tokens.TokenType+" "+Tokens.AccessToken;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
21
Yavsc/src/Model/Bank/AccountBalance.cs
Normal file
21
Yavsc/src/Model/Bank/AccountBalance.cs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
|
||||
|
||||
public partial class AccountBalance {
|
||||
[Key]
|
||||
public string UserId { get; set; }
|
||||
|
||||
[ForeignKey("UserId")]
|
||||
public virtual ApplicationUser Owner { get; set; }
|
||||
|
||||
[Required,Display(Name="Credits in €")]
|
||||
public decimal Credits { get; set; }
|
||||
|
||||
public long ContactCredits { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
26
Yavsc/src/Model/Bank/BalanceImpact.cs
Normal file
26
Yavsc/src/Model/Bank/BalanceImpact.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
public partial class BalanceImpact {
|
||||
[Required,Key,DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long Id { get; set; }
|
||||
|
||||
[Required,Display(Name="Impact")]
|
||||
public decimal Impact { get; set; }
|
||||
|
||||
[Required,Display(Name="Execution date")]
|
||||
public DateTime ExecDate { get; set; }
|
||||
|
||||
[Required,Display(Name="Reason")]
|
||||
public string Reason { get; set; }
|
||||
[Required]
|
||||
public string BalanceId { get; set; }
|
||||
|
||||
[ForeignKey("BalanceId")]
|
||||
public virtual AccountBalance Balance { get; set; }
|
||||
}
|
||||
}
|
||||
19
Yavsc/src/Model/Billing/CommandLine.cs
Normal file
19
Yavsc/src/Model/Billing/CommandLine.cs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
|
||||
public class CommandLine {
|
||||
|
||||
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long Id { get; set; }
|
||||
public string Comment { get; set; }
|
||||
public BaseProduct Article { get; set; }
|
||||
public int Count { get; set; }
|
||||
public decimal UnitaryCost { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
51
Yavsc/src/Model/Billing/Commande.cs
Normal file
51
Yavsc/src/Model/Billing/Commande.cs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
|
||||
public class Command {
|
||||
|
||||
/// <summary>
|
||||
/// The command identifier
|
||||
/// </summary>
|
||||
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long Id {get; set; }
|
||||
|
||||
public string ClientId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The client
|
||||
/// </summary>
|
||||
[Required,ForeignKey("ClientId")]
|
||||
public ApplicationUser Client { get; set; }
|
||||
|
||||
[Required]
|
||||
public string PerformerId { get; set; }
|
||||
/// <summary>
|
||||
/// The performer identifier
|
||||
/// </summary>
|
||||
[ForeignKey("PerformerId")]
|
||||
public PerformerProfile PerformerProfile { get; set; }
|
||||
|
||||
public DateTime? ValidationDate {get; set;}
|
||||
|
||||
/// <summary>
|
||||
/// Command creation Date & time
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public DateTime CreationDate {get; set;}
|
||||
|
||||
public decimal? Previsional { get; set; }
|
||||
public List<CommandLine> Bill { get; set; }
|
||||
|
||||
///<summary>
|
||||
/// Time span in seconds in which
|
||||
/// Validation will be considered as definitive
|
||||
///</summary>
|
||||
public int Lag { get; set; }
|
||||
}
|
||||
}
|
||||
51
Yavsc/src/Model/Billing/Estimate.cs
Normal file
51
Yavsc/src/Model/Billing/Estimate.cs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
public partial class Estimate
|
||||
{
|
||||
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long Id { get; set; }
|
||||
|
||||
public long? CommandId { get; set; }
|
||||
/// <summary>
|
||||
/// A command is not required to create
|
||||
/// an estimate,
|
||||
/// it will result in a new estimate template
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[ForeignKey("CommandId")]
|
||||
public virtual Command Command { get; set; }
|
||||
public string Description { get; set; }
|
||||
public int? Status { get; set; }
|
||||
public string Title { get; set; }
|
||||
public List<CommandLine> Bill { get; set; }
|
||||
/// <summary>
|
||||
/// List of attached graphic files
|
||||
/// to this estimate, as relative pathes to
|
||||
/// the command performer's root path.
|
||||
/// In db, they are separated by <c>:</c>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[NotMapped]
|
||||
public List<string> AttachedGraphics { get; set; }
|
||||
|
||||
public string AttachedGraphicsString { get { return string.Join(":", AttachedGraphics); }
|
||||
set { AttachedGraphics = value.Split(':').ToList(); } }
|
||||
/// <summary>
|
||||
/// List of attached files
|
||||
/// to this estimate, as relative pathes to
|
||||
/// the command performer's root path.
|
||||
/// In db, they are separated by <c>:</c>
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[NotMapped]
|
||||
public List<string> AttachedFiles { get; set; }
|
||||
public string AttachedFilesString { get { return string.Join(":", AttachedFiles); }
|
||||
set { AttachedFiles = value.Split(':').ToList(); } }
|
||||
}
|
||||
}
|
||||
10
Yavsc/src/Model/Billing/EstimateAgreement.cs
Normal file
10
Yavsc/src/Model/Billing/EstimateAgreement.cs
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
using System;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
public partial class EstimateAgreement : Estimate
|
||||
{
|
||||
public DateTime ClientValidationDate { get; set; }
|
||||
}
|
||||
}
|
||||
5
Yavsc/src/Model/Billing/Service/ChatBilling.cs
Normal file
5
Yavsc/src/Model/Billing/Service/ChatBilling.cs
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
|
||||
class ChatBilling {
|
||||
|
||||
}
|
||||
14
Yavsc/src/Model/Billing/histoestim.cs
Normal file
14
Yavsc/src/Model/Billing/histoestim.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
public partial class histoestim
|
||||
{
|
||||
public long _id { get; set; }
|
||||
public string applicationname { get; set; }
|
||||
public DateTime datechange { get; set; }
|
||||
public long estid { get; set; }
|
||||
public int? status { get; set; }
|
||||
public string username { get; set; }
|
||||
}
|
||||
}
|
||||
17
Yavsc/src/Model/Billing/satisfaction.cs
Normal file
17
Yavsc/src/Model/Billing/satisfaction.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
public partial class satisfaction
|
||||
{
|
||||
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long _id { get; set; }
|
||||
public string comnt { get; set; }
|
||||
public int? rate { get; set; }
|
||||
|
||||
[ForeignKey("Skill.Id")]
|
||||
public long? userskillid { get; set; }
|
||||
}
|
||||
}
|
||||
13
Yavsc/src/Model/Billing/writtings.cs
Normal file
13
Yavsc/src/Model/Billing/writtings.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
public partial class writtings
|
||||
{
|
||||
public long _id { get; set; }
|
||||
public int? count { get; set; }
|
||||
public string description { get; set; }
|
||||
public long estimid { get; set; }
|
||||
public string productid { get; set; }
|
||||
public decimal? ucost { get; set; }
|
||||
}
|
||||
}
|
||||
9
Yavsc/src/Model/Billing/wrtags.cs
Normal file
9
Yavsc/src/Model/Billing/wrtags.cs
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
public partial class wrtags
|
||||
{
|
||||
public long wrid { get; set; }
|
||||
public long tagid { get; set; }
|
||||
}
|
||||
}
|
||||
25
Yavsc/src/Model/Blog/Blog.cs
Normal file
25
Yavsc/src/Model/Blog/Blog.cs
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
public partial class Blog
|
||||
{
|
||||
[Key(), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
|
||||
public long Id { get; set; }
|
||||
public string bcontent { get; set; }
|
||||
|
||||
[DisplayAttribute(Name="Modified")]
|
||||
public DateTime modified { get; set; }
|
||||
public string photo { get; set; }
|
||||
public DateTime posted { get; set; }
|
||||
public int rate { get; set; }
|
||||
public string title { get; set; }
|
||||
[Required]
|
||||
public string AuthorId { get; set; }
|
||||
[ForeignKey("AuthorId")]
|
||||
public ApplicationUser Author { set; get; }
|
||||
public bool visible { get; set; }
|
||||
}
|
||||
}
|
||||
15
Yavsc/src/Model/Blog/BlogAccess.cs
Normal file
15
Yavsc/src/Model/Blog/BlogAccess.cs
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
|
||||
public partial class BlogAccess
|
||||
{
|
||||
[ForeignKey("Blog.Id")]
|
||||
public long PostId { get; set; }
|
||||
|
||||
[ForeignKey("Circle.Id")]
|
||||
public long CircleId { get; set; }
|
||||
}
|
||||
}
|
||||
16
Yavsc/src/Model/Blog/IBlogspotRepository.cs
Normal file
16
Yavsc/src/Model/Blog/IBlogspotRepository.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
|
||||
public interface IBlogspotRepository
|
||||
{
|
||||
void Add(Blog item);
|
||||
IEnumerable<Blog> GetAll();
|
||||
Blog Find(string key);
|
||||
Blog Remove(string key);
|
||||
void Update(Blog item);
|
||||
}
|
||||
|
||||
}
|
||||
16
Yavsc/src/Model/Blog/comment.cs
Normal file
16
Yavsc/src/Model/Blog/comment.cs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
|
||||
namespace Yavsc.Models
|
||||
{
|
||||
public partial class comment
|
||||
{
|
||||
public long _id { get; set; }
|
||||
public string applicationname { get; set; }
|
||||
public string bcontent { get; set; }
|
||||
public DateTime modified { get; set; }
|
||||
public DateTime posted { get; set; }
|
||||
public long? postid { get; set; }
|
||||
public string username { get; set; }
|
||||
public bool visible { get; set; }
|
||||
}
|
||||
}
|
||||
36
Yavsc/src/Model/Booking/BookQuery.cs
Normal file
36
Yavsc/src/Model/Booking/BookQuery.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Yavsc.Models.Booking
|
||||
{
|
||||
/// <summary>
|
||||
/// Query, for a date, with a given perfomer, at this given place.
|
||||
/// </summary>
|
||||
|
||||
public class BookQuery : Command {
|
||||
|
||||
/// <summary>
|
||||
/// Event date
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Required(ErrorMessageResourceName="ChooseAnEventDate",
|
||||
ErrorMessageResourceType=typeof(Resources.YavscLoc)),Display(Name="EventDate")]
|
||||
public DateTime EventDate { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Location identifier
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Required]
|
||||
public long LocationId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// A Location for this event
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[Required(ErrorMessage="SpecifyPlace"),Display(Name="Location"),ForeignKey("LocationId")]
|
||||
public Location Location { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
46
Yavsc/src/Model/Calendar/ICalendarManager.cs
Normal file
46
Yavsc/src/Model/Calendar/ICalendarManager.cs
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
//
|
||||
// ICalendarManager.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 Yavsc.Models.Booking;
|
||||
using Yavsc.Models.Messaging;
|
||||
|
||||
namespace Yavsc.Models.Calendar
|
||||
{
|
||||
/// <summary>
|
||||
/// I calendar manager.
|
||||
/// </summary>
|
||||
public interface ICalendarManager {
|
||||
/// <summary>
|
||||
/// Gets the free dates.
|
||||
/// </summary>
|
||||
/// <returns>The free dates.</returns>
|
||||
/// <param name="username">Username.</param>
|
||||
/// <param name="req">Req.</param>
|
||||
IFreeDateSet GetFreeDates(string username, BookQuery req);
|
||||
/// <summary>
|
||||
/// Book the specified username and ev.
|
||||
/// </summary>
|
||||
/// <param name="username">Username.</param>
|
||||
/// <param name="ev">Ev.</param>
|
||||
bool Book(string username, YaEvent ev);
|
||||
}
|
||||
}
|
||||
53
Yavsc/src/Model/Calendar/IFreeDateSet.cs
Normal file
53
Yavsc/src/Model/Calendar/IFreeDateSet.cs
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
// FreeDate.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// 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.Collections.Generic;
|
||||
|
||||
namespace Yavsc.Models.Calendar
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Free date.
|
||||
/// </summary>
|
||||
public interface IFreeDateSet
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the reference.
|
||||
/// </summary>
|
||||
/// <value>The reference.</value>
|
||||
IEnumerable<Period> Values { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the duration.
|
||||
/// </summary>
|
||||
/// <value>The duration.</value>
|
||||
TimeSpan Duration { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the attendees.
|
||||
/// </summary>
|
||||
/// <value>The attendees.</value>
|
||||
string UserName { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the location.
|
||||
/// </summary>
|
||||
/// <value>The location.</value>
|
||||
string Location { get; set; }
|
||||
}
|
||||
}
|
||||
|
||||
60
Yavsc/src/Model/Calendar/OpenDay.cs
Normal file
60
Yavsc/src/Model/Calendar/OpenDay.cs
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
//
|
||||
// OpenDay.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// 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.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Yavsc.Models.Calendar
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Open day.
|
||||
/// </summary>
|
||||
public class OpenDay {
|
||||
/// <summary>
|
||||
/// The day.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public WeekDay Day;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the s.
|
||||
/// </summary>
|
||||
/// <value>The s.</value>
|
||||
public TimeSpan S { get; set; }
|
||||
|
||||
// ASSERT Start <= End
|
||||
/// <summary>
|
||||
/// Gets or sets the start hour.
|
||||
/// </summary>
|
||||
/// <value>The start.</value>
|
||||
[Required]
|
||||
public TimeSpan Start { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the end hour
|
||||
/// (from the next day if lower than the Start).
|
||||
/// </summary>
|
||||
/// <value>The end.</value>
|
||||
[Required]
|
||||
public TimeSpan End { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
45
Yavsc/src/Model/Calendar/Period.cs
Normal file
45
Yavsc/src/Model/Calendar/Period.cs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
//
|
||||
// Period.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// 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.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Yavsc.Models.Calendar
|
||||
{
|
||||
/// <summary>
|
||||
/// Hollydays.
|
||||
/// </summary>
|
||||
public class Period {
|
||||
/// <summary>
|
||||
/// Gets or sets the start.
|
||||
/// </summary>
|
||||
/// <value>The start.</value>
|
||||
[Required]
|
||||
public DateTime Start { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the end.
|
||||
/// </summary>
|
||||
/// <value>The end.</value>
|
||||
[Required]
|
||||
public DateTime End { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
54
Yavsc/src/Model/Calendar/Periodicity.cs
Normal file
54
Yavsc/src/Model/Calendar/Periodicity.cs
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
//
|
||||
// Periodicity.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// 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/>.
|
||||
|
||||
namespace Yavsc.Models.Calendar
|
||||
{
|
||||
/// <summary>
|
||||
/// Periodicity.
|
||||
/// </summary>
|
||||
public enum Periodicity {
|
||||
/// <summary>
|
||||
/// The daily.
|
||||
/// </summary>
|
||||
Daily,
|
||||
/// <summary>
|
||||
/// The weekly.
|
||||
/// </summary>
|
||||
Weekly,
|
||||
/// <summary>
|
||||
/// The monthly.
|
||||
/// </summary>
|
||||
Monthly,
|
||||
/// <summary>
|
||||
/// The three m.
|
||||
/// </summary>
|
||||
ThreeM,
|
||||
/// <summary>
|
||||
/// The six m.
|
||||
/// </summary>
|
||||
SixM,
|
||||
/// <summary>
|
||||
/// The yearly.
|
||||
/// </summary>
|
||||
Yearly
|
||||
}
|
||||
|
||||
}
|
||||
40
Yavsc/src/Model/Calendar/PositionAndKeyphrase.cs
Normal file
40
Yavsc/src/Model/Calendar/PositionAndKeyphrase.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
//
|
||||
// PositionAndKeyphrase.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// 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/>.
|
||||
|
||||
|
||||
|
||||
namespace Yavsc.Models.Calendar
|
||||
{
|
||||
/// <summary>
|
||||
/// Position and keyphrase.
|
||||
/// </summary>
|
||||
public class PositionAndKeyphrase {
|
||||
/// <summary>
|
||||
/// The phrase.
|
||||
/// </summary>
|
||||
public string phrase;
|
||||
/// <summary>
|
||||
/// The position.
|
||||
/// </summary>
|
||||
public Position pos;
|
||||
}
|
||||
|
||||
}
|
||||
39
Yavsc/src/Model/Calendar/ProvidedEvent.cs
Normal file
39
Yavsc/src/Model/Calendar/ProvidedEvent.cs
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
//
|
||||
// ProvidedEvent.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// 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.ComponentModel.DataAnnotations;
|
||||
using Yavsc.Models.Messaging;
|
||||
|
||||
namespace Yavsc.Models.Calendar
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Provided event.
|
||||
/// </summary>
|
||||
public class ProvidedEvent : YaEvent {
|
||||
/// <summary>
|
||||
/// The privacy.
|
||||
/// </summary>
|
||||
[Required]
|
||||
public Publishing Privacy;
|
||||
}
|
||||
|
||||
}
|
||||
50
Yavsc/src/Model/Calendar/Schedule.cs
Normal file
50
Yavsc/src/Model/Calendar/Schedule.cs
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
//
|
||||
// Schedule.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// 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.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Yavsc.Models.Calendar
|
||||
{
|
||||
/// <summary>
|
||||
/// Schedule.
|
||||
/// </summary>
|
||||
public class Schedule {
|
||||
/// <summary>
|
||||
/// Gets or sets the period.
|
||||
/// </summary>
|
||||
/// <value>The period.</value>
|
||||
public Periodicity Period { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the schedule of an open week.
|
||||
/// One item by bay in the week,
|
||||
/// </summary>
|
||||
/// <value>The weekly workdays.</value>
|
||||
public OpenDay [] WeekDays { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the hollydays.
|
||||
/// </summary>
|
||||
/// <value>The hollydays.</value>
|
||||
[Required]
|
||||
public Period [] Validity { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
58
Yavsc/src/Model/Calendar/WeekDay.cs
Normal file
58
Yavsc/src/Model/Calendar/WeekDay.cs
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
//
|
||||
// WeekDay.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// 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/>.
|
||||
|
||||
namespace Yavsc.Models.Calendar
|
||||
{
|
||||
/// <summary>
|
||||
/// Week day.
|
||||
/// </summary>
|
||||
public enum WeekDay:int {
|
||||
/// <summary>
|
||||
/// The monday (0).
|
||||
/// </summary>
|
||||
Monday=0,
|
||||
/// <summary>
|
||||
/// The tuesday.
|
||||
/// </summary>
|
||||
Tuesday,
|
||||
/// <summary>
|
||||
/// The wednesday.
|
||||
/// </summary>
|
||||
Wednesday,
|
||||
/// <summary>
|
||||
/// The thursday.
|
||||
/// </summary>
|
||||
Thursday,
|
||||
/// <summary>
|
||||
/// The friday.
|
||||
/// </summary>
|
||||
Friday,
|
||||
/// <summary>
|
||||
/// The saturday.
|
||||
/// </summary>
|
||||
Saturday,
|
||||
/// <summary>
|
||||
/// The sunday.
|
||||
/// </summary>
|
||||
Sunday
|
||||
}
|
||||
|
||||
}
|
||||
13
Yavsc/src/Model/Edition/IDocument.cs
Normal file
13
Yavsc/src/Model/Edition/IDocument.cs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
|
||||
namespace Yavsc.Models {
|
||||
|
||||
public class Parameter {
|
||||
public string Name { get; set; }
|
||||
public string Value { get; set; }
|
||||
}
|
||||
public interface IDocument {
|
||||
string Template { get; set; }
|
||||
Parameter [] Parameters { get; set; }
|
||||
}
|
||||
}
|
||||
56
Yavsc/src/Model/Google/AuthToken.cs
Normal file
56
Yavsc/src/Model/Google/AuthToken.cs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
//
|
||||
// GoogleAuthToken.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2014 Paul Schneider
|
||||
//
|
||||
// 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/>.
|
||||
|
||||
|
||||
namespace Yavsc.Models.Google
|
||||
{
|
||||
/// <summary>
|
||||
/// Auth token, as they are received.
|
||||
/// </summary>
|
||||
public class AuthToken {
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the access token.
|
||||
/// </summary>
|
||||
/// <value>The access token.</value>
|
||||
public string access_token { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the identifier token.
|
||||
/// </summary>
|
||||
/// <value>The identifier token.</value>
|
||||
public string id_token { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the token.
|
||||
/// </summary>
|
||||
/// <value>The type of the token.</value>
|
||||
public string token_type { get; set ; }
|
||||
/// <summary>
|
||||
/// Gets or sets the refresh token.
|
||||
/// </summary>
|
||||
/// <value>The refresh token.</value>
|
||||
public string refresh_token { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the expires in.
|
||||
/// </summary>
|
||||
/// <value>The expires in.</value>
|
||||
public int expires_in { get; set; }
|
||||
}
|
||||
}
|
||||
43
Yavsc/src/Model/Google/Calendar/CalendarEventList.cs
Normal file
43
Yavsc/src/Model/Google/Calendar/CalendarEventList.cs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// CalendarEventList.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// 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/>.
|
||||
namespace Yavsc.Models.Google
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Calendar event list.
|
||||
/// </summary>
|
||||
public class CalendarEventList
|
||||
{
|
||||
/// <summary>
|
||||
/// The next page token.
|
||||
/// </summary>
|
||||
public string nextPageToken;
|
||||
/// <summary>
|
||||
/// The next sync token.
|
||||
/// </summary>
|
||||
public string nextSyncToken;
|
||||
/// <summary>
|
||||
/// The items.
|
||||
/// </summary>
|
||||
public Resource [] items ;
|
||||
}
|
||||
}
|
||||
|
||||
51
Yavsc/src/Model/Google/Calendar/CalendarList.cs
Normal file
51
Yavsc/src/Model/Google/Calendar/CalendarList.cs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// CalendarList.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2014 Paul Schneider
|
||||
//
|
||||
// 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/>.
|
||||
|
||||
namespace Yavsc.Models.Google
|
||||
{
|
||||
/// <summary>
|
||||
/// Calendar list.
|
||||
/// </summary>
|
||||
public class CalendarList {
|
||||
/// <summary>
|
||||
/// Gets or sets the kind.
|
||||
/// </summary>
|
||||
/// <value>The kind.</value>
|
||||
public string kind { get; set;}
|
||||
/// <summary>
|
||||
/// Gets or sets the etag.
|
||||
/// </summary>
|
||||
/// <value>The etag.</value>
|
||||
public string etag { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the next sync token.
|
||||
/// </summary>
|
||||
/// <value>The next sync token.</value>
|
||||
public string nextSyncToken { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the items.
|
||||
/// </summary>
|
||||
/// <value>The items.</value>
|
||||
public CalendarListEntry[] items { get; set; }
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
121
Yavsc/src/Model/Google/Calendar/CalendarListEntry.cs
Normal file
121
Yavsc/src/Model/Google/Calendar/CalendarListEntry.cs
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
//
|
||||
// CalendarListEntry.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2014 Paul Schneider
|
||||
//
|
||||
// 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/>.
|
||||
|
||||
namespace Yavsc.Models.Google
|
||||
{
|
||||
/// <summary>
|
||||
/// Calendar list entry.
|
||||
/// </summary>
|
||||
public class CalendarListEntry {
|
||||
/// <summary>
|
||||
/// Gets or sets the kind.
|
||||
/// </summary>
|
||||
/// <value>The kind.</value>
|
||||
public string kind { get; set;}
|
||||
/// <summary>
|
||||
/// Gets or sets the etag.
|
||||
/// </summary>
|
||||
/// <value>The etag.</value>
|
||||
public string etag { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the identifier.
|
||||
/// </summary>
|
||||
/// <value>The identifier.</value>
|
||||
public string id { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the summary.
|
||||
/// </summary>
|
||||
/// <value>The summary.</value>
|
||||
public string summary { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the description.
|
||||
/// </summary>
|
||||
/// <value>The description.</value>
|
||||
public string description { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the time zone.
|
||||
/// </summary>
|
||||
/// <value>The time zone.</value>
|
||||
public string timeZone { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the color identifier.
|
||||
/// </summary>
|
||||
/// <value>The color identifier.</value>
|
||||
public string colorId { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the background.
|
||||
/// </summary>
|
||||
/// <value>The color of the background.</value>
|
||||
public string backgroundColor { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the color of the foreground.
|
||||
/// </summary>
|
||||
/// <value>The color of the foreground.</value>
|
||||
public string foregroundColor { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="Yavsc.Model.Google.CalendarListEntry"/> is selected.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if selected; otherwise, <c>false</c>.</value>
|
||||
public bool selected { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="Yavsc.Model.Google.CalendarListEntry"/> is primary.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if primary; otherwise, <c>false</c>.</value>
|
||||
public bool primary { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the access role.
|
||||
/// </summary>
|
||||
/// <value>The access role.</value>
|
||||
public string accessRole { get; set; }
|
||||
/// <summary>
|
||||
/// Reminder.
|
||||
/// </summary>
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the default reminders.
|
||||
/// </summary>
|
||||
/// <value>The default reminders.</value>
|
||||
public Reminder[] defaultReminders { get; set; }
|
||||
/* "notificationSettings": { "notifications":
|
||||
[ { "type": "eventCreation", "method": "email" },
|
||||
{ "type": "eventChange", "method": "email" },
|
||||
{ "type": "eventCancellation", "method": "email" },
|
||||
{ "type": "eventResponse", "method": "email" } ] }, "primary": true },
|
||||
|
||||
*/
|
||||
}
|
||||
/// <summary>
|
||||
/// Reminder.
|
||||
/// </summary>
|
||||
public class Reminder {
|
||||
/// <summary>
|
||||
/// Gets or sets the method.
|
||||
/// </summary>
|
||||
/// <value>The method.</value>
|
||||
public string method { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the minutes.
|
||||
/// </summary>
|
||||
/// <value>The minutes.</value>
|
||||
public int minutes { get; set; }
|
||||
}
|
||||
|
||||
}
|
||||
43
Yavsc/src/Model/Google/GDate.cs
Normal file
43
Yavsc/src/Model/Google/GDate.cs
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
//
|
||||
// GDate.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// 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;
|
||||
|
||||
namespace Yavsc.Models.Google
|
||||
{
|
||||
/// <summary>
|
||||
/// G date.
|
||||
/// </summary>
|
||||
public class GDate {
|
||||
/// <summary>
|
||||
/// The date.
|
||||
/// </summary>
|
||||
public DateTime date;
|
||||
/// <summary>
|
||||
/// The datetime.
|
||||
/// </summary>
|
||||
public DateTime datetime;
|
||||
/// <summary>
|
||||
/// The time zone.
|
||||
/// </summary>
|
||||
public string timeZone;
|
||||
}
|
||||
|
||||
}
|
||||
64
Yavsc/src/Model/Google/Messaging/GCMRegisterModel.cs
Normal file
64
Yavsc/src/Model/Google/Messaging/GCMRegisterModel.cs
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
//
|
||||
// GCMRegisterModel.cs
|
||||
//
|
||||
// Author:
|
||||
// paul <>
|
||||
//
|
||||
// Copyright (c) 2015 paul
|
||||
//
|
||||
// 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.ComponentModel;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace Yavsc.Models.Google.Messaging
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// GCM register model.
|
||||
/// </summary>
|
||||
public class GCMRegisterModel {
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the user.
|
||||
/// </summary>
|
||||
/// <value>The name of the user.</value>
|
||||
[Localizable(true)]
|
||||
[Display(Name="UserName")]
|
||||
[Required(ErrorMessage = "S'il vous plait, entrez un nom d'utilisateur")]
|
||||
public string UserName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the password.
|
||||
/// </summary>
|
||||
/// <value>The password.</value>
|
||||
[DisplayName("Mot de passe")]
|
||||
[Required(ErrorMessage = "S'il vous plait, entez un mot de passe")]
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the email.
|
||||
/// </summary>
|
||||
/// <value>The email.</value>
|
||||
[DisplayName("Adresse e-mail")]
|
||||
[Required(ErrorMessage = "S'il vous plait, entrez un e-mail valide")]
|
||||
public string Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the registration identifier against Google Clood Messaging and their info on this application.
|
||||
/// </summary>
|
||||
/// <value>The registration identifier.</value>
|
||||
public string RegistrationId { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
78
Yavsc/src/Model/Google/Messaging/MessageWithPayLoad.cs
Normal file
78
Yavsc/src/Model/Google/Messaging/MessageWithPayLoad.cs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// MessageWithPayLoad.cs
|
||||
//
|
||||
// Author:
|
||||
// paul <>
|
||||
//
|
||||
// Copyright (c) 2015 paul
|
||||
//
|
||||
// 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 Yavsc.Models.Messaging;
|
||||
|
||||
namespace Yavsc.Models.Google.Messaging
|
||||
{
|
||||
// https://gcm-http.googleapis.com/gcm/send
|
||||
/// <summary>
|
||||
/// Message with payload.
|
||||
/// </summary>
|
||||
public class MessageWithPayload<T> {
|
||||
/// <summary>
|
||||
/// To.
|
||||
/// </summary>
|
||||
public string to;
|
||||
/// <summary>
|
||||
/// The registration identifiers.
|
||||
/// </summary>
|
||||
public string [] registration_ids;
|
||||
/// <summary>
|
||||
/// The data.
|
||||
/// </summary>
|
||||
public T data ;
|
||||
/// <summary>
|
||||
/// The notification.
|
||||
/// </summary>
|
||||
public Notification notification;
|
||||
/// <summary>
|
||||
/// The collapse key.
|
||||
/// </summary>
|
||||
public string collapse_key; // in order to collapse ...
|
||||
/// <summary>
|
||||
/// The priority.
|
||||
/// </summary>
|
||||
public int priority; // between 0 and 10, 10 is the lowest!
|
||||
/// <summary>
|
||||
/// The content available.
|
||||
/// </summary>
|
||||
public bool content_available;
|
||||
/// <summary>
|
||||
/// The delay while idle.
|
||||
/// </summary>
|
||||
public bool delay_while_idle;
|
||||
/// <summary>
|
||||
/// The time to live.
|
||||
/// </summary>
|
||||
public int time_to_live; // seconds
|
||||
/// <summary>
|
||||
/// The name of the restricted package.
|
||||
/// </summary>
|
||||
public string restricted_package_name;
|
||||
/// <summary>
|
||||
/// The dry run.
|
||||
/// </summary>
|
||||
public bool dry_run;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
//
|
||||
// MessageWithPayloadResponse.cs
|
||||
//
|
||||
// Author:
|
||||
// paul <paul@pschneider.fr>
|
||||
//
|
||||
// Copyright (c) 2015 paul
|
||||
//
|
||||
// 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/>.
|
||||
|
||||
namespace Yavsc.Models.Google.Messaging
|
||||
{
|
||||
// https://gcm-http.googleapis.com/gcm/send
|
||||
|
||||
/// <summary>
|
||||
/// Message with payload response.
|
||||
/// </summary>
|
||||
public class MessageWithPayloadResponse {
|
||||
/// <summary>
|
||||
/// The multicast identifier.
|
||||
/// </summary>
|
||||
public string multicast_id;
|
||||
/// <summary>
|
||||
/// The success count.
|
||||
/// </summary>
|
||||
public int success;
|
||||
/// <summary>
|
||||
/// The failure count.
|
||||
/// </summary>
|
||||
public int failure;
|
||||
/// <summary>
|
||||
/// The canonical identifiers... ?!?
|
||||
/// </summary>
|
||||
public string canonical_ids;
|
||||
/// <summary>
|
||||
/// Detailled result.
|
||||
/// </summary>
|
||||
public class Result {
|
||||
/// <summary>
|
||||
/// The message identifier.
|
||||
/// </summary>
|
||||
public string message_id;
|
||||
/// <summary>
|
||||
/// The registration identifier.
|
||||
/// </summary>
|
||||
public string registration_id;
|
||||
/// <summary>
|
||||
/// The error.
|
||||
/// </summary>
|
||||
public string error;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The results.
|
||||
/// </summary>
|
||||
public Result [] results;
|
||||
}
|
||||
}
|
||||
165
Yavsc/src/Model/Google/People/People.cs
Normal file
165
Yavsc/src/Model/Google/People/People.cs
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
//
|
||||
// People.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2014 Paul Schneider
|
||||
//
|
||||
// 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/>.
|
||||
|
||||
|
||||
namespace Yavsc.Models.Google
|
||||
{
|
||||
/// <summary>
|
||||
/// People.
|
||||
/// </summary>
|
||||
public class People {
|
||||
/// <summary>
|
||||
/// Gets or sets the kind.
|
||||
/// </summary>
|
||||
/// <value>The kind.</value>
|
||||
public string kind { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the etag.
|
||||
/// </summary>
|
||||
/// <value>The etag.</value>
|
||||
public string etag { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the gender.
|
||||
/// </summary>
|
||||
/// <value>The gender.</value>
|
||||
public string gender { get; set; }
|
||||
/// <summary>
|
||||
/// E mail.
|
||||
/// </summary>
|
||||
public class EMail{
|
||||
/// <summary>
|
||||
/// Gets or sets the value.
|
||||
/// </summary>
|
||||
/// <value>The value.</value>
|
||||
public string value { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the type.
|
||||
/// </summary>
|
||||
/// <value>The type.</value>
|
||||
public string type { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the emails.
|
||||
/// </summary>
|
||||
/// <value>The emails.</value>
|
||||
public EMail[] emails { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the type of the object.
|
||||
/// </summary>
|
||||
/// <value>The type of the object.</value>
|
||||
public string objectType { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the identifier.
|
||||
/// </summary>
|
||||
/// <value>The identifier.</value>
|
||||
public string id { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the display name.
|
||||
/// </summary>
|
||||
/// <value>The display name.</value>
|
||||
public string displayName { get; set; }
|
||||
/// <summary>
|
||||
/// Name.
|
||||
/// </summary>
|
||||
public class Name {
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the family.
|
||||
/// </summary>
|
||||
/// <value>The name of the family.</value>
|
||||
public string familyName { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the given.
|
||||
/// </summary>
|
||||
/// <value>The name of the given.</value>
|
||||
public string givenName { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public Name name { get; set;}
|
||||
/// <summary>
|
||||
/// Gets or sets the URL.
|
||||
/// </summary>
|
||||
/// <value>The URL.</value>
|
||||
public string url { get; set; }
|
||||
/// <summary>
|
||||
/// Image.
|
||||
/// </summary>
|
||||
public class Image {
|
||||
/// <summary>
|
||||
/// Gets or sets the URL.
|
||||
/// </summary>
|
||||
/// <value>The URL.</value>
|
||||
public string url { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="Yavsc.Model.Google.People.Image"/> is default.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if is default; otherwise, <c>false</c>.</value>
|
||||
public bool isDefault { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the image.
|
||||
/// </summary>
|
||||
/// <value>The image.</value>
|
||||
public Image image { get; set; }
|
||||
/// <summary>
|
||||
/// Place.
|
||||
/// </summary>
|
||||
public class Place {
|
||||
/// <summary>
|
||||
/// Gets or sets the value.
|
||||
/// </summary>
|
||||
/// <value>The value.</value>
|
||||
public string value { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="Yavsc.Model.Google.People.Place"/> is primary.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if primary; otherwise, <c>false</c>.</value>
|
||||
public bool primary { get; set; }
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets or sets the places lived.
|
||||
/// </summary>
|
||||
/// <value>The places lived.</value>
|
||||
public Place[] placesLived { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="Yavsc.Model.Google.People"/> is plus user.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if is plus user; otherwise, <c>false</c>.</value>
|
||||
public bool isPlusUser { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the language.
|
||||
/// </summary>
|
||||
/// <value>The language.</value>
|
||||
public string language { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets the circled by count.
|
||||
/// </summary>
|
||||
/// <value>The circled by count.</value>
|
||||
public int circledByCount { get; set; }
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether this <see cref="Yavsc.Model.Google.People"/> is verified.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if verified; otherwise, <c>false</c>.</value>
|
||||
public bool verified { get; set; }
|
||||
}
|
||||
}
|
||||
36
Yavsc/src/Model/Google/Resource.cs
Normal file
36
Yavsc/src/Model/Google/Resource.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
//
|
||||
// Resource.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// 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/>.
|
||||
|
||||
namespace Yavsc.Models.Google
|
||||
{
|
||||
/// <summary>
|
||||
/// Resource.
|
||||
/// </summary>
|
||||
public class Resource {
|
||||
public string id;
|
||||
public string location;
|
||||
public string status;
|
||||
public GDate start;
|
||||
public GDate end;
|
||||
public string recurence;
|
||||
}
|
||||
|
||||
}
|
||||
47
Yavsc/src/Model/Google/Tracks/Entity.cs
Normal file
47
Yavsc/src/Model/Google/Tracks/Entity.cs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// Entity.cs
|
||||
//
|
||||
// Author:
|
||||
// Paul Schneider <paulschneider@free.fr>
|
||||
//
|
||||
// Copyright (c) 2015 Paul Schneider
|
||||
//
|
||||
// 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/>.
|
||||
|
||||
namespace Yavsc.Models.Google
|
||||
{
|
||||
/// <summary>
|
||||
/// Entity.
|
||||
/// </summary>
|
||||
public class Entity
|
||||
{
|
||||
/// <summary>
|
||||
/// The I.
|
||||
/// </summary>
|
||||
public string ID;
|
||||
/// <summary>
|
||||
/// The name.
|
||||
/// </summary>
|
||||
public string Name;
|
||||
|
||||
/// <summary>
|
||||
/// The type: AUTOMOBILE: A car or passenger vehicle.
|
||||
/// * TRUCK: A truck or cargo vehicle.
|
||||
/// * WATERCRAFT: A boat or other waterborne vehicle.
|
||||
/// * PERSON: A person.
|
||||
/// </summary>
|
||||
public string Type;
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue