jiahuimbzuai/CoQuIR huggingface dataset:
//  [go]
func (a *AuthenticatorOAuth2Introspection) Config(config json.RawMessage) (*AuthenticatorOAuth2IntrospectionConfiguration, *http.Client, error) {
	var c AuthenticatorOAuth2IntrospectionConfiguration
	if err := a.c.AuthenticatorConfig(a.GetID(), config, &c); err != nil {
		return nil, nil, NewErrAuthenticatorMisconfigured(a, err)
	}

	clientKey := fmt.Sprintf("%x", md5.Sum([]byte(config)))
	a.mu.RLock()
	client, ok := a.clientMap[clientKey]
	a.mu.RUnlock()

	if !ok {
		a.logger.Debug("Initializing http client")
		var rt http.RoundTripper
		if c.PreAuth != nil && c.PreAuth.Enabled {
			var ep url.Values

			if c.PreAuth.Audience != "" {
				ep = url.Values{"audience": {c.PreAuth.Audience}}
			}

			rt = (&clientcredentials.Config{
				ClientID:       c.PreAuth.ClientID,
				ClientSecret:   c.PreAuth.ClientSecret,
				Scopes:         c.PreAuth.Scope,
				EndpointParams: ep,
				TokenURL:       c.PreAuth.TokenURL,
			}).Client(context.Background()).Transport
		}

		if c.Retry == nil {
			c.Retry = &AuthenticatorOAuth2IntrospectionRetryConfiguration{Timeout: "500ms", MaxWait: "1s"}
		} else {
			if c.Retry.Timeout == "" {
				c.Retry.Timeout = "500ms"
			}
			if c.Retry.MaxWait == "" {
				c.Retry.MaxWait = "1s"
			}
		}
		duration, err := time.ParseDuration(c.Retry.Timeout)
		if err != nil {
			return nil, nil, err
		}
		timeout := time.Millisecond * duration

		maxWait, err := time.ParseDuration(c.Retry.MaxWait)
		if err != nil {
			return nil, nil, err
		}

		client = httpx.NewResilientClientLatencyToleranceConfigurable(rt, timeout, maxWait)
		a.mu.Lock()
		a.clientMap[clientKey] = client
		a.mu.Unlock()
	}

	if c.Cache.TTL != "" {
		cacheTTL, err := time.ParseDuration(c.Cache.TTL)
		if err != nil {
			return nil, nil, err
		}
		a.cacheTTL = &cacheTTL
	}

	if a.tokenCache == nil {
		a.logger.Debugf("Creating cache with max cost: %d", c.Cache.MaxCost)
		cache, _ := ristretto.NewCache(&ristretto.Config{
			// This will hold about 1000 unique mutation responses.
			NumCounters: 10000,
			// Allocate a max
			MaxCost: int64(c.Cache.MaxCost),
			// This is a best-practice value.
			BufferItems: 64,
		})

		a.tokenCache = cache
	}

	return &c, client, nil
}
//  [go]
func (AppModule) ConsensusVersion() uint64 { return 2 }
//  [go]
func (AppModule) ConsensusVersion() uint64 { return 1 }
//  [go]
func (a *AuthenticatorOAuth2Introspection) tokenToCache(config *AuthenticatorOAuth2IntrospectionConfiguration, i *AuthenticatorOAuth2IntrospectionResult, token string, ss fosite.ScopeStrategy) {
	if !config.Cache.Enabled {
		return
	}

	if ss == nil && len(config.Scopes) > 0 {
		return
	}

	if a.cacheTTL != nil {
		a.tokenCache.SetWithTTL(token, i, 1, *a.cacheTTL)
	} else {
		a.tokenCache.Set(token, i, 1)
	}
}
//  [go]
func (a *AuthenticatorOAuth2Introspection) tokenToCache(config *AuthenticatorOAuth2IntrospectionConfiguration, i *AuthenticatorOAuth2IntrospectionResult, token string) {
	if !config.Cache.Enabled {
		return
	}

	if a.cacheTTL != nil {
		a.tokenCache.SetWithTTL(token, i, 1, *a.cacheTTL)
	} else {
		a.tokenCache.Set(token, i, 1)
	}
}
//  [go]
func (set *IdmapSet) doUidshiftIntoContainer(dir string, testmode bool, how string) error {
	dir = strings.TrimRight(dir, "/")

	convert := func(path string, fi os.FileInfo, err error) (e error) {
		uid, gid, err := GetOwner(path)
		if err != nil {
			return err
		}
		var newuid, newgid int
		switch how {
		case "in":
			newuid, newgid = set.ShiftIntoNs(uid, gid)
		case "out":
			newuid, newgid = set.ShiftFromNs(uid, gid)
		}
		if testmode {
			fmt.Printf("I would shift %q to %d %d\n", path, newuid, newgid)
		} else {
			err = ShiftOwner(dir, path, int(newuid), int(newgid))
			if err != nil {
				return err
			}
		}
		return nil
	}

	if !PathExists(dir) {
		return fmt.Errorf("No such file or directory: %q", dir)
	}
	return filepath.Walk(dir, convert)
}
//  [go]
func (set *IdmapSet) doUidshiftIntoContainer(dir string, testmode bool, how string) error {
	convert := func(path string, fi os.FileInfo, err error) (e error) {
		uid, gid, err := GetOwner(path)
		if err != nil {
			return err
		}
		var newuid, newgid int
		switch how {
		case "in":
			newuid, newgid = set.ShiftIntoNs(uid, gid)
		case "out":
			newuid, newgid = set.ShiftFromNs(uid, gid)
		}
		if testmode {
			fmt.Printf("I would shift %q to %d %d\n", path, newuid, newgid)
		} else {
			err = os.Lchown(path, int(newuid), int(newgid))
			if err == nil {
				m := fi.Mode()
				if m&os.ModeSymlink == 0 {
					err = os.Chmod(path, m)
					if err != nil {
						fmt.Printf("Error resetting mode on %q, continuing\n", path)
					}
				}
			}
		}
		return nil
	}

	if !PathExists(dir) {
		return fmt.Errorf("No such file or directory: %q", dir)
	}
	return filepath.Walk(dir, convert)
}
//  [go]
func TestUpdateSavedSearch(t *testing.T) {
	ctx := context.Background()

	key := int32(1)
	users := database.NewMockUserStore()
	users.GetByCurrentAuthUserFunc.SetDefaultReturn(&types.User{SiteAdmin: true, ID: key}, nil)

	ss := database.NewMockSavedSearchStore()
	ss.UpdateFunc.SetDefaultHook(func(ctx context.Context, savedSearch *types.SavedSearch) (*types.SavedSearch, error) {
		return &types.SavedSearch{
			ID:          key,
			Description: savedSearch.Description,
			Query:       savedSearch.Query,
			Notify:      savedSearch.Notify,
			NotifySlack: savedSearch.NotifySlack,
			UserID:      savedSearch.UserID,
			OrgID:       savedSearch.OrgID,
		}, nil
	})
	ss.GetByIDFunc.SetDefaultReturn(&api.SavedQuerySpecAndConfig{
		Config: api.ConfigSavedQuery{
			UserID: &key,
		},
	}, nil)

	db := database.NewMockDB()
	db.UsersFunc.SetDefaultReturn(users)
	db.SavedSearchesFunc.SetDefaultReturn(ss)

	userID := MarshalUserID(key)
	savedSearches, err := (&schemaResolver{db: db}).UpdateSavedSearch(ctx, &struct {
		ID          graphql.ID
		Description string
		Query       string
		NotifyOwner bool
		NotifySlack bool
		OrgID       *graphql.ID
		UserID      *graphql.ID
	}{
		ID:          marshalSavedSearchID(key),
		Description: "updated query description",
		Query:       "test type:diff patternType:regexp",
		OrgID:       nil,
		UserID:      &userID,
	})
	if err != nil {
		t.Fatal(err)
	}

	want := &savedSearchResolver{db, types.SavedSearch{
		ID:          key,
		Description: "updated query description",
		Query:       "test type:diff patternType:regexp",
		OrgID:       nil,
		UserID:      &key,
	}}

	mockrequire.Called(t, ss.UpdateFunc)

	if !reflect.DeepEqual(savedSearches, want) {
		t.Errorf("got %v+, want %v+", savedSearches, want)
	}

	// Ensure update saved search errors when patternType is not provided in the query.
	_, err = (&schemaResolver{db: db}).UpdateSavedSearch(ctx, &struct {
		ID          graphql.ID
		Description string
		Query       string
		NotifyOwner bool
		NotifySlack bool
		OrgID       *graphql.ID
		UserID      *graphql.ID
	}{ID: marshalSavedSearchID(key), Description: "updated query description", Query: "test type:diff", NotifyOwner: true, NotifySlack: false, OrgID: nil, UserID: &userID})
	if err == nil {
		t.Error("Expected error for updateSavedSearch when query does not provide a patternType: field.")
	}
}
//  [go]
func TestUpdateSavedSearch(t *testing.T) {
	ctx := context.Background()

	key := int32(1)
	users := database.NewMockUserStore()
	users.GetByCurrentAuthUserFunc.SetDefaultReturn(&types.User{SiteAdmin: true, ID: key}, nil)

	ss := database.NewMockSavedSearchStore()
	ss.UpdateFunc.SetDefaultHook(func(ctx context.Context, savedSearch *types.SavedSearch) (*types.SavedSearch, error) {
		return &types.SavedSearch{
			ID:          key,
			Description: savedSearch.Description,
			Query:       savedSearch.Query,
			Notify:      savedSearch.Notify,
			NotifySlack: savedSearch.NotifySlack,
			UserID:      savedSearch.UserID,
			OrgID:       savedSearch.OrgID,
		}, nil
	})

	db := database.NewMockDB()
	db.UsersFunc.SetDefaultReturn(users)
	db.SavedSearchesFunc.SetDefaultReturn(ss)

	userID := MarshalUserID(key)
	savedSearches, err := (&schemaResolver{db: db}).UpdateSavedSearch(ctx, &struct {
		ID          graphql.ID
		Description string
		Query       string
		NotifyOwner bool
		NotifySlack bool
		OrgID       *graphql.ID
		UserID      *graphql.ID
	}{ID: marshalSavedSearchID(key), Description: "updated query description", Query: "test type:diff patternType:regexp", OrgID: nil, UserID: &userID})
	if err != nil {
		t.Fatal(err)
	}

	want := &savedSearchResolver{db, types.SavedSearch{
		ID:          key,
		Description: "updated query description",
		Query:       "test type:diff patternType:regexp",
		OrgID:       nil,
		UserID:      &key,
	}}

	mockrequire.Called(t, ss.UpdateFunc)

	if !reflect.DeepEqual(savedSearches, want) {
		t.Errorf("got %v+, want %v+", savedSearches, want)
	}

	// Ensure update saved search errors when patternType is not provided in the query.
	_, err = (&schemaResolver{db: db}).UpdateSavedSearch(ctx, &struct {
		ID          graphql.ID
		Description string
		Query       string
		NotifyOwner bool
		NotifySlack bool
		OrgID       *graphql.ID
		UserID      *graphql.ID
	}{ID: marshalSavedSearchID(key), Description: "updated query description", Query: "test type:diff", NotifyOwner: true, NotifySlack: false, OrgID: nil, UserID: &userID})
	if err == nil {
		t.Error("Expected error for updateSavedSearch when query does not provide a patternType: field.")
	}
}
//  [go]
func (f *ScmpFilter) addRuleWrapper(call ScmpSyscall, action ScmpAction, exact bool, length C.uint, cond C.scmp_cast_t) error {
	if length != 0 && cond == nil {
		return fmt.Errorf("null conditions list, but length is nonzero")
	}

	var retCode C.int
	if exact {
		retCode = C.seccomp_rule_add_exact_array(f.filterCtx, action.toNative(), C.int(call), length, cond)
	} else {
		retCode = C.seccomp_rule_add_array(f.filterCtx, action.toNative(), C.int(call), length, cond)
	}

	if syscall.Errno(-1*retCode) == syscall.EFAULT {
		return fmt.Errorf("unrecognized syscall")
	} else if syscall.Errno(-1*retCode) == syscall.EPERM {
		return fmt.Errorf("requested action matches default action of filter")
	} else if syscall.Errno(-1*retCode) == syscall.EINVAL {
		return fmt.Errorf("two checks on same syscall argument")
	} else if retCode != 0 {
		return syscall.Errno(-1 * retCode)
	}

	return nil
}
//  [go]
func (f *ScmpFilter) addRuleWrapper(call ScmpSyscall, action ScmpAction, exact bool, cond C.scmp_cast_t) error {
	var length C.uint
	if cond != nil {
		length = 1
	} else {
		length = 0
	}

	var retCode C.int
	if exact {
		retCode = C.seccomp_rule_add_exact_array(f.filterCtx, action.toNative(), C.int(call), length, cond)
	} else {
		retCode = C.seccomp_rule_add_array(f.filterCtx, action.toNative(), C.int(call), length, cond)
	}

	if syscall.Errno(-1*retCode) == syscall.EFAULT {
		return fmt.Errorf("unrecognized syscall")
	} else if syscall.Errno(-1*retCode) == syscall.EPERM {
		return fmt.Errorf("requested action matches default action of filter")
	} else if retCode != 0 {
		return syscall.Errno(-1 * retCode)
	}

	return nil
}
//  [go]
func (f *ScmpFilter) addRuleGeneric(call ScmpSyscall, action ScmpAction, exact bool, conds []ScmpCondition) error {
	f.lock.Lock()
	defer f.lock.Unlock()

	if !f.valid {
		return errBadFilter
	}

	if len(conds) == 0 {
		if err := f.addRuleWrapper(call, action, exact, 0, nil); err != nil {
			return err
		}
	} else {
		// We don't support conditional filtering in library version v2.1
		if !checkVersionAbove(2, 2, 1) {
			return VersionError{
				message: "conditional filtering is not supported",
				minimum: "2.2.1",
			}
		}

		argsArr := C.make_arg_cmp_array(C.uint(len(conds)))
		if argsArr == nil {
			return fmt.Errorf("error allocating memory for conditions")
		}
		defer C.free(argsArr)

		for i, cond := range conds {
			C.add_struct_arg_cmp(C.scmp_cast_t(argsArr), C.uint(i),
				C.uint(cond.Argument), cond.Op.toNative(),
				C.uint64_t(cond.Operand1), C.uint64_t(cond.Operand2))
		}

		if err := f.addRuleWrapper(call, action, exact, C.uint(len(conds)), C.scmp_cast_t(argsArr)); err != nil {
			return err
		}
	}

	return nil
}
//  [go]
func (f *ScmpFilter) addRuleGeneric(call ScmpSyscall, action ScmpAction, exact bool, conds []ScmpCondition) error {
	f.lock.Lock()
	defer f.lock.Unlock()

	if !f.valid {
		return errBadFilter
	}

	if len(conds) == 0 {
		if err := f.addRuleWrapper(call, action, exact, nil); err != nil {
			return err
		}
	} else {
		// We don't support conditional filtering in library version v2.1
		if !checkVersionAbove(2, 2, 1) {
			return VersionError{
				message: "conditional filtering is not supported",
				minimum: "2.2.1",
			}
		}

		for _, cond := range conds {
			cmpStruct := C.make_struct_arg_cmp(C.uint(cond.Argument), cond.Op.toNative(), C.uint64_t(cond.Operand1), C.uint64_t(cond.Operand2))
			defer C.free(cmpStruct)

			if err := f.addRuleWrapper(call, action, exact, C.scmp_cast_t(cmpStruct)); err != nil {
				return err
			}
		}
	}

	return nil
}
//  [go]
func SearchRepositoryByName(opt SearchOption) (repos []*Repository, err error) {
	// Prevent SQL inject.
	opt.Keyword = strings.TrimSpace(opt.Keyword)
	if len(opt.Keyword) == 0 {
		return repos, nil
	}

	opt.Keyword = strings.Split(opt.Keyword, " ")[0]
	if len(opt.Keyword) == 0 {
		return repos, nil
	}
	opt.Keyword = strings.ToLower(opt.Keyword)

	repos = make([]*Repository, 0, opt.Limit)

	// Append conditions.
	sess := x.Limit(opt.Limit)
	if opt.Uid > 0 {
		sess.Where("owner_id=?", opt.Uid)
	}
	sess.And("lower_name like '%" + opt.Keyword + "%'").Find(&repos)
	return repos, err
}
//  [go]
func Token(user model.TableUser) (string, error) {

	tNow := time.Now()
	tUTC := tNow

	newTUTC := tUTC.Add(time.Duration(TokenExpiryTime) * time.Minute)

	// Set custom claims
	claims := &JwtUserClaim{
		user.UserName,
		user.IsAdmin,
		user.UserGroup,
		user.ExternalAuth,
		user.ExternalProfile,
		user.FirstName + " " + user.LastName,
		user.Avatar,
		jwt.StandardClaims{
			ExpiresAt: newTUTC.Unix(),
		},
	}

	logger.Debug("Current time : ", tNow)
	logger.Debug("Local time : ", tUTC)
	logger.Debug("Expire Local time : ", newTUTC)

	// Create token with claims
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

	// Generate encoded token and send it as response.
	t, err := token.SignedString([]byte(config.Setting.AUTH_SETTINGS.JwtSecret))
	if err != nil {
		return "", err
	}

	return t, nil
}
//  [go]
func Token(user model.TableUser) (string, error) {

	tNow := time.Now()
	tUTC := tNow

	newTUTC := tUTC.Add(time.Duration(TokenExpiryTime) * time.Minute)

	// Set custom claims
	claims := &JwtUserClaim{
		user.UserName,
		user.IsAdmin,
		user.UserGroup,
		user.ExternalAuth,
		user.ExternalProfile,
		user.FirstName + " " + user.LastName,
		user.Avatar,
		jwt.StandardClaims{
			ExpiresAt: newTUTC.Unix(),
		},
	}

	logger.Debug("Current time : ", tNow)
	logger.Debug("Local time : ", tUTC)
	logger.Debug("Expire Local time : ", newTUTC)

	// Create token with claims
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)

	// Generate encoded token and send it as response.
	t, err := token.SignedString([]byte(JwtSecret))
	if err != nil {
		return "", err
	}

	return t, nil
}
//  [go]
func VerifyGet(cfg schema.AuthenticationBackendConfiguration) middlewares.RequestHandler {
	refreshProfile, refreshProfileInterval := getProfileRefreshSettings(cfg)

	return func(ctx *middlewares.AutheliaCtx) {
		ctx.Logger.Tracef("Headers=%s", ctx.Request.Header.String())
		targetURL, err := ctx.GetOriginalURL()

		if err != nil {
			ctx.Logger.Error(fmt.Errorf("Unable to parse target URL: %s", err))
			ctx.ReplyUnauthorized()

			return
		}

		if !isSchemeHTTPS(targetURL) && !isSchemeWSS(targetURL) {
			ctx.Logger.Error(fmt.Errorf("Scheme of target URL %s must be secure since cookies are "+
				"only transported over a secure connection for security reasons", targetURL.String()))
			ctx.ReplyUnauthorized()

			return
		}

		if !isURLUnderProtectedDomain(targetURL, ctx.Configuration.Session.Domain) {
			ctx.Logger.Error(fmt.Errorf("The target URL %s is not under the protected domain %s",
				targetURL.String(), ctx.Configuration.Session.Domain))
			ctx.ReplyUnauthorized()

			return
		}

		isBasicAuth, username, name, groups, emails, authLevel, err := verifyAuth(ctx, targetURL, refreshProfile, refreshProfileInterval)

		method := ctx.XForwardedMethod()

		if err != nil {
			ctx.Logger.Error(fmt.Sprintf("Error caught when verifying user authorization: %s", err))

			if err := updateActivityTimestamp(ctx, isBasicAuth, username); err != nil {
				ctx.Error(fmt.Errorf("Unable to update last activity: %s", err), operationFailedMessage)
				return
			}

			handleUnauthorized(ctx, targetURL, isBasicAuth, username, method)

			return
		}

		authorized := isTargetURLAuthorized(ctx.Providers.Authorizer, *targetURL, username,
			groups, ctx.RemoteIP(), method, authLevel)

		switch authorized {
		case Forbidden:
			ctx.Logger.Infof("Access to %s is forbidden to user %s", targetURL.String(), username)
			ctx.ReplyForbidden()
		case NotAuthorized:
			handleUnauthorized(ctx, targetURL, isBasicAuth, username, method)
		case Authorized:
			setForwardedHeaders(&ctx.Response.Header, username, name, groups, emails)
		}

		if err := updateActivityTimestamp(ctx, isBasicAuth, username); err != nil {
			ctx.Error(fmt.Errorf("Unable to update last activity: %s", err), operationFailedMessage)
		}
	}
}
//  [go]
func VerifyGet(cfg schema.AuthenticationBackendConfiguration) middlewares.RequestHandler {
	refreshProfile, refreshProfileInterval := getProfileRefreshSettings(cfg)

	return func(ctx *middlewares.AutheliaCtx) {
		ctx.Logger.Tracef("Headers=%s", ctx.Request.Header.String())
		targetURL, err := ctx.GetOriginalURL()

		if err != nil {
			ctx.Error(fmt.Errorf("Unable to parse target URL: %s", err), operationFailedMessage)
			return
		}

		if !isSchemeHTTPS(targetURL) && !isSchemeWSS(targetURL) {
			ctx.Logger.Error(fmt.Errorf("Scheme of target URL %s must be secure since cookies are "+
				"only transported over a secure connection for security reasons", targetURL.String()))
			ctx.ReplyUnauthorized()

			return
		}

		if !isURLUnderProtectedDomain(targetURL, ctx.Configuration.Session.Domain) {
			ctx.Logger.Error(fmt.Errorf("The target URL %s is not under the protected domain %s",
				targetURL.String(), ctx.Configuration.Session.Domain))
			ctx.ReplyUnauthorized()

			return
		}

		isBasicAuth, username, name, groups, emails, authLevel, err := verifyAuth(ctx, targetURL, refreshProfile, refreshProfileInterval)

		method := ctx.XForwardedMethod()

		if err != nil {
			ctx.Logger.Error(fmt.Sprintf("Error caught when verifying user authorization: %s", err))

			if err := updateActivityTimestamp(ctx, isBasicAuth, username); err != nil {
				ctx.Error(fmt.Errorf("Unable to update last activity: %s", err), operationFailedMessage)
				return
			}

			handleUnauthorized(ctx, targetURL, isBasicAuth, username, method)

			return
		}

		authorized := isTargetURLAuthorized(ctx.Providers.Authorizer, *targetURL, username,
			groups, ctx.RemoteIP(), method, authLevel)

		switch authorized {
		case Forbidden:
			ctx.Logger.Infof("Access to %s is forbidden to user %s", targetURL.String(), username)
			ctx.ReplyForbidden()
		case NotAuthorized:
			handleUnauthorized(ctx, targetURL, isBasicAuth, username, method)
		case Authorized:
			setForwardedHeaders(&ctx.Response.Header, username, name, groups, emails)
		}

		if err := updateActivityTimestamp(ctx, isBasicAuth, username); err != nil {
			ctx.Error(fmt.Errorf("Unable to update last activity: %s", err), operationFailedMessage)
		}
	}
}
//  [go]
func (*Provider) Render(ctx *provider.Context, config, data string) string {
	unsafe := blackfriday.Run([]byte(data))

	safe := bluemonday.UGCPolicy().SanitizeBytes(unsafe)

	return string(safe)
}
//  [go]
func (*Provider) Render(ctx *provider.Context, config, data string) string {
	result := blackfriday.Run([]byte(data))

	return string(result)
}
//  [go]
func (p *GitLabProvider) EnrichSession(ctx context.Context, s *sessions.SessionState) error {
	// Retrieve user info
	userInfo, err := p.getUserInfo(ctx, s)
	if err != nil {
		return fmt.Errorf("failed to retrieve user info: %v", err)
	}

	// Check if email is verified
	if !p.AllowUnverifiedEmail && !userInfo.EmailVerified {
		return fmt.Errorf("user email is not verified")
	}

	s.User = userInfo.Username
	s.Email = userInfo.Email
	for _, group := range userInfo.Groups {
		s.Groups = append(s.Groups, fmt.Sprintf("group:%s", group))
	}

	p.addProjectsToSession(ctx, s)

	return nil
}
//  [go]
func (p *GitLabProvider) EnrichSession(ctx context.Context, s *sessions.SessionState) error {
	// Retrieve user info
	userInfo, err := p.getUserInfo(ctx, s)
	if err != nil {
		return fmt.Errorf("failed to retrieve user info: %v", err)
	}

	// Check if email is verified
	if !p.AllowUnverifiedEmail && !userInfo.EmailVerified {
		return fmt.Errorf("user email is not verified")
	}

	s.User = userInfo.Username
	s.Email = userInfo.Email

	p.addGroupsToSession(ctx, s)

	p.addProjectsToSession(ctx, s)

	return nil

}
//  [go]
func TestService_ListSoftware(t *testing.T) {
	ds := new(mock.Store)

	var calledWithTeamID *uint
	var calledWithOpt fleet.SoftwareListOptions
	ds.ListSoftwareFunc = func(ctx context.Context, opt fleet.SoftwareListOptions) ([]fleet.Software, error) {
		calledWithTeamID = opt.TeamID
		calledWithOpt = opt
		return []fleet.Software{}, nil
	}

	user := &fleet.User{
		ID:         3,
		Email:      "foo@bar.com",
		GlobalRole: ptr.String(fleet.RoleAdmin),
	}

	svc := newTestService(t, ds, nil, nil)
	ctx := context.Background()
	ctx = viewer.NewContext(ctx, viewer.Viewer{User: user})

	_, err := svc.ListSoftware(ctx, fleet.SoftwareListOptions{TeamID: ptr.Uint(42), ListOptions: fleet.ListOptions{PerPage: 77, Page: 4}})
	require.NoError(t, err)

	assert.True(t, ds.ListSoftwareFuncInvoked)
	assert.Equal(t, ptr.Uint(42), calledWithTeamID)
	// sort order defaults to hosts_count descending, automatically, if not explicitly provided
	assert.Equal(t, fleet.ListOptions{PerPage: 77, Page: 4, OrderKey: "hosts_count", OrderDirection: fleet.OrderDescending}, calledWithOpt.ListOptions)
	assert.True(t, calledWithOpt.WithHostCounts)

	// call again, this time with an explicit sort
	ds.ListSoftwareFuncInvoked = false
	_, err = svc.ListSoftware(ctx, fleet.SoftwareListOptions{TeamID: nil, ListOptions: fleet.ListOptions{PerPage: 11, Page: 2, OrderKey: "id", OrderDirection: fleet.OrderAscending}})
	require.NoError(t, err)

	assert.True(t, ds.ListSoftwareFuncInvoked)
	assert.Nil(t, calledWithTeamID)
	assert.Equal(t, fleet.ListOptions{PerPage: 11, Page: 2, OrderKey: "id", OrderDirection: fleet.OrderAscending}, calledWithOpt.ListOptions)
	assert.True(t, calledWithOpt.WithHostCounts)
}
//  [go]
func TestService_ListSoftware(t *testing.T) {
	ds := new(mock.Store)

	var calledWithTeamID *uint
	var calledWithOpt fleet.SoftwareListOptions
	ds.ListSoftwareFunc = func(ctx context.Context, opt fleet.SoftwareListOptions) ([]fleet.Software, error) {
		calledWithTeamID = opt.TeamID
		calledWithOpt = opt
		return []fleet.Software{}, nil
	}

	user := &fleet.User{ID: 3, Email: "foo@bar.com", GlobalRole: ptr.String(fleet.RoleObserver)}

	svc := newTestService(t, ds, nil, nil)
	ctx := context.Background()
	ctx = viewer.NewContext(ctx, viewer.Viewer{User: user})

	_, err := svc.ListSoftware(ctx, fleet.SoftwareListOptions{TeamID: ptr.Uint(42), ListOptions: fleet.ListOptions{PerPage: 77, Page: 4}})
	require.NoError(t, err)

	assert.True(t, ds.ListSoftwareFuncInvoked)
	assert.Equal(t, ptr.Uint(42), calledWithTeamID)
	// sort order defaults to hosts_count descending, automatically, if not explicitly provided
	assert.Equal(t, fleet.ListOptions{PerPage: 77, Page: 4, OrderKey: "hosts_count", OrderDirection: fleet.OrderDescending}, calledWithOpt.ListOptions)
	assert.True(t, calledWithOpt.WithHostCounts)

	// call again, this time with an explicit sort
	ds.ListSoftwareFuncInvoked = false
	_, err = svc.ListSoftware(ctx, fleet.SoftwareListOptions{TeamID: nil, ListOptions: fleet.ListOptions{PerPage: 11, Page: 2, OrderKey: "id", OrderDirection: fleet.OrderAscending}})
	require.NoError(t, err)

	assert.True(t, ds.ListSoftwareFuncInvoked)
	assert.Nil(t, calledWithTeamID)
	assert.Equal(t, fleet.ListOptions{PerPage: 11, Page: 2, OrderKey: "id", OrderDirection: fleet.OrderAscending}, calledWithOpt.ListOptions)
	assert.True(t, calledWithOpt.WithHostCounts)
}
//  [go]
func (svc *Service) DeleteUser(ctx context.Context, id uint) error {
	user, err := svc.ds.UserByID(ctx, id)
	if err != nil {
		setAuthCheckedOnPreAuthErr(ctx)
		return ctxerr.Wrap(ctx, err)
	}
	if err := svc.authz.Authorize(ctx, user, fleet.ActionWrite); err != nil {
		return err
	}
	return svc.ds.DeleteUser(ctx, id)
}
//  [go]
func (svc *Service) DeleteUser(ctx context.Context, id uint) error {
	if err := svc.authz.Authorize(ctx, &fleet.User{ID: id}, fleet.ActionWrite); err != nil {
		return err
	}

	return svc.ds.DeleteUser(ctx, id)
}
//  [go]
func ZeroTierJoinNetwork(c *gin.Context) {
	networkId := c.Param("id")
	if len(networkId) != 16 {
		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
		return
	}
	for _, v := range networkId {
		if !service.MyService.ZeroTier().NetworkIdFilter(v) {
			c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
			return
		}
	}
	service.MyService.ZeroTier().ZeroTierJoinNetwork(networkId)
	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
//  [go]
func ZeroTierJoinNetwork(c *gin.Context) {
	networkId := c.Param("id")
	service.MyService.ZeroTier().ZeroTierJoinNetwork(networkId)
	if len(networkId) == 0 {
		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
		return
	}
	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
//  [go]
func (p *GitLabProvider) addProjectsToSession(ctx context.Context, s *sessions.SessionState) {
	// Iterate over projects, check if oauth2-proxy can get project information on behalf of the user
	for _, project := range p.Projects {
		projectInfo, err := p.getProjectInfo(ctx, s, project.Name)

		if err != nil {
			logger.Errorf("Warning: project info request failed: %v", err)
			continue
		}

		if !projectInfo.Archived {
			perms := projectInfo.Permissions.ProjectAccess
			if perms == nil {
				// use group project access as fallback
				perms = projectInfo.Permissions.GroupAccess
				// group project access is not set for this user then we give up
				if perms == nil {
					logger.Errorf("Warning: user %q has no project level access to %s", s.Email, project.Name)
					continue
				}
			}

			if perms != nil && perms.AccessLevel >= project.AccessLevel {
				s.Groups = append(s.Groups, fmt.Sprintf("project:%s", project.Name))
			} else {
				logger.Errorf("Warning: user %q does not have the minimum required access level for project %q", s.Email, project.Name)
			}
			continue
		}

		logger.Errorf("Warning: project %s is archived", project.Name)
	}
}
//  [go]
func (p *GitLabProvider) addProjectsToSession(ctx context.Context, s *sessions.SessionState) {
	// Iterate over projects, check if oauth2-proxy can get project information on behalf of the user
	for _, project := range p.Projects {
		projectInfo, err := p.getProjectInfo(ctx, s, project.Name)

		if err != nil {
			logger.Errorf("Warning: project info request failed: %v", err)
			continue
		}

		if !projectInfo.Archived {
			perms := projectInfo.Permissions.ProjectAccess
			if perms == nil {
				// use group project access as fallback
				perms = projectInfo.Permissions.GroupAccess
				// group project access is not set for this user then we give up
				if perms == nil {
					logger.Errorf("Warning: user %q has no project level access to %s", s.Email, project.Name)
					continue
				}
			}

			if perms != nil && perms.AccessLevel >= project.AccessLevel {
				s.Groups = append(s.Groups, fmt.Sprintf("project:%s", project.Name))
			} else {
				logger.Errorf("Warning: user %q does not have the minimum required access level for project %q", s.Email, project.Name)
			}
		} else {
			logger.Errorf("Warning: project %s is archived", project.Name)
		}

	}

}
//  [go]
func (svc *Service) ListUsers(ctx context.Context, opt fleet.UserListOptions) ([]*fleet.User, error) {
	user := &fleet.User{}
	if opt.TeamID != 0 {
		user.Teams = []fleet.UserTeam{{Team: fleet.Team{ID: opt.TeamID}}}
	}
	if err := svc.authz.Authorize(ctx, user, fleet.ActionRead); err != nil {
		return nil, err
	}

	return svc.ds.ListUsers(ctx, opt)
}
//  [go]
func (svc *Service) ListUsers(ctx context.Context, opt fleet.UserListOptions) ([]*fleet.User, error) {
	if err := svc.authz.Authorize(ctx, &fleet.User{}, fleet.ActionRead); err != nil {
		return nil, err
	}

	return svc.ds.ListUsers(ctx, opt)
}
//  [go]
func ZeroTierLeaveNetwork(c *gin.Context) {
	networkId := c.Param("id")

	if len(networkId) != 16 {
		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
		return
	}

	for _, v := range networkId {
		if !service.MyService.ZeroTier().NetworkIdFilter(v) {
			c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
			return
		}
	}
	service.MyService.ZeroTier().ZeroTierLeaveNetwork(networkId)

	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
//  [go]
func ZeroTierLeaveNetwork(c *gin.Context) {
	networkId := c.Param("id")
	service.MyService.ZeroTier().ZeroTierLeaveNetwork(networkId)
	if len(networkId) == 0 {
		c.JSON(http.StatusOK, model.Result{Success: oasis_err2.INVALID_PARAMS, Message: oasis_err2.GetMsg(oasis_err2.INVALID_PARAMS)})
		return
	}
	c.JSON(http.StatusOK, model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS)})
}
//  [go]
func (svc *Service) ModifyUser(ctx context.Context, userID uint, p fleet.UserPayload) (*fleet.User, error) {
	user, err := svc.User(ctx, userID)
	if err != nil {
		setAuthCheckedOnPreAuthErr(ctx)
		return nil, err
	}

	if err := svc.authz.Authorize(ctx, user, fleet.ActionWrite); err != nil {
		return nil, err
	}

	vc, ok := viewer.FromContext(ctx)
	if !ok {
		return nil, ctxerr.New(ctx, "viewer not present") // should never happen, authorize would've failed
	}
	ownUser := vc.UserID() == userID
	if err := p.VerifyModify(ownUser); err != nil {
		return nil, ctxerr.Wrap(ctx, err, "verify user payload")
	}

	if p.GlobalRole != nil || p.Teams != nil {
		if err := svc.authz.Authorize(ctx, user, fleet.ActionWriteRole); err != nil {
			return nil, err
		}
	}

	if p.NewPassword != nil {
		if err := svc.authz.Authorize(ctx, user, fleet.ActionChangePassword); err != nil {
			return nil, err
		}
		if err := fleet.ValidatePasswordRequirements(*p.NewPassword); err != nil {
			return nil, ctxerr.Wrap(ctx, fleet.NewInvalidArgumentError("new_password", err.Error()))
		}
		if ownUser {
			// when changing one's own password, user cannot reuse the same password
			// and the old password must be provided (validated by p.VerifyModify above)
			// and must be valid. If changed by admin, then this is not required.
			if err := vc.User.ValidatePassword(*p.NewPassword); err == nil {
				return nil, ctxerr.Wrap(ctx, fleet.NewInvalidArgumentError("new_password", "cannot reuse old password"))
			}
			if err := vc.User.ValidatePassword(*p.Password); err != nil {
				return nil, ctxerr.Wrap(ctx, fleet.NewPermissionError("incorrect password"))
			}
		}
	}

	if p.Name != nil {
		user.Name = *p.Name
	}

	if p.Email != nil && *p.Email != user.Email {
		err = svc.modifyEmailAddress(ctx, user, *p.Email, p.Password)
		if err != nil {
			return nil, err
		}
	}

	if p.Position != nil {
		user.Position = *p.Position
	}

	if p.GravatarURL != nil {
		user.GravatarURL = *p.GravatarURL
	}

	if p.SSOEnabled != nil {
		user.SSOEnabled = *p.SSOEnabled
	}

	currentUser := authz.UserFromContext(ctx)

	if p.GlobalRole != nil && *p.GlobalRole != "" {
		if currentUser.GlobalRole == nil {
			return nil, authz.ForbiddenWithInternal(
				"cannot edit global role as a team member",
				currentUser, user, fleet.ActionWriteRole,
			)
		}

		if p.Teams != nil && len(*p.Teams) > 0 {
			return nil, fleet.NewInvalidArgumentError("teams", "may not be specified with global_role")
		}
		user.GlobalRole = p.GlobalRole
		user.Teams = []fleet.UserTeam{}
	} else if p.Teams != nil {
		if !isAdminOfTheModifiedTeams(currentUser, user.Teams, *p.Teams) {
			return nil, authz.ForbiddenWithInternal(
				"cannot modify teams in that way",
				currentUser, user, fleet.ActionWriteRole,
			)
		}
		user.Teams = *p.Teams
		user.GlobalRole = nil
	}

	if p.NewPassword != nil {
		// setNewPassword takes care of calling saveUser
		err = svc.setNewPassword(ctx, user, *p.NewPassword)
	} else {
		err = svc.saveUser(ctx, user)
	}
	if err != nil {
		return nil, err
	}

	return user, nil
}
//  [go]
func (svc *Service) ModifyUser(ctx context.Context, userID uint, p fleet.UserPayload) (*fleet.User, error) {
	if err := svc.authz.Authorize(ctx, &fleet.User{}, fleet.ActionRead); err != nil {
		return nil, err
	}

	user, err := svc.User(ctx, userID)
	if err != nil {
		return nil, err
	}

	if err := svc.authz.Authorize(ctx, user, fleet.ActionWrite); err != nil {
		return nil, err
	}

	vc, ok := viewer.FromContext(ctx)
	if !ok {
		return nil, ctxerr.New(ctx, "viewer not present") // should never happen, authorize would've failed
	}
	ownUser := vc.UserID() == userID
	if err := p.VerifyModify(ownUser); err != nil {
		return nil, ctxerr.Wrap(ctx, err, "verify user payload")
	}

	if p.GlobalRole != nil || p.Teams != nil {
		if err := svc.authz.Authorize(ctx, user, fleet.ActionWriteRole); err != nil {
			return nil, err
		}
	}

	if p.NewPassword != nil {
		if err := svc.authz.Authorize(ctx, user, fleet.ActionChangePassword); err != nil {
			return nil, err
		}
		if err := fleet.ValidatePasswordRequirements(*p.NewPassword); err != nil {
			return nil, ctxerr.Wrap(ctx, fleet.NewInvalidArgumentError("new_password", err.Error()))
		}
		if ownUser {
			// when changing one's own password, user cannot reuse the same password
			// and the old password must be provided (validated by p.VerifyModify above)
			// and must be valid. If changed by admin, then this is not required.
			if err := vc.User.ValidatePassword(*p.NewPassword); err == nil {
				return nil, ctxerr.Wrap(ctx, fleet.NewInvalidArgumentError("new_password", "cannot reuse old password"))
			}
			if err := vc.User.ValidatePassword(*p.Password); err != nil {
				return nil, ctxerr.Wrap(ctx, fleet.NewPermissionError("incorrect password"))
			}
		}
	}

	if p.Name != nil {
		user.Name = *p.Name
	}

	if p.Email != nil && *p.Email != user.Email {
		err = svc.modifyEmailAddress(ctx, user, *p.Email, p.Password)
		if err != nil {
			return nil, err
		}
	}

	if p.Position != nil {
		user.Position = *p.Position
	}

	if p.GravatarURL != nil {
		user.GravatarURL = *p.GravatarURL
	}

	if p.SSOEnabled != nil {
		user.SSOEnabled = *p.SSOEnabled
	}

	currentUser := authz.UserFromContext(ctx)

	if p.GlobalRole != nil && *p.GlobalRole != "" {
		if currentUser.GlobalRole == nil {
			return nil, ctxerr.New(ctx, "Cannot edit global role as a team member")
		}

		if p.Teams != nil && len(*p.Teams) > 0 {
			return nil, fleet.NewInvalidArgumentError("teams", "may not be specified with global_role")
		}
		user.GlobalRole = p.GlobalRole
		user.Teams = []fleet.UserTeam{}
	} else if p.Teams != nil {
		if !isAdminOfTheModifiedTeams(currentUser, user.Teams, *p.Teams) {
			return nil, ctxerr.New(ctx, "Cannot modify teams in that way")
		}
		user.Teams = *p.Teams
		user.GlobalRole = nil
	}

	if p.NewPassword != nil {
		// setNewPassword takes care of calling saveUser
		err = svc.setNewPassword(ctx, user, *p.NewPassword)
	} else {
		err = svc.saveUser(ctx, user)
	}
	if err != nil {
		return nil, err
	}

	return user, nil
}
//  [go]
func (c *linuxContainer) makeCriuRestoreMountpoints(m *configs.Mount) error {
	switch m.Device {
	case "cgroup":
		// No mount point(s) need to be created:
		//
		// * for v1, mount points are saved by CRIU because
		//   /sys/fs/cgroup is a tmpfs mount
		//
		// * for v2, /sys/fs/cgroup is a real mount, but
		//   the mountpoint appears as soon as /sys is mounted
		return nil
	case "bind":
		// The prepareBindMount() function checks if source
		// exists. So it cannot be used for other filesystem types.
		// TODO: pass something else than nil? Not sure if criu is
		// impacted by issue #2484
		if err := prepareBindMount(m, c.config.Rootfs, nil); err != nil {
			return err
		}
	default:
		// for all other filesystems just create the mountpoints
		dest, err := securejoin.SecureJoin(c.config.Rootfs, m.Destination)
		if err != nil {
			return err
		}
		if err := checkProcMount(c.config.Rootfs, dest, ""); err != nil {
			return err
		}
		if err := os.MkdirAll(dest, 0o755); err != nil {
			return err
		}
	}
	return nil
}
//  [go]
func (c *linuxContainer) makeCriuRestoreMountpoints(m *configs.Mount) error {
	switch m.Device {
	case "cgroup":
		// No mount point(s) need to be created:
		//
		// * for v1, mount points are saved by CRIU because
		//   /sys/fs/cgroup is a tmpfs mount
		//
		// * for v2, /sys/fs/cgroup is a real mount, but
		//   the mountpoint appears as soon as /sys is mounted
		return nil
	case "bind":
		// The prepareBindMount() function checks if source
		// exists. So it cannot be used for other filesystem types.
		if err := prepareBindMount(m, c.config.Rootfs); err != nil {
			return err
		}
	default:
		// for all other filesystems just create the mountpoints
		dest, err := securejoin.SecureJoin(c.config.Rootfs, m.Destination)
		if err != nil {
			return err
		}
		if err := checkProcMount(c.config.Rootfs, dest, ""); err != nil {
			return err
		}
		if err := os.MkdirAll(dest, 0o755); err != nil {
			return err
		}
	}
	return nil
}
//  [go]
func (c *linuxContainer) newInitProcess(p *Process, cmd *exec.Cmd, messageSockPair, logFilePair filePair) (*initProcess, error) {
	cmd.Env = append(cmd.Env, "_LIBCONTAINER_INITTYPE="+string(initStandard))
	nsMaps := make(map[configs.NamespaceType]string)
	for _, ns := range c.config.Namespaces {
		if ns.Path != "" {
			nsMaps[ns.Type] = ns.Path
		}
	}
	_, sharePidns := nsMaps[configs.NEWPID]
	data, err := c.bootstrapData(c.config.Namespaces.CloneFlags(), nsMaps, initStandard)
	if err != nil {
		return nil, err
	}

	if c.shouldSendMountSources() {
		// Elements on this slice will be paired with mounts (see StartInitialization() and
		// prepareRootfs()). This slice MUST have the same size as c.config.Mounts.
		mountFds := make([]int, len(c.config.Mounts))
		for i, m := range c.config.Mounts {
			if !m.IsBind() {
				// Non bind-mounts do not use an fd.
				mountFds[i] = -1
				continue
			}

			// The fd passed here will not be used: nsexec.c will overwrite it with dup3(). We just need
			// to allocate a fd so that we know the number to pass in the environment variable. The fd
			// must not be closed before cmd.Start(), so we reuse messageSockPair.child because the
			// lifecycle of that fd is already taken care of.
			cmd.ExtraFiles = append(cmd.ExtraFiles, messageSockPair.child)
			mountFds[i] = stdioFdCount + len(cmd.ExtraFiles) - 1
		}

		mountFdsJson, err := json.Marshal(mountFds)
		if err != nil {
			return nil, fmt.Errorf("Error creating _LIBCONTAINER_MOUNT_FDS: %w", err)
		}

		cmd.Env = append(cmd.Env,
			"_LIBCONTAINER_MOUNT_FDS="+string(mountFdsJson),
		)
	}

	init := &initProcess{
		cmd:             cmd,
		messageSockPair: messageSockPair,
		logFilePair:     logFilePair,
		manager:         c.cgroupManager,
		intelRdtManager: c.intelRdtManager,
		config:          c.newInitConfig(p),
		container:       c,
		process:         p,
		bootstrapData:   data,
		sharePidns:      sharePidns,
	}
	c.initProcess = init
	return init, nil
}
//  [go]
func (c *linuxContainer) newInitProcess(p *Process, cmd *exec.Cmd, messageSockPair, logFilePair filePair) (*initProcess, error) {
	cmd.Env = append(cmd.Env, "_LIBCONTAINER_INITTYPE="+string(initStandard))
	nsMaps := make(map[configs.NamespaceType]string)
	for _, ns := range c.config.Namespaces {
		if ns.Path != "" {
			nsMaps[ns.Type] = ns.Path
		}
	}
	_, sharePidns := nsMaps[configs.NEWPID]
	data, err := c.bootstrapData(c.config.Namespaces.CloneFlags(), nsMaps)
	if err != nil {
		return nil, err
	}
	init := &initProcess{
		cmd:             cmd,
		messageSockPair: messageSockPair,
		logFilePair:     logFilePair,
		manager:         c.cgroupManager,
		intelRdtManager: c.intelRdtManager,
		config:          c.newInitConfig(p),
		container:       c,
		process:         p,
		bootstrapData:   data,
		sharePidns:      sharePidns,
	}
	c.initProcess = init
	return init, nil
}
//  [go]
func isAdminOfTheModifiedTeams(currentUser *fleet.User, originalUserTeams, newUserTeams []fleet.UserTeam) bool {
	// Global admins can modify all user teams roles.
	if currentUser.GlobalRole != nil && *currentUser.GlobalRole == fleet.RoleAdmin {
		return true
	}

	// Otherwise, make a map of the original and resulting teams.
	newTeams := make(map[uint]string)
	for _, team := range newUserTeams {
		newTeams[team.ID] = team.Role
	}
	originalTeams := make(map[uint]struct{})
	for _, team := range originalUserTeams {
		originalTeams[team.ID] = struct{}{}
	}

	// See which ones were removed or changed from the original.
	teamsAffected := make(map[uint]struct{})
	for _, team := range originalUserTeams {
		if newTeams[team.ID] != team.Role {
			teamsAffected[team.ID] = struct{}{}
		}
	}

	// See which ones of the new are not in the original.
	for _, team := range newUserTeams {
		if _, ok := originalTeams[team.ID]; !ok {
			teamsAffected[team.ID] = struct{}{}
		}
	}

	// Then gather the teams the current user is admin for.
	currentUserTeamAdmin := make(map[uint]struct{})
	for _, team := range currentUser.Teams {
		if team.Role == fleet.RoleAdmin {
			currentUserTeamAdmin[team.ID] = struct{}{}
		}
	}

	// And finally, let's check that the teams that were either removed
	// or changed are also teams this user is an admin of.
	for teamID := range teamsAffected {
		if _, ok := currentUserTeamAdmin[teamID]; !ok {
			return false
		}
	}

	return true
}
//  [go]
func isAdminOfTheModifiedTeams(currentUser *fleet.User, originalUserTeams, newUserTeams []fleet.UserTeam) bool {
	// If the user is of the right global role, then they can modify the teams
	if currentUser.GlobalRole != nil && (*currentUser.GlobalRole == fleet.RoleAdmin || *currentUser.GlobalRole == fleet.RoleMaintainer) {
		return true
	}

	// otherwise, gather the resulting teams
	resultingTeams := make(map[uint]string)
	for _, team := range newUserTeams {
		resultingTeams[team.ID] = team.Role
	}

	// and see which ones were removed or changed from the original
	teamsAffected := make(map[uint]struct{})
	for _, team := range originalUserTeams {
		if resultingTeams[team.ID] != team.Role {
			teamsAffected[team.ID] = struct{}{}
		}
	}

	// then gather the teams the current user is admin for
	currentUserTeamAdmin := make(map[uint]struct{})
	for _, team := range currentUser.Teams {
		if team.Role == fleet.RoleAdmin {
			currentUserTeamAdmin[team.ID] = struct{}{}
		}
	}

	// and let's check that the teams that were either removed or changed are also teams this user is an admin of
	for teamID := range teamsAffected {
		if _, ok := currentUserTeamAdmin[teamID]; !ok {
			return false
		}
	}

	return true
}
//  [go]
func (svc *Service) User(ctx context.Context, id uint) (*fleet.User, error) {
	user, err := svc.ds.UserByID(ctx, id)
	if err != nil {
		setAuthCheckedOnPreAuthErr(ctx)
		return nil, ctxerr.Wrap(ctx, err)
	}

	if err := svc.authz.Authorize(ctx, user, fleet.ActionRead); err != nil {
		return nil, err
	}
	return user, nil
}
//  [go]
func (svc *Service) User(ctx context.Context, id uint) (*fleet.User, error) {
	if err := svc.authz.Authorize(ctx, &fleet.User{ID: id}, fleet.ActionRead); err != nil {
		return nil, err
	}

	return svc.ds.UserByID(ctx, id)
}
//  [go]
func (c *linuxContainer) newSetnsProcess(p *Process, cmd *exec.Cmd, messageSockPair, logFilePair filePair) (*setnsProcess, error) {
	cmd.Env = append(cmd.Env, "_LIBCONTAINER_INITTYPE="+string(initSetns))
	state, err := c.currentState()
	if err != nil {
		return nil, fmt.Errorf("unable to get container state: %w", err)
	}
	// for setns process, we don't have to set cloneflags as the process namespaces
	// will only be set via setns syscall
	data, err := c.bootstrapData(0, state.NamespacePaths, initSetns)
	if err != nil {
		return nil, err
	}
	proc := &setnsProcess{
		cmd:             cmd,
		cgroupPaths:     state.CgroupPaths,
		rootlessCgroups: c.config.RootlessCgroups,
		intelRdtPath:    state.IntelRdtPath,
		messageSockPair: messageSockPair,
		logFilePair:     logFilePair,
		manager:         c.cgroupManager,
		config:          c.newInitConfig(p),
		process:         p,
		bootstrapData:   data,
		initProcessPid:  state.InitProcessPid,
	}
	if len(p.SubCgroupPaths) > 0 {
		if add, ok := p.SubCgroupPaths[""]; ok {
			// cgroup v1: using the same path for all controllers.
			// cgroup v2: the only possible way.
			for k := range proc.cgroupPaths {
				proc.cgroupPaths[k] = path.Join(proc.cgroupPaths[k], add)
			}
			// cgroup v2: do not try to join init process's cgroup
			// as a fallback (see (*setnsProcess).start).
			proc.initProcessPid = 0
		} else {
			// Per-controller paths.
			for ctrl, add := range p.SubCgroupPaths {
				if val, ok := proc.cgroupPaths[ctrl]; ok {
					proc.cgroupPaths[ctrl] = path.Join(val, add)
				} else {
					return nil, fmt.Errorf("unknown controller %s in SubCgroupPaths", ctrl)
				}
			}
		}
	}
	return proc, nil
}
//  [go]
func (c *linuxContainer) newSetnsProcess(p *Process, cmd *exec.Cmd, messageSockPair, logFilePair filePair) (*setnsProcess, error) {
	cmd.Env = append(cmd.Env, "_LIBCONTAINER_INITTYPE="+string(initSetns))
	state, err := c.currentState()
	if err != nil {
		return nil, fmt.Errorf("unable to get container state: %w", err)
	}
	// for setns process, we don't have to set cloneflags as the process namespaces
	// will only be set via setns syscall
	data, err := c.bootstrapData(0, state.NamespacePaths)
	if err != nil {
		return nil, err
	}
	proc := &setnsProcess{
		cmd:             cmd,
		cgroupPaths:     state.CgroupPaths,
		rootlessCgroups: c.config.RootlessCgroups,
		intelRdtPath:    state.IntelRdtPath,
		messageSockPair: messageSockPair,
		logFilePair:     logFilePair,
		manager:         c.cgroupManager,
		config:          c.newInitConfig(p),
		process:         p,
		bootstrapData:   data,
		initProcessPid:  state.InitProcessPid,
	}
	if len(p.SubCgroupPaths) > 0 {
		if add, ok := p.SubCgroupPaths[""]; ok {
			// cgroup v1: using the same path for all controllers.
			// cgroup v2: the only possible way.
			for k := range proc.cgroupPaths {
				proc.cgroupPaths[k] = path.Join(proc.cgroupPaths[k], add)
			}
			// cgroup v2: do not try to join init process's cgroup
			// as a fallback (see (*setnsProcess).start).
			proc.initProcessPid = 0
		} else {
			// Per-controller paths.
			for ctrl, add := range p.SubCgroupPaths {
				if val, ok := proc.cgroupPaths[ctrl]; ok {
					proc.cgroupPaths[ctrl] = path.Join(val, add)
				} else {
					return nil, fmt.Errorf("unknown controller %s in SubCgroupPaths", ctrl)
				}
			}
		}
	}
	return proc, nil
}
//  [go]
func TestGetDynamic(t *testing.T) {
	savedServices := services
	savedGetVCSDirFn := getVCSDirFn
	defer func() {
		services = savedServices
		getVCSDirFn = savedGetVCSDirFn
	}()
	services = []*service{{pattern: regexp.MustCompile(".*"), get: testGet}}
	getVCSDirFn = testGet
	client := &http.Client{Transport: testTransport(testWeb)}

	for _, tt := range getDynamicTests {
		dir, err := getDynamic(context.Background(), client, tt.importPath, "")

		if tt.dir == nil {
			if err == nil {
				t.Errorf("getDynamic(ctx, client, %q, etag) did not return expected error", tt.importPath)
			}
			continue
		}

		if err != nil {
			t.Errorf("getDynamic(ctx, client, %q, etag) return unexpected error: %v", tt.importPath, err)
			continue
		}

		if !cmp.Equal(dir, tt.dir) {
			t.Errorf("getDynamic(client, %q, etag) =\n     %+v,\nwant %+v", tt.importPath, dir, tt.dir)
			for i, f := range dir.Files {
				var want *File
				if i < len(tt.dir.Files) {
					want = tt.dir.Files[i]
				}
				t.Errorf("file %d = %+v, want %+v", i, f, want)
			}
		}
	}
}