func (s *ProjectService) update(req *restful.Request, resp *restful.Response, p *project.Project) { raw := &ProjectEntity{} if err := req.ReadEntity(raw); err != nil { logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusBadRequest, services.WrongEntityErr) return } user := filters.GetUser(req) if p.Owner != user.Id { resp.WriteServiceError(http.StatusForbidden, services.AuthForbidErr) return } mgr := s.Manager() defer mgr.Close() if raw.Name != "" { p.Name = raw.Name } if err := mgr.Projects.Update(p); err != nil { if mgr.IsDup(err) { resp.WriteServiceError( http.StatusConflict, services.NewError(services.CodeDuplicate, "project with this name and owner is existed")) return } logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusInternalServerError, services.DbErr) return } resp.WriteEntity(p) }
func (s *ProjectService) TakeProject(fn ProjectFunction) restful.RouteFunction { return func(req *restful.Request, resp *restful.Response) { // TODO (m0sth8): check permissions for the user id := req.PathParameter(ParamId) if !s.IsId(id) { resp.WriteServiceError(http.StatusBadRequest, services.IdHexErr) return } mgr := s.Manager() defer mgr.Close() p, err := mgr.Projects.GetById(mgr.ToId(id)) mgr.Close() if err != nil { if mgr.IsNotFound(err) { resp.WriteErrorString(http.StatusNotFound, "Not found") return } logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusInternalServerError, services.DbErr) return } u := filters.GetUser(req) admin := false if !admin && p.Owner != u.Id && p.GetMember(u.Id) == nil { resp.WriteServiceError(http.StatusForbidden, services.AuthForbidErr) return } fn(req, resp, p) } }
func (s *ProjectService) list(req *restful.Request, resp *restful.Response) { // TODO (m0sth8): check permissions query, err := fltr.FromRequest(req, manager.ProjectFltr{}) if err != nil { resp.WriteServiceError(http.StatusBadRequest, services.NewBadReq(err.Error())) return } u := filters.GetUser(req) admin := false // if user is not admin then show him only his projects or where he has membership if !admin { query = manager.Or(fltr.GetQuery(&manager.ProjectFltr{Owner: u.Id, Member: u.Id})) } mgr := s.Manager() defer mgr.Close() results, count, err := mgr.Projects.FilterByQuery(query) if err != nil { logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusInternalServerError, services.DbErr) return } result := &project.ProjectList{ Meta: pagination.Meta{Count: count}, Results: results, } resp.WriteEntity(result) }
func (s *MeService) info(req *restful.Request, resp *restful.Response) { mgr := s.Manager() defer mgr.Close() u := filters.GetUser(req) query := manager.Or(fltr.GetQuery(&manager.ProjectFltr{Owner: u.Id, Member: u.Id})) projects, count, err := mgr.Projects.FilterByQuery(query) if err != nil { logrus.Error(stackerr.Wrap(err)) } else { // TODO (m0sth8): create default project when user on create is triggered. // create one default project if count == 0 { p, err := mgr.Projects.CreateDefault(u.Id) if err != nil { logrus.Error(stackerr.Wrap(err)) // It might be possible, that default project is already created // So, client should repeat request resp.WriteServiceError(http.StatusInternalServerError, services.DbErr) return } else { projects = append(projects, p) } } } info := me.Info{ User: u, Projects: projects, } resp.WriteEntity(info) }
func (s *ProjectService) membersCreate(req *restful.Request, resp *restful.Response, p *project.Project) { raw := &project.Member{} if err := req.ReadEntity(raw); err != nil { logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusBadRequest, services.WrongEntityErr) return } if raw.User == "" { resp.WriteServiceError(http.StatusBadRequest, services.NewBadReq("user is required")) return } u := filters.GetUser(req) if p.Owner != u.Id { resp.WriteServiceError(http.StatusForbidden, services.AuthForbidErr) return } for _, member := range p.Members { if member.User == raw.User { resp.WriteServiceError(http.StatusConflict, services.NewError(services.CodeDuplicate, "User is already member")) return } } mgr := s.Manager() defer mgr.Close() mUser, err := mgr.Users.GetById(raw.User) if err != nil { if mgr.IsNotFound(err) { resp.WriteErrorString(http.StatusNotFound, "User not found") return } logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusInternalServerError, services.DbErr) return } member := &project.Member{User: mUser.Id} p.Members = append(p.Members, member) err = mgr.Projects.Update(p) if err != nil { if mgr.IsNotFound(err) { resp.WriteErrorString(http.StatusNotFound, "Not found") return } logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusInternalServerError, services.DbErr) return } resp.WriteHeader(http.StatusCreated) resp.WriteEntity(member) }
func (s *MeService) changePassword(req *restful.Request, resp *restful.Response) { // TODO (m0sth8): add captcha support raw := &ChangePasswordEntity{} if err := req.ReadEntity(raw); err != nil { logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusBadRequest, services.WrongEntityErr) return } u := filters.GetUser(req) // verify old password verified, err := s.PassCtx().Verify(raw.Old, u.Password) if err != nil { logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusInternalServerError, services.AppErr) return } if !verified { resp.WriteServiceError(http.StatusBadRequest, services.NewBadReq("old password is incorrect")) return } // TODO (m0sth8): validate new password (length, symbols etc); extract if len(raw.New) < 7 { resp.WriteServiceError(http.StatusBadRequest, services.NewBadReq("new password must be more than 6 symbols")) return } pass, err := s.PassCtx().Encrypt(raw.New) if err != nil { logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusInternalServerError, services.AppErr) return } u.Password = pass mgr := s.Manager() defer mgr.Close() err = mgr.Users.Update(u) if err != nil { logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusInternalServerError, services.DbErr) return } resp.WriteHeader(http.StatusOK) }
func (s *ProjectService) create(req *restful.Request, resp *restful.Response) { // TODO (m0sth8): Check permissions for the user, he is might be blocked or removed raw := &ProjectEntity{} if err := req.ReadEntity(raw); err != nil { logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusBadRequest, services.WrongEntityErr) return } user := filters.GetUser(req) mgr := s.Manager() defer mgr.Close() obj := &project.Project{ Name: raw.Name, Owner: user.Id, } obj, err := mgr.Projects.Create(obj) if err != nil { if mgr.IsDup(err) { resp.WriteServiceError( http.StatusConflict, services.NewError(services.CodeDuplicate, "project with this name and owner is existed")) return } logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusInternalServerError, services.DbErr) return } resp.WriteHeader(http.StatusCreated) resp.WriteEntity(obj) }
func (s *ScanService) create(req *restful.Request, resp *restful.Response) { // TODO (m0sth8): Check permissions raw := &scan.Scan{} if err := req.ReadEntity(raw); err != nil { logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusBadRequest, services.WrongEntityErr) return } u := filters.GetUser(req) mgr := s.Manager() defer mgr.Close() // TODO (m0sth8): check project and target permissions for this user // validations project, err := mgr.Projects.GetById(raw.Project) if err != nil { resp.WriteServiceError(http.StatusBadRequest, services.NewBadReq("project not found")) return } target, err := mgr.Targets.GetById(raw.Target) if err != nil { if mgr.IsNotFound(err) { resp.WriteServiceError(http.StatusBadRequest, services.NewBadReq("target not found")) return } logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusInternalServerError, services.DbErr) return } if target.Project != project.Id { resp.WriteServiceError(http.StatusBadRequest, services.NewBadReq("this target is not from this project")) return } planObj, err := mgr.Plans.GetById(raw.Plan) if err != nil { if mgr.IsNotFound(err) { resp.WriteServiceError(http.StatusBadRequest, services.NewBadReq("plan not found")) return } logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusInternalServerError, services.DbErr) return } if planObj.TargetType != target.Type { resp.WriteServiceError(http.StatusBadRequest, services.NewBadReq("target.type and plan.targetType is not compatible")) return } sc := &scan.Scan{ Status: scan.StatusCreated, Owner: u.Id, Plan: raw.Plan, Project: project.Id, Target: target.Id, Conf: scan.ScanConf{ Target: target.Addr(), }, Sessions: []*scan.Session{}, } now := time.Now().UTC() // Add session from plans workflow steps for _, step := range planObj.Workflow { plugin, err := mgr.Plugins.GetByName(step.Plugin) if err != nil { if mgr.IsNotFound(err) { resp.WriteServiceError(http.StatusBadRequest, services.NewBadReq(fmt.Sprintf("plugin %s is not found", step.Plugin))) return } logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusInternalServerError, services.DbErr) return } // TODO (m0sth8): extract template execution if step.Conf != nil { if command := step.Conf.CommandArgs; command != "" { t, err := template.New("").Parse(command) if err != nil { logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusInternalServerError, services.NewAppErr("Wrong command args template")) return } buf := bytes.NewBuffer(nil) err = t.Execute(buf, sc.Conf) if err != nil { logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusInternalServerError, services.NewAppErr("Wrong command args template")) return } step.Conf.CommandArgs = buf.String() } if formData := step.Conf.FormData; formData != "" { t, err := template.New("").Parse(formData) if err != nil { logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusInternalServerError, services.NewAppErr("Wrong form data template")) return } buf := bytes.NewBuffer(nil) err = t.Execute(buf, sc.Conf) if err != nil { logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusInternalServerError, services.NewAppErr("Wrong form data template")) return } step.Conf.FormData = buf.String() } if target := step.Conf.Target; target == "" { step.Conf.Target = sc.Conf.Target } } else { step.Conf = &plan.Conf{ Target: sc.Conf.Target, } } sess := scan.Session{ Id: mgr.NewId(), Step: step, Plugin: plugin.Id, Status: scan.StatusCreated, Dates: scan.Dates{ Created: &now, Updated: &now, }, } sc.Sessions = append(sc.Sessions, &sess) } obj, err := mgr.Scans.Create(sc) if err != nil { logrus.Error(stackerr.Wrap(err)) resp.WriteServiceError(http.StatusInternalServerError, services.DbErr) return } // put scan to queue s.Scheduler().AddScan(obj) if _, err := mgr.Feed.AddScan(obj); err != nil { logrus.Error(stackerr.Wrap(err)) } resp.WriteHeader(http.StatusCreated) resp.WriteEntity(obj) }