MCPcopy Create free account
hub / github.com/bytebase/bytebase / buildIssueMessage

Method buildIssueMessage

backend/api/v1/issue_service.go:434–577  ·  view source on GitHub ↗
(ctx context.Context, project *store.ProjectMessage, userEmail string, request *v1pb.CreateIssueRequest, labels []string)

Source from the content-addressed store, hash-verified

432}
433
434func (s *IssueService) buildIssueMessage(ctx context.Context, project *store.ProjectMessage, userEmail string, request *v1pb.CreateIssueRequest, labels []string) (*store.IssueMessage, error) {
435 var planUID *int64
436 var roleGrant *storepb.RoleGrant
437 var title, description string
438
439 // Type-specific validation and preparation
440 switch request.Issue.Type {
441 case v1pb.Issue_DATABASE_EXPORT:
442 return nil, connect.NewError(connect.CodeInvalidArgument, errors.Errorf("data export issue creation is no longer supported"))
443
444 case v1pb.Issue_ROLE_GRANT:
445 // Title is required for role grant requests.
446 if strings.TrimSpace(request.Issue.Title) == "" {
447 return nil, connect.NewError(connect.CodeInvalidArgument, errors.Errorf("issue title is required"))
448 }
449
450 // Check if role grant workflow feature is enabled.
451 if err := s.licenseService.IsFeatureEnabled(ctx, common.GetWorkspaceIDFromContext(ctx), v1pb.PlanFeature_FEATURE_REQUEST_ROLE_WORKFLOW); err != nil {
452 return nil, connect.NewError(connect.CodePermissionDenied,
453 errors.Errorf("role request requires approval workflow feature (available in Enterprise plan)"))
454 }
455
456 // Validate role grant fields.
457 if request.Issue.RoleGrant.GetRole() == "" {
458 return nil, connect.NewError(connect.CodeInvalidArgument, errors.Errorf("expect role grant role"))
459 }
460 if request.Issue.RoleGrant.GetUser() == "" {
461 return nil, connect.NewError(connect.CodeInvalidArgument, errors.Errorf("expect role grant user"))
462 }
463
464 // Validate CEL expression if it's not empty.
465 if expression := request.Issue.RoleGrant.GetCondition().GetExpression(); expression != "" {
466 e, err := cel.NewEnv(common.IAMPolicyConditionCELAttributes...)
467 if err != nil {
468 return nil, connect.NewError(connect.CodeInternal, errors.Wrapf(err, "failed to create cel environment"))
469 }
470 if _, issues := e.Compile(expression); issues != nil {
471 return nil, connect.NewError(connect.CodeInvalidArgument, errors.Errorf("found issues in role grant condition expression, issues: %v", issues.String()))
472 }
473 }
474
475 // Enforce the workspace maximum request expiration cap (project owner is
476 // exempt), mirroring SetIamPolicy. The role grant's condition carries the
477 // `request.time < timestamp(...)` clause that becomes the IAM binding, so
478 // validating it here also rejects a missing expiration when a cap is set.
479 if request.Issue.RoleGrant.GetRole() != fmt.Sprintf("roles/%s", store.ProjectOwnerRole) {
480 workspaceProfileSetting, err := s.store.GetWorkspaceProfileSetting(ctx, common.GetWorkspaceIDFromContext(ctx))
481 if err != nil {
482 return nil, connect.NewError(connect.CodeInternal, errors.New("failed to get workspace profile setting"))
483 }
484 if maximumRequestExpiration := workspaceProfileSetting.GetMaximumRequestExpiration(); maximumRequestExpiration != nil {
485 if err := validateExpirationInExpression(request.Issue.RoleGrant.GetCondition().GetExpression(), maximumRequestExpiration); err != nil {
486 return nil, connect.NewError(connect.CodeInvalidArgument, errors.Wrapf(err, "failed to validate role expiration"))
487 }
488 }
489 }
490
491 roleGrantUserEmail, err := common.GetUserEmail(request.Issue.RoleGrant.User)

Callers 1

CreateIssueMethod · 0.95

Calls 15

GetUserEmailFunction · 0.92
FormatUserEmailFunction · 0.92
GetProjectIDPlanIDFunction · 0.92
convertToAPIIssueTypeFunction · 0.85
ErrorfMethod · 0.80
IsFeatureEnabledMethod · 0.80
GetUserByEmailMethod · 0.80
GetRoleMethod · 0.65
GetUserMethod · 0.65

Tested by

no test coverage detected