public override void OnAuthorization(AuthorizationContext filterContext) { base.OnAuthorization(filterContext); var repository = filterContext.Controller.ControllerContext.RouteData.Values["id"].ToString(); var user = filterContext.HttpContext.User.Identity.Name; if (RequiresRepositoryAdministrator) { if (!RepositoryPermissionService.IsRepositoryAdministrator(user, repository)) { filterContext.Result = new HttpUnauthorizedResult(); } } else { if (!RepositoryPermissionService.HasPermission(user, repository)) { if (!RepositoryPermissionService.AllowsAnonymous(repository)) { filterContext.Result = new HttpUnauthorizedResult(); } } } }
public ActionResult GitLfsBasicTransferUpload(string repositoryName, string oid) { bool authorized = RepositoryPermissionService.HasPermission(User.Id(), RepositoryRepository.GetRepository(repositoryName).Id, RepositoryAccessLevel.Pull); if (!authorized) { Response.StatusCode = 403; return(Content( Newtonsoft.Json.JsonConvert.SerializeObject(new BatchApiErrorResponse() { Message = "You do not have permission to PUSH (LFS upload)." }) , GitLfsConsts.GIT_LFS_CONTENT_TYPE)); } // If the object already exists, the client does not send it. But even if it does, we will still not replace it. if (!StorageProvider.Exists(repositoryName, oid)) { using (Stream destStream = StorageProvider.GetWriteStream(LfsOperationNames.UPLOAD, repositoryName, oid)) { Request.InputStream.CopyTo(destStream); destStream.Flush(); destStream.Close(); } } Response.StatusCode = 200; return(null); }
public ActionResult SecureGetInfoRefs(String repositoryName, String service) { bool isPush = String.Equals("git-receive-pack", service, StringComparison.OrdinalIgnoreCase); if (!RepositoryIsValid(repositoryName)) { // This isn't a real repo - but we might consider allowing creation if (isPush && UserConfiguration.Current.AllowPushToCreate) { if (!RepositoryPermissionService.HasCreatePermission(User.Id())) { return(UnauthorizedResult()); } if (!TryCreateOnPush(repositoryName)) { return(UnauthorizedResult()); } } else { return(new HttpNotFoundResult()); } } var requiredLevel = isPush ? RepositoryAccessLevel.Push : RepositoryAccessLevel.Pull; if (RepositoryPermissionService.HasPermission(User.Id(), repositoryName, requiredLevel)) { return(GetInfoRefs(repositoryName, service)); } else { return(UnauthorizedResult()); } }
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, GitRequirement requirement) { if (context == null) { throw new ArgumentNullException(nameof(context)); } HttpContext httpContext = _httpContextAccessor.HttpContext; string incomingRepoName = GetRepoPath(httpContext.Request.Path, httpContext.Request.PathBase); string repoName = Repository.NormalizeRepositoryName(incomingRepoName, RepositoryRepository); // Add header to prevent redirection to login page even if we fail auth later (see IAuthenticationProvider.Configure) // If we don't fail auth later, then this is benign httpContext.Request.Headers.Add("AuthNoRedirect", "1"); if (context.User != null && context.User.Identity.IsAuthenticated && context.User.Identity is ClaimsIdentity) { // We already have a claims id, we don't need to worry about the rest of these checks Log.Verbose("GitAuth: User {username} already has identity", httpContext.User.DisplayName()); context.Succeed(requirement); return(Task.FromResult(0)); } string authHeader = httpContext.Request.Headers["Authorization"]; if (String.IsNullOrEmpty(authHeader)) { // We don't have an auth header, but if we're doing an anonymous operation, that's OK if (RepositoryPermissionService.HasPermission(Guid.Empty, repoName, RepositoryAccessLevel.Pull)) { // Allow this through. If it turns out they're actually trying to do an anon push and that's not allowed for this repo // then the GitController will reject them in there Log.Information("GitAuth: No auth header, anon operation may be allowed"); context.Succeed(requirement); return(Task.FromResult(0)); } else { // If we're not even allowed to do an anonymous pull, then we should bounce this now, // and tell the other end to try again with an auth header included next time httpContext.Response.Headers.Add("WWW-Authenticate", "Basic realm=\"Bonobo Git\""); context.Fail(); Log.Warning("GitAuth: No auth header, anon operations not allowed"); return(Task.FromResult(0)); } } // Process the auth header and see if we've been given valid credentials if (!IsUserAuthorized(authHeader, httpContext)) { context.Fail(); } return(Task.FromResult(0)); }
public ActionResult SecureReceivePack(String project) { if (RepositoryPermissionService.HasPermission(User.Id(), project) || (RepositoryPermissionService.AllowsAnonymous(project) && UserConfiguration.Current.AllowAnonymousPush)) { return(ExecuteReceivePack(project)); } else { return(UnauthorizedResult()); } }
public ActionResult SecureUploadPack(String project) { if (RepositoryPermissionService.HasPermission(User.Id(), project) || RepositoryPermissionService.AllowsAnonymous(project)) { return(ExecuteUploadPack(project)); } else { return(UnauthorizedResult()); } }
public ActionResult SecureGetInfoRefs(String project, String service) { if (RepositoryPermissionService.HasPermission(User.Id(), project) || (RepositoryPermissionService.AllowsAnonymous(project) && (String.Equals("git-upload-pack", service, StringComparison.OrdinalIgnoreCase) || UserConfiguration.Current.AllowAnonymousPush))) { return(GetInfoRefs(project, service)); } else { return(UnauthorizedResult()); } }
public override void OnAuthorization(System.Web.Mvc.AuthorizationContext filterContext) { if (filterContext == null) { throw new ArgumentNullException("filterContext"); } HttpContextBase httpContext = filterContext.HttpContext; string incomingRepoName = GetRepoPath(httpContext.Request.Path, httpContext.Request.ApplicationPath); string repoName = Repository.NormalizeRepositoryName(incomingRepoName, RepositoryRepository); // Add header to prevent redirection to login page even if we fail auth later (see IAuthenticationProvider.Configure) // If we don't fail auth later, then this is benign httpContext.Request.Headers.Add("AuthNoRedirect", "1"); if (httpContext.Request.IsAuthenticated && httpContext.User != null && httpContext.User.Identity is System.Security.Claims.ClaimsIdentity) { // We already have a claims id, we don't need to worry about the rest of these checks return; } string authHeader = httpContext.Request.Headers["Authorization"]; if (String.IsNullOrEmpty(authHeader)) { // We don't have an auth header, but if we're doing an anonymous operation, that's OK if (RepositoryPermissionService.HasPermission(Guid.Empty, repoName, RepositoryAccessLevel.Pull)) { // Allow this through. If it turns out they're actually trying to do an anon push and that's not allowed for this repo // then the GitController will reject them in there return; } else { // If we're not even allowed to do an anonymous pull, then we should bounce this now, // and tell the other end to try again with an auth header included next time httpContext.Response.Headers.Add("WWW-Authenticate", "Basic realm=\"Bonobo Git\""); filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Unauthorized); return; } } // Process the auth header and see if we've been given valid credentials if (!IsUserAuthorized(authHeader, httpContext)) { filterContext.Result = new HttpStatusCodeResult(HttpStatusCode.Unauthorized); } }
public ActionResult SecureUploadPack(String repositoryName) { if (!RepositoryIsValid(repositoryName)) { return(new HttpNotFoundResult()); } if (RepositoryPermissionService.HasPermission(User.Id(), repositoryName, RepositoryAccessLevel.Pull)) { return(ExecuteUploadPack(repositoryName)); } else { return(UnauthorizedResult()); } }
public ActionResult SecureReceivePack(String repositoryName) { if (!RepositoryIsValid(repositoryName)) { return(new HttpNotFoundResult()); } if (RepositoryPermissionService.HasPermission(User.Id(), repositoryName) || (RepositoryPermissionService.AllowsAnonymous(repositoryName) && UserConfiguration.Current.AllowAnonymousPush)) { return(ExecuteReceivePack(repositoryName)); } else { return(UnauthorizedResult()); } }
public ActionResult Detail(Guid id) { ViewBag.ID = id; var model = ConvertRepositoryModel(RepositoryRepository.GetRepository(id)); if (model != null) { model.IsCurrentUserAdministrator = RepositoryPermissionService.HasPermission(User.Id(), model.Id, RepositoryAccessLevel.Administer); SetGitUrls(model); } using (var browser = new RepositoryBrowser(Path.Combine(UserConfiguration.Current.Repositories, model.Name))) { string defaultReferenceName; browser.BrowseTree(null, null, out defaultReferenceName); RouteData.Values.Add("encodedName", defaultReferenceName); } return(View(model)); }
public ActionResult GitLfsBasicTransferDownload(string repositoryName, string oid) { bool authorized = RepositoryPermissionService.HasPermission(User.Id(), RepositoryRepository.GetRepository(repositoryName).Id, RepositoryAccessLevel.Pull); if (!authorized) { Response.StatusCode = 403; return(Content( Newtonsoft.Json.JsonConvert.SerializeObject(new BatchApiErrorResponse() { Message = "You do not have permission to PULL (LFS download)." }) , GitLfsConsts.GIT_LFS_CONTENT_TYPE)); } Stream readStream = StorageProvider.GetReadStream(LfsOperationNames.DOWNLOAD, repositoryName, oid); return(File(readStream, "application/octet-stream")); }
public override void OnAuthorization(AuthorizationContext filterContext) { base.OnAuthorization(filterContext); var repository = filterContext.Controller.ControllerContext.RouteData.Values["id"].ToString(); var user = filterContext.HttpContext.User.Identity.Name; if (RequiresRepositoryAdministrator) { if (RepositoryPermissionService.IsRepositoryAdministrator(user, repository)) { return; } } else { if (RepositoryPermissionService.HasPermission(user, repository)) { return; } if (RepositoryPermissionService.AllowsAnonymous(repository)) { return; } } if (filterContext.HttpContext.User == null || !(filterContext.HttpContext.User.Identity is FormsIdentity) || !filterContext.HttpContext.User.Identity.IsAuthenticated) { filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary { { "controller", "Home" }, { "action", "LogOn" }, { "returnUrl", filterContext.HttpContext.Request.Url.PathAndQuery } }); } else { filterContext.Result = new RedirectResult("~/Home/Unauthorized"); } }
public ActionResult SecureGetInfoRefs(String repositoryName, String service) { if (!RepositoryIsValid(repositoryName)) { return(new HttpNotFoundResult()); } bool isPush = String.Equals("git-receive-pack", service, StringComparison.OrdinalIgnoreCase); var requiredLevel = isPush ? RepositoryAccessLevel.Push : RepositoryAccessLevel.Pull; if (RepositoryPermissionService.HasPermission(User.Id(), repositoryName, requiredLevel)) { return(GetInfoRefs(repositoryName, service)); } else { return(UnauthorizedResult()); } }
public override void OnAuthorization(AuthorizationContext filterContext) { base.OnAuthorization(filterContext); if (!(filterContext.Result is HttpUnauthorizedResult)) { Guid repoId = Guid.Parse(filterContext.Controller.ControllerContext.RouteData.Values["id"].ToString()); Guid userId = filterContext.HttpContext.User.Id(); var requiredAccess = RequiresRepositoryAdministrator ? RepositoryAccessLevel.Administer : RepositoryAccessLevel.Push; if (RepositoryPermissionService.HasPermission(userId, repoId, requiredAccess)) { return; } filterContext.Result = new RedirectResult("~/Home/Unauthorized"); } }
private ActionResult SecureGetInfoRefs(String repositoryName, String service) { bool isPush = String.Equals("git-receive-pack", service, StringComparison.OrdinalIgnoreCase); if (!RepositoryIsValid(repositoryName)) { // This isn't a real repo - but we might consider allowing creation if (isPush && UserConfiguration.Current.AllowPushToCreate) { if (!RepositoryPermissionService.HasCreatePermission(User.Id())) { Log.Warning("GitC: User {UserId} is not allowed to do push-to-create", User.Id()); return(UnauthorizedResult()); } if (!TryCreateOnPush(repositoryName)) { return(UnauthorizedResult()); } } else { return(new HttpNotFoundResult()); } } var requiredLevel = isPush ? RepositoryAccessLevel.Push : RepositoryAccessLevel.Pull; if (RepositoryPermissionService.HasPermission(User.Id(), repositoryName, requiredLevel)) { return(GetInfoRefs(repositoryName, service)); } else { Log.Warning("GitC: SecureGetInfoRefs unauth because User {UserId} doesn't have permission {Permission} on repo {RepositoryName}", User.Id(), requiredLevel, repositoryName); return(UnauthorizedResult()); } }
public override void OnAuthorization(AuthorizationContext filterContext) { 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)) { Guid userId = filterContext.HttpContext.User.Id(); var requiredAccess = RequiresRepositoryAdministrator ? RepositoryAccessLevel.Administer : RepositoryAccessLevel.Push; if (RepositoryPermissionService.HasPermission(userId, repoId, requiredAccess)) { return; } filterContext.Result = new RedirectResult(urlhelper.Action("Unauthorized", "Home")); } else { var rd = filterContext.RequestContext.RouteData; var action = rd.GetRequiredString("action"); var controller = rd.GetRequiredString("controller"); if (action.Equals("index", StringComparison.OrdinalIgnoreCase) && controller.Equals("repository", StringComparison.OrdinalIgnoreCase)) { filterContext.Result = new RedirectResult(urlhelper.Action("Unauthorized", "Home")); } else { filterContext.Controller.TempData["RepositoryNotFound"] = true; filterContext.Result = new RedirectResult(urlhelper.Action("Index", "Repository")); } } } }
public ActionResult SecureGetInfoRefs(String repositoryName, String service) { if (!RepositoryIsValid(repositoryName)) { return(new HttpNotFoundResult()); } bool allowAnonClone = RepositoryPermissionService.AllowsAnonymous(repositoryName); bool hasPermission = RepositoryPermissionService.HasPermission(User.Id(), repositoryName); bool isClone = String.Equals("git-upload-pack", service, StringComparison.OrdinalIgnoreCase); bool isPush = String.Equals("git-receive-pack", service, StringComparison.OrdinalIgnoreCase); bool allowAnonPush = UserConfiguration.Current.AllowAnonymousPush; if (hasPermission || (allowAnonClone && isClone) || (allowAnonPush && isPush)) { return(GetInfoRefs(repositoryName, service)); } else { return(UnauthorizedResult()); } }
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, WebRequirement requirement) { Guid repoId; var urlhelper = new UrlHelper(_actionContextAccessor.ActionContext); if (Guid.TryParse(_actionContextAccessor.ActionContext.RouteData.Values["id"].ToString(), out repoId)) { Guid userId = context.User.Id(); var requiredAccess = RequiresRepositoryAdministrator ? RepositoryAccessLevel.Administer : RepositoryAccessLevel.Push; if (RepositoryPermissionService.HasPermission(userId, repoId, requiredAccess)) { context.Succeed(requirement); return(Task.FromResult(0)); } //filterContext.Result = new RedirectResult(urlhelper.Action("Unauthorized", "Home")); } else { var rd = _actionContextAccessor.ActionContext.RouteData; rd.Values.TryGetValue("action", out var action); rd.Values.TryGetValue("controller", out var controller); if (((string)action).Equals("index", StringComparison.OrdinalIgnoreCase) && ((string)controller).Equals("repository", StringComparison.OrdinalIgnoreCase)) { //filterContext.Result = new RedirectResult(urlhelper.Action("Unauthorized", "Home")); } else { //filterContext.Controller.TempData["RepositoryNotFound"] = true; //filterContext.Result = new RedirectResult(urlhelper.Action("Index", "Repository")); } } return(Task.FromResult(0)); }
public override void OnAuthorization(AuthorizationContext filterContext) { base.OnAuthorization(filterContext); if (!(filterContext.Result is HttpUnauthorizedResult)) { string repository = filterContext.Controller.ControllerContext.RouteData.Values["id"].ToString(); string user = filterContext.HttpContext.User.Id(); if (filterContext.HttpContext.User.IsInRole(Definitions.Roles.Administrator)) { return; } if (RequiresRepositoryAdministrator) { if (RepositoryPermissionService.IsRepositoryAdministrator(user, repository)) { return; } } else { if (RepositoryPermissionService.HasPermission(user, repository)) { return; } if (RepositoryPermissionService.AllowsAnonymous(repository)) { return; } } filterContext.Result = new RedirectResult("~/Home/Unauthorized"); } }
public ActionResult Detail(Guid id) { var mater = ConvertRepositoryModel(RepositoryRepository.GetRepository(id), User); if (mater != null) { mater.IsCurrentUserAdministrator = RepositoryPermissionService.HasPermission(User.Id(), mater.Id, RepositoryAccessLevel.Administer); SetGitUrls(mater); } ViewBag.ID = id; ViewBag.Name = mater.Name; ViewBag.GitUrl = mater.GitUrl; //using (var browser = new RepositoryBrowser(Path.Combine(UserConfiguration.Current.Repositories, model.Name))) //{ // string defaultReferenceName; // browser.BrowseTree(null, null, out defaultReferenceName); // RouteData.Values.Add("encodedName", defaultReferenceName); //} bool includeDetails = Request.IsAjaxRequest(); var name = PathEncoder.Decode(null); var path = PathEncoder.Decode(null); var repo = RepositoryRepository.GetRepository(id); var repositoryDetailModel = ConvertRepositoryModel(repo, User); using (var browser = new RepositoryBrowser(Path.Combine(UserConfiguration.Current.Repositories, repo.Name))) { string referenceName; var files = browser.BrowseTree(name, path, out referenceName, includeDetails).ToList(); PopulateBranchesData(browser, referenceName); var readme = files.FirstOrDefault(x => x.Name.Equals("readme.md", StringComparison.OrdinalIgnoreCase)); string readmeTxt = string.Empty; if (readme != null) { string refereceName; var blob = browser.BrowseBlob(name, readme.Path, out refereceName); readmeTxt = blob.Text; } var model = new RepositoryTreeModel { Name = repo.Name, Branch = name ?? referenceName, Path = path, Readme = readmeTxt, Logo = new RepositoryLogoDetailModel(repo.Logo), Files = files.OrderByDescending(i => i.IsTree).ThenBy(i => i.Name) }; if (includeDetails) { return(Json(model, JsonRequestBehavior.AllowGet)); } else { PopulateBranchesData(browser, referenceName); PopulateAddressBarData(path); return(View(model)); } } }
public GitLfsResult GetBatchApiResponse(string urlScheme, string urlAuthority, string requestApplicationPath, string repositoryName, string[] acceptTypes, BatchApiRequest requestObj, Guid userId) { // Validate the request. if (!acceptTypes .Select(at => at.Split(new[] { ';' })) .SelectMany(list => list) .Any(at => at.Equals("application/vnd.git-lfs+json"))) { return(GitLfsResult.From( Newtonsoft.Json.JsonConvert.SerializeObject( new BatchApiErrorResponse() { Message = "Invalid ContentType." }), 406, GitLfsConsts.GIT_LFS_CONTENT_TYPE)); } // Check permissions RepositoryAccessLevel accessLevelRequested; if (requestObj.Operation.Equals(LfsOperationNames.DOWNLOAD)) { accessLevelRequested = RepositoryAccessLevel.Pull; } else if (requestObj.Operation.Equals(LfsOperationNames.UPLOAD)) { accessLevelRequested = RepositoryAccessLevel.Push; } else { accessLevelRequested = RepositoryAccessLevel.Administer; } bool authorized = RepositoryPermissionService.HasPermission(userId, RepositoryRepository.GetRepository(repositoryName).Id, accessLevelRequested); if (!authorized) { return(GitLfsResult.From( Newtonsoft.Json.JsonConvert.SerializeObject( new BatchApiErrorResponse() { Message = "You do not have the required permissions." }), 403, GitLfsConsts.GIT_LFS_CONTENT_TYPE)); } if (requestObj == null) { return(GitLfsResult.From( Newtonsoft.Json.JsonConvert.SerializeObject( new BatchApiErrorResponse() { Message = "Cannot parse request body." }), 400, GitLfsConsts.GIT_LFS_CONTENT_TYPE)); } // Process the request. var requestedTransferAdapters = requestObj.Transfers ?? (new string[] { LfsTransferProviderNames.BASIC }); string firstSupportedTransferAdapter = requestedTransferAdapters.FirstOrDefault(t => t.Equals(LfsTransferProviderNames.BASIC)); if (firstSupportedTransferAdapter != null) { string transferAdapterToUse = firstSupportedTransferAdapter; var requiredSpace = DetermineRequiredDiskSpace(requestObj); if (StorageProvider.SufficientSpace(requiredSpace)) { BatchApiResponse responseObj = new BatchApiResponse() { Transfer = transferAdapterToUse, Objects = requestObj.Objects .Select(ro => new { ro, ActionFactory = new LfsActionFactory() }) .Select(x => new BatchApiResponse.BatchApiObject() { Oid = x.ro.Oid, Size = x.ro.Size, Authenticated = true, Actions = x.ActionFactory.CreateBatchApiObjectActions(urlScheme, urlAuthority, requestApplicationPath, requestObj.Operation, x.ro, repositoryName, StorageProvider) }) .ToArray() }; return(GitLfsResult.From(responseObj, 200, GitLfsConsts.GIT_LFS_CONTENT_TYPE)); } else { return(GitLfsResult.From(new BatchApiErrorResponse() { Message = "Insufficient storage space." }, 507, GitLfsConsts.GIT_LFS_CONTENT_TYPE)); } } else { // None of the requested transfer adapters are supported. return(GitLfsResult.From(new BatchApiErrorResponse() { Message = $"None of the requested transfer adapters are supported." }, 400, GitLfsConsts.GIT_LFS_CONTENT_TYPE)); } }
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)) { if (urlhelper == null) { urlhelper = GetUrlHelper(filterContext); } if (repoId == Guid.Empty) { repoId = GetRepoId(filterContext); } if (repoId != Guid.Empty) { Guid userId = filterContext.HttpContext.User.Id(); var requiredAccess = RequiresRepositoryAdministrator ? RepositoryAccessLevel.Administer : RepositoryAccessLevel.Push; if (RepositoryPermissionService.HasPermission(userId, repoId, requiredAccess)) { return; } filterContext.Result = new RedirectResult(urlhelper.Action("Unauthorized", "Home")); } else { var rd = filterContext.RequestContext.RouteData; var action = rd.GetRequiredString("action"); var controller = rd.GetRequiredString("controller"); if (action.Equals("index", StringComparison.OrdinalIgnoreCase) && controller.Equals("repository", StringComparison.OrdinalIgnoreCase)) { filterContext.Result = new RedirectResult(urlhelper.Action("Unauthorized", "Home")); } else { filterContext.Controller.TempData["RepositoryNotFound"] = true; filterContext.Result = new RedirectResult(urlhelper.Action("Index", "Repository")); } } } }