Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 14 additions & 4 deletions BuildRevisionCounter/BuildRevisionCounter.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,21 @@
<Reference Include="Microsoft.Owin.Host.SystemWeb">
<HintPath>..\packages\Microsoft.Owin.Host.SystemWeb.3.0.0\lib\net45\Microsoft.Owin.Host.SystemWeb.dll</HintPath>
</Reference>
<Reference Include="MongoDB.Bson">
<HintPath>..\packages\mongocsharpdriver.1.10.0\lib\net35\MongoDB.Bson.dll</HintPath>
<Reference Include="MongoDB.Bson, Version=2.0.0.828, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MongoDB.Bson.2.0.0\lib\net45\MongoDB.Bson.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="MongoDB.Driver">
<HintPath>..\packages\mongocsharpdriver.1.10.0\lib\net35\MongoDB.Driver.dll</HintPath>
<Reference Include="MongoDB.Driver, Version=2.0.0.828, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MongoDB.Driver.2.0.0\lib\net45\MongoDB.Driver.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="MongoDB.Driver.Core, Version=2.0.0.828, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MongoDB.Driver.Core.2.0.0\lib\net45\MongoDB.Driver.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="MongoDB.Driver.Legacy, Version=2.0.0.828, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\mongocsharpdriver.2.0.0\lib\net45\MongoDB.Driver.Legacy.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.6.0.4\lib\net45\Newtonsoft.Json.dll</HintPath>
Expand Down
35 changes: 17 additions & 18 deletions BuildRevisionCounter/Controllers/CounterController.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
using BuildRevisionCounter.Model;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using System;
using System.Net;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using BuildRevisionCounter.Security;

Expand All @@ -18,16 +16,16 @@ public class CounterController : ApiController

static CounterController()
{
_storage = new MongoDBStorage();
_storage = MongoDBStorage.Instance;
}

