Skip to content

Commit

Permalink
Merge pull request #710 from jeffgaroutte/anonymousRepo77
Browse files Browse the repository at this point in the history
Browsing / acessing public/anonymous repositories w/o credentials
  • Loading branch information
willdean committed Aug 14, 2017
2 parents d1d6fa8 + dda8531 commit a4b2966
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,14 @@ public void SetCheckbox(IWebElement field, bool select)
if (select != field.Selected)
{
field.Click();
/* Because selenium tests & drivers can be flakey I added a second test
* with a different way of checking -or clearing- a checkbox.
* This fixed local failures. (win10/IE11)
*/
if (select != field.Selected)
{
field.SendKeys(" ");
}
}
}

Expand Down
23 changes: 12 additions & 11 deletions Bonobo.Git.Server.Test/IntegrationTests/MiscTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,30 @@ public void EnsureCookiePersistBetweenBrowserRestart()
app.Browser.Manage().Cookies.DeleteAllCookies();
Thread.Sleep(TimeSpan.FromSeconds(5)); // give it some time to delete the cookies

app.NavigateTo<RepositoryController>(c => c.Index(null, null));
app.UrlShouldMapTo<HomeController>(c => c.LogOn("/Repository/Index"));
app.NavigateTo<AccountController>(c => c.Detail(new Guid("7479fc09-2c0b-4e93-a2cf-5e4bbf6bab4f")));
app.UrlShouldMapTo<HomeController>(c => c.LogOn("/Account/Detail/7479fc09-2c0b-4e93-a2cf-5e4bbf6bab4f"));

var form = app.FindFormFor<LogOnModel>();
var chkField = form.Field(f => f.Username).SetValueTo("admin")
.Field(f=> f.Password).SetValueTo("admin")
.Field(f => f.Password).SetValueTo("admin")
.Field(f => f.RememberMe).Field;
ITH.SetCheckbox(chkField, true);
form.Submit();
app.UrlShouldMapTo<RepositoryController>(c => c.Index(null, null));

app.UrlShouldMapTo<AccountController>(c => c.Detail(new Guid("7479fc09-2c0b-4e93-a2cf-5e4bbf6bab4f")));
MvcWebApp.Driver.Shutdown();
app = new MvcWebApp();

app.NavigateTo<RepositoryController>(c => c.Index(null, null));
app.UrlShouldMapTo<RepositoryController>(c => c.Index(null, null));
ITH = new IntegrationTestHelpers(app, lc);
app.NavigateTo<AccountController>(c => c.Detail(new Guid("7479fc09-2c0b-4e93-a2cf-5e4bbf6bab4f")));
app.UrlShouldMapTo<AccountController>(c => c.Detail(new Guid("7479fc09-2c0b-4e93-a2cf-5e4bbf6bab4f")));
// ok we re logged in with success.

// Now let's make sure we can unset remember me
app.NavigateTo<HomeController>(c => c.LogOff());
app.NavigateTo<HomeController>(c => c.LogOn(""));
form = app.FindFormFor<LogOnModel>();
chkField = form.Field(f => f.Username).SetValueTo("admin")
.Field(f=> f.Password).SetValueTo("admin")
.Field(f => f.Password).SetValueTo("admin")
.Field(f => f.RememberMe).Field;
ITH.SetCheckbox(chkField, false);
form.Submit();
Expand All @@ -53,8 +54,8 @@ public void EnsureCookiePersistBetweenBrowserRestart()
app = new MvcWebApp();
ITH = new IntegrationTestHelpers(app, lc);

app.NavigateTo<RepositoryController>(c => c.Index(null, null));
app.UrlShouldMapTo<HomeController>(c => c.LogOn("/Repository/Index"));
app.NavigateTo<AccountController>(c => c.Detail(new Guid("7479fc09-2c0b-4e93-a2cf-5e4bbf6bab4f")));
app.UrlShouldMapTo<HomeController>(c => c.LogOn("/Account/Detail/7479fc09-2c0b-4e93-a2cf-5e4bbf6bab4f"));
}
}
}
50 changes: 47 additions & 3 deletions Bonobo.Git.Server/Attributes/WebAuthorizeRepositoryAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,42 @@ public class WebAuthorizeRepositoryAttribute : WebAuthorizeAttribute

