예제 #1
0
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)
}
예제 #2
0
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)
	}
}
예제 #3
0
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)
}
예제 #4
0
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)
}
예제 #5
0
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)
}
예제 #6
0
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)
}
예제 #7
0
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)
}
예제 #8
0
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)
}