[HttpGet]
[Route("{revisionName}")]
[Authorize(Roles = "admin, editor, anonymous")]
public long Current([FromUri] string revisionName)
public async Task<long> Current([FromUri] string revisionName)
{
var q = Query<RevisionModel>.Where(_ => _.Id == revisionName);
var revision = _storage.Revisions.FindOne(q);
var q = Builders<RevisionModel>.Filter.Eq(_ => _.Id, revisionName);
var revision = await _storage.Revisions.Find(q).FirstOrDefaultAsync();

if (revision == null)
throw new HttpResponseException(HttpStatusCode.NotFound);
Expand All @@ -38,20 +36,21 @@ public long Current([FromUri] string revisionName)
[HttpPost]
[Route("{revisionName}")]
[Authorize(Roles = "buildserver")]
public long Bumping([FromUri] string revisionName)
public async Task<long> Bumping([FromUri] string revisionName)
{
var result = _storage.Revisions.FindAndModify(new FindAndModifyArgs()
var options = new FindOneAndUpdateOptions<RevisionModel>
{
Query = Query<RevisionModel>.Where(_ => _.Id == revisionName),
Upsert = true,
Update = Update<RevisionModel>
.SetOnInsert(_ => _.Created, DateTime.UtcNow)
.Inc(_ => _.NextNumber, 1)
.Set(_ => _.Updated, DateTime.UtcNow),
VersionReturned = FindAndModifyDocumentVersion.Modified
});

var revision = result.GetModifiedDocumentAs<RevisionModel>();
IsUpsert = true,
ReturnDocument = ReturnDocument.After
};

var revision = await _storage.Revisions.FindOneAndUpdateAsync(
Builders<RevisionModel>.Filter.Eq(r => r.Id, revisionName),
Builders<RevisionModel>.Update
.SetOnInsert(l => l.Created, DateTime.UtcNow)
.Inc(l => l.NextNumber, 1)
.Set(l => l.Updated, DateTime.UtcNow),
options);

return revision.NextNumber;
}
Expand Down
48 changes: 40 additions & 8 deletions BuildRevisionCounter/MongoDBStorage.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,57 @@ namespace BuildRevisionCounter
{
public class MongoDBStorage
{
public readonly MongoCollection<RevisionModel> Revisions;
public readonly MongoCollection<UserModel> Users;
private static readonly Object SLock = new Object();
private static MongoDBStorage _instance = null;

public MongoDBStorage()
private readonly IMongoClient _client;
private readonly IMongoDatabase _database;

private MongoDBStorage()
{
string connectionString = ConfigurationManager.ConnectionStrings["MongoDBStorage"].ConnectionString;
var database = MongoDatabase.Create(connectionString);
var url = new MongoUrl(connectionString);

Revisions = database.GetCollection<RevisionModel>("revisions");
Users = database.GetCollection<UserModel>("users");
_client = new MongoClient(url);
_database = _client.GetDatabase(url.DatabaseName);

CreateAdmin();
}

public static MongoDBStorage Instance
{
get
{
if (_instance == null)
{
lock (SLock)
{
if (_instance == null)
_instance = new MongoDBStorage();
}
}
return _instance;
}
}

public IMongoCollection<RevisionModel> Revisions
{
get { return _database.GetCollection<RevisionModel>("revisions"); }
}

public IMongoCollection<UserModel> Users
{
get { return _database.GetCollection<UserModel>("users"); }
}

private void CreateAdmin()
{
if (!Users.AsQueryable().Any())
var anyUser = Users.Find(l => true).SingleOrDefaultAsync();
anyUser.Wait();

if (anyUser.Result == null)
{
Users.Insert(new UserModel
Users.InsertOneAsync(new UserModel
{
Name = "admin",
Password = "admin",
Expand Down
17 changes: 9 additions & 8 deletions BuildRevisionCounter/Security/BasicAuthenticationAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http.Filters;
using BuildRevisionCounter.Model;
using BuildRevisionCounter.Model;
using MongoDB.Driver;
using MongoDB.Driver.Builders;

namespace BuildRevisionCounter.Security
Expand All @@ -25,9 +26,9 @@ public class BasicAuthenticationAttribute : Attribute, IAuthenticationFilter

private static readonly MongoDBStorage _storage;

static BasicAuthenticationAttribute()
{
_storage = new MongoDBStorage();
static BasicAuthenticationAttribute()
{
_storage = MongoDBStorage.Instance;
}

public bool AllowMultiple { get { return false; } }
Expand All @@ -54,18 +55,18 @@ public Task AuthenticateAsync(HttpAuthenticationContext context, CancellationTok
return Task.FromResult(0);
}

context.Principal = Authenticate(user, password);
context.Principal = Authenticate(user, password).Result;

if (context.Principal == null)
context.ErrorResult = new AuthenticationFailureResult("Invalid username or password", request);

return Task.FromResult(0);
}

private IPrincipal Authenticate(string userName, string password)
private async Task<IPrincipal> Authenticate(string userName, string password)
{
IPrincipal principal = null;
var user = _storage.Users.FindOne(Query<UserModel>.Where(u => u.Name == userName));
IPrincipal principal = null;
var user = await _storage.Users.Find(l => l.Name == userName).SingleOrDefaultAsync();
if (user != null && user.Password == password)
{
principal = new GenericPrincipal(new GenericIdentity(userName), user.Roles);
Expand Down
2 changes: 1 addition & 1 deletion BuildRevisionCounter/Web.config
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="MongoDBStorage" connectionString="mongodb://localhost/brCounter"/>
<add name="MongoDBStorage" connectionString="mongodb://localhost/brCounter" />
</connectionStrings>
<system.web>
<compilation debug="true" targetFramework="4.5.1" />
Expand Down
5 changes: 4 additions & 1 deletion BuildRevisionCounter/packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
<package id="Microsoft.AspNet.WebApi.Owin" version="5.2.2" targetFramework="net451" />
<package id="Microsoft.Owin" version="3.0.0" targetFramework="net451" />
<package id="Microsoft.Owin.Host.SystemWeb" version="3.0.0" targetFramework="net451" />
<package id="mongocsharpdriver" version="1.10.0" targetFramework="net451" />
<package id="mongocsharpdriver" version="2.0.0" targetFramework="net451" />
<package id="MongoDB.Bson" version="2.0.0" targetFramework="net451" />
<package id="MongoDB.Driver" version="2.0.0" targetFramework="net451" />
<package id="MongoDB.Driver.Core" version="2.0.0" targetFramework="net451" />
<package id="Newtonsoft.Json" version="6.0.4" targetFramework="net451" />
<package id="Owin" version="1.0" targetFramework="net451" />
</packages>