public bool RequiresRepositoryAdministrator { get; set; }

public bool AllowAnonymousAccessWhenRepositoryAllowsIt { get; set; }

public override void OnAuthorization(AuthorizationContext filterContext)
{
Guid repoId = Guid.Empty;
UrlHelper urlhelper = null;

// is this set to allow anon users?
if (AllowAnonymousAccessWhenRepositoryAllowsIt)
{
urlhelper = GetUrlHelper(filterContext);
repoId = GetRepoId(filterContext);
//if the user is authenciated or the repo id isnt there let the normal auth code handle it.
if (repoId != Guid.Empty && !filterContext.HttpContext.User.Identity.IsAuthenticated)
{
//we are only allowing read access here. The web ui doesnt do pushes
if (RepositoryPermissionService.HasPermission(Guid.Empty, repoId, RepositoryAccessLevel.Pull))
{
return;
}
}
}
//do base role checks
base.OnAuthorization(filterContext);

if (!(filterContext.Result is HttpUnauthorizedResult))
{
Guid repoId;
var urlhelper = new UrlHelper(filterContext.RequestContext);
if (Guid.TryParse(filterContext.Controller.ControllerContext.RouteData.Values["id"].ToString(), out repoId))
if (urlhelper == null)
{
urlhelper = GetUrlHelper(filterContext);
}
if (repoId == Guid.Empty)
{
repoId = GetRepoId(filterContext);
}
if (repoId != Guid.Empty)
{
Guid userId = filterContext.HttpContext.User.Id();

Expand Down Expand Up @@ -55,5 +82,22 @@ public override void OnAuthorization(AuthorizationContext filterContext)
}
}
}
private static Guid GetRepoId(AuthorizationContext filterContext)
{
Guid result;
if (Guid.TryParse(filterContext.Controller.ControllerContext.RouteData.Values["id"].ToString(), out result))
{
return result;
}
else
{
return Guid.Empty;
}
}

private static UrlHelper GetUrlHelper(AuthorizationContext filterContext)
{
return new UrlHelper(filterContext.RequestContext);
}
}
}
1 change: 0 additions & 1 deletion Bonobo.Git.Server/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public class HomeController : Controller
[Dependency]
public IDatabaseResetManager ResetManager { get; set; }

