// Post handles POST request, and records audit log or refreshes cache based on event. func (n *NotificationHandler) Post() { var notification models.Notification err := json.Unmarshal(n.Ctx.Input.CopyBody(1<<32), ¬ification) if err != nil { log.Errorf("failed to decode notification: %v", err) return } events, err := filterEvents(¬ification) if err != nil { log.Errorf("failed to filter events: %v", err) return } for _, event := range events { repository := event.Target.Repository project, _ := utils.ParseRepository(repository) tag := event.Target.Tag action := event.Action user := event.Actor.Name if len(user) == 0 { user = "******" } go func() { if err := dao.AccessLog(user, project, repository, tag, action); err != nil { log.Errorf("failed to add access log: %v", err) } }() if action == "push" { go func() { exist := dao.RepositoryExists(repository) if exist { return } log.Debugf("Add repository %s into DB.", repository) repoRecord := models.RepoRecord{Name: repository, OwnerName: user, ProjectName: project} if err := dao.AddRepository(repoRecord); err != nil { log.Errorf("Error happens when adding repository: %v", err) } if err := cache.RefreshCatalogCache(); err != nil { log.Errorf("failed to refresh cache: %v", err) } }() go api.TriggerReplicationByRepository(repository, []string{tag}, models.RepOpTransfer) } if action == "pull" { go func() { log.Debugf("Increase the repository %s pull count.", repository) if err := dao.IncreasePullCount(repository); err != nil { log.Errorf("Error happens when increasing pull count: %v", repository) } }() } } }
// Delete ... func (ra *RepositoryAPI) Delete() { repoName := ra.GetString("repo_name") if len(repoName) == 0 { ra.CustomAbort(http.StatusBadRequest, "repo_name is nil") } projectName, _ := utils.ParseRepository(repoName) project, err := dao.GetProjectByName(projectName) if err != nil { log.Errorf("failed to get project %s: %v", projectName, err) ra.CustomAbort(http.StatusInternalServerError, "") } if project == nil { ra.CustomAbort(http.StatusNotFound, fmt.Sprintf("project %s not found", projectName)) } if project.Public == 0 { userID := ra.ValidateUser() if !hasProjectAdminRole(userID, project.ProjectID) { ra.CustomAbort(http.StatusForbidden, "") } } rc, err := ra.initRepositoryClient(repoName) if err != nil { log.Errorf("error occurred while initializing repository client for %s: %v", repoName, err) ra.CustomAbort(http.StatusInternalServerError, "internal error") } tags := []string{} tag := ra.GetString("tag") if len(tag) == 0 { tagList, err := rc.ListTag() if err != nil { if regErr, ok := err.(*registry_error.Error); ok { ra.CustomAbort(regErr.StatusCode, regErr.Detail) } log.Errorf("error occurred while listing tags of %s: %v", repoName, err) ra.CustomAbort(http.StatusInternalServerError, "internal error") } // TODO remove the logic if the bug of registry is fixed if len(tagList) == 0 { ra.CustomAbort(http.StatusNotFound, http.StatusText(http.StatusNotFound)) } tags = append(tags, tagList...) } else { tags = append(tags, tag) } user, _, ok := ra.Ctx.Request.BasicAuth() if !ok { user, err = ra.getUsername() if err != nil { log.Errorf("failed to get user: %v", err) } } for _, t := range tags { if err := rc.DeleteTag(t); err != nil { if regErr, ok := err.(*registry_error.Error); ok { if regErr.StatusCode != http.StatusNotFound { ra.CustomAbort(regErr.StatusCode, regErr.Detail) } } else { log.Errorf("error occurred while deleting tag %s:%s: %v", repoName, t, err) ra.CustomAbort(http.StatusInternalServerError, "internal error") } } log.Infof("delete tag: %s:%s", repoName, t) go TriggerReplicationByRepository(repoName, []string{t}, models.RepOpDelete) go func(tag string) { if err := dao.AccessLog(user, projectName, repoName, tag, "delete"); err != nil { log.Errorf("failed to add access log: %v", err) } }(t) } exist, err := repositoryExist(repoName, rc) if err != nil { log.Errorf("failed to check the existence of repository %s: %v", repoName, err) ra.CustomAbort(http.StatusInternalServerError, "") } if !exist { if err = dao.DeleteRepository(repoName); err != nil { log.Errorf("failed to delete repository %s: %v", repoName, err) ra.CustomAbort(http.StatusInternalServerError, "") } } go func() { log.Debug("refreshing catalog cache") if err := cache.RefreshCatalogCache(); err != nil { log.Errorf("error occurred while refresh catalog cache: %v", err) } }() }