[WebAuthorize]
public ActionResult Index()
{
return RedirectToAction("Index", "Repository");
Expand Down
32 changes: 17 additions & 15 deletions Bonobo.Git.Server/Controllers/RepositoryController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,28 +36,31 @@ public class RepositoryController : Controller
[Dependency]
public IAuthenticationProvider AuthenticationProvider { get; set; }

[WebAuthorize]
public ActionResult Index(string sortGroup = null, string searchString = null)
{
var firstList = this.GetIndexModel();
var unorderedRepositoryDetails = this.GetIndexModel();
if (!User.Identity.IsAuthenticated && !unorderedRepositoryDetails.Any())
{
return RedirectToAction("Logon", "Home", new { returnUrl="/Home/Index" });
}
if (!string.IsNullOrEmpty(searchString))
{
var search = searchString.ToLower();
firstList = firstList.Where(a => a.Name.ToLower().Contains(search) ||
unorderedRepositoryDetails = unorderedRepositoryDetails.Where(a => a.Name.ToLower().Contains(search) ||
(!string.IsNullOrEmpty(a.Group) && a.Group.ToLower().Contains(search)) ||
(!string.IsNullOrEmpty(a.Description) && a.Description.ToLower().Contains(search)))
.AsEnumerable();
}

foreach(var item in firstList){
foreach(var item in unorderedRepositoryDetails){
SetGitUrls(item);
}
var list = firstList
var orderedReposityDetails = unorderedRepositoryDetails
.GroupBy(x => x.Group)
.OrderBy(x => x.Key, string.IsNullOrEmpty(sortGroup) || sortGroup.Equals("ASC"))
.ToDictionary(x => x.Key ?? string.Empty, x => x.ToArray());

return View(list);
return View(orderedReposityDetails);
}

[WebAuthorizeRepository(RequiresRepositoryAdministrator = true)]
Expand Down Expand Up @@ -207,7 +210,7 @@ public ActionResult Delete(RepositoryDetailModel model)
return RedirectToAction("Index");
}

[WebAuthorizeRepository]
[WebAuthorizeRepository(AllowAnonymousAccessWhenRepositoryAllowsIt = true)]
public ActionResult Detail(Guid id)
{
ViewBag.ID = id;
Expand Down Expand Up @@ -250,7 +253,7 @@ void SetGitUrls(RepositoryDetailModel model)
}
}

[WebAuthorizeRepository]
[WebAuthorizeRepository(AllowAnonymousAccessWhenRepositoryAllowsIt = true)]
public ActionResult Tree(Guid id, string encodedName, string encodedPath)
{
bool includeDetails = Request.IsAjaxRequest();
Expand Down Expand Up @@ -297,7 +300,7 @@ public ActionResult Tree(Guid id, string encodedName, string encodedPath)
}
}

[WebAuthorizeRepository]
[WebAuthorizeRepository(AllowAnonymousAccessWhenRepositoryAllowsIt = true)]
public ActionResult Blob(Guid id, string encodedName, string encodedPath)
{
ViewBag.ID = id;
Expand Down Expand Up @@ -367,7 +370,7 @@ public ActionResult Blame(Guid id, string encodedName, string encodedPath)
}
}

[WebAuthorizeRepository]
[WebAuthorizeRepository(AllowAnonymousAccessWhenRepositoryAllowsIt = true)]
public ActionResult Download(Guid id, string encodedName, string encodedPath)
{
var name = PathEncoder.Decode(encodedName);
Expand Down Expand Up @@ -423,7 +426,7 @@ private static void AddTreeToZip(RepositoryBrowser browser, string name, string
}
}

[WebAuthorizeRepository]
[WebAuthorizeRepository(AllowAnonymousAccessWhenRepositoryAllowsIt = true)]
public ActionResult Tags(Guid id, string encodedName, int page = 1)
{
page = page >= 1 ? page : 1;
Expand All @@ -447,7 +450,7 @@ public ActionResult Tags(Guid id, string encodedName, int page = 1)
}
}

[WebAuthorizeRepository]
[WebAuthorizeRepository(AllowAnonymousAccessWhenRepositoryAllowsIt = true)]
public ActionResult Commits(Guid id, string encodedName, int? page = null)
{
page = page >= 1 ? page : 1;
Expand Down Expand Up @@ -508,7 +511,7 @@ public ActionResult Commits(Guid id, string encodedName, int? page = null)
}
}

[WebAuthorizeRepository]
[WebAuthorizeRepository(AllowAnonymousAccessWhenRepositoryAllowsIt = true)]
public ActionResult Commit(Guid id, string commit)
{
ViewBag.ID = id;
Expand All @@ -523,7 +526,7 @@ public ActionResult Commit(Guid id, string commit)
}
}

[WebAuthorize]
[WebAuthorizeRepository]
public ActionResult Clone(Guid id)
{
if (!RepositoryPermissionService.HasCreatePermission(User.Id()))
Expand All @@ -539,7 +542,6 @@ public ActionResult Clone(Guid id)
}

[HttpPost]
[WebAuthorize]
[WebAuthorizeRepository]
[ValidateAntiForgeryToken]
public ActionResult Clone(Guid id, RepositoryDetailModel model)
Expand Down
10 changes: 5 additions & 5 deletions Bonobo.Git.Server/Views/Repository/Index.cshtml
Original file line number Diff line number Diff line change
Expand Up @@ -151,9 +151,9 @@
if(repo.AllowAnonymousPush != RepositoryPushMode.Global){
pushSetting = repo.AllowAnonymousPush == RepositoryPushMode.Yes;
}

var pushIcon = repo.AllowAnonymousPush == RepositoryPushMode.Global ? "fa-globe" : "fa-sign-in";
var pushTitle = Resources.Repository_Detail_AllowAnonymousPush + ": " + (pushSetting ? Resources.Yes : Resources.No);
var pushTitle = Resources.Repository_Detail_AllowAnonymousPush + ": " + (pushSetting ? Resources.Yes : Resources.No);
var pushColor = pushSetting ? "rgba(0, 120, 230, 1)" : "lightblue";
var ret = Html.Raw("<span class='fa-fw'>").ToHtmlString();
ret += Html.Raw("<div class='fa fa-sign-out' style='display: block; color: " + anonColor + "' title='" + anonTitle + "'></div>").ToHtmlString();
Expand All @@ -166,9 +166,9 @@

columns.Add(permitted.Column("Description", typeof(RepositoryDetailModel).GetDisplayValue("Description"), format: (item) => ((item.Description != null && ((string)item.Description).Length > 100)) ? ((string)item.Description).Substring(0, 100) + " ... " : item.Description, style: "description"));
columns.Add(permitted.Column(format: (item) => Html.Raw("<button class=\"pure-button pure-button-primary copy-to-clip-button\" title=\"" + Resources.Repository_Git_Url_Copy + "\" data-clipboard-text=\"" + Html.Encode(item.GitUrl) + "\"><i class=\"fa fa-copy\" ></i></button>"), style: "action"));
columns.Add(permitted.Column(format: (item) => Html.Raw("<button class=\"pure-button pure-button-primary copy-to-clip-button\" title=\"" + Resources.Repository_Personal_Git_Url_Copy + "\" data-clipboard-text=\"" + Html.Encode(item.PersonalGitUrl) + "\"><i class=\"fa fa-user\"></i><i class=\"fa fa-copy\"></i></button>"), style: "action"));
columns.Add(permitted.Column(format: (item) => Html.ActionLink(" ", "Edit", new { id = item.Id }, new { @class = "edit", title = Resources.Grid_Edit }), style: "action"));
columns.Add(permitted.Column(format: (item) => Html.ActionLink(" ", "Delete", new { id = item.Id }, new { @class = "delete", title = Resources.Grid_Delete }), style: "action"));
columns.Add(permitted.Column(format: (item) => Html.Raw(String.IsNullOrWhiteSpace(item.PersonalGitUrl) ? "&nbsp" :"<button class=\"pure-button pure-button-primary copy-to-clip-button\" title=\"" + Resources.Repository_Personal_Git_Url_Copy + "\" data-clipboard-text=\"" + Html.Encode(item.PersonalGitUrl) + "\"><i class=\"fa fa-user\"></i><i class=\"fa fa-copy\"></i></button>"), style: "action"));
columns.Add(permitted.Column(format: (item) => ((RepositoryDetailModel)item.Value).IsCurrentUserAdministrator ? Html.ActionLink(" ", "Edit", new { id = item.Id }, new { @class = "edit", title = Resources.Grid_Edit }) : Html.Raw("&nbsp;"), style: "action"));
columns.Add(permitted.Column(format: (item) => ((RepositoryDetailModel)item.Value).IsCurrentUserAdministrator ? Html.ActionLink(" ", "Delete", new { id = item.Id }, new { @class = "delete", title = Resources.Grid_Delete }) : Html.Raw("&nbsp;"), style: "action"));

permitted.Columns(columns.ToArray());
@permitted.GetHtml(
Expand Down

0 comments on commit a4b2966

Please sign in to comment.