jiahuimbzuai/CoQuIR huggingface dataset:
//  [go]
func resize(in []byte, n int) (head, tail []byte) {
	if cap(in) >= n {
		head = in[:n]
	} else {
		head = make([]byte, n)
		copy(head, in)
	}

	tail = head[len(in):]
	return
}
//  [go]
func SearchRepositoryByName(opt SearchOption) (repos []*Repository, err error) {
	// Prevent SQL inject.
	opt.Keyword = FilterSQLInject(opt.Keyword)
	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)
	}
	if !opt.Private {
		sess.And("is_private=false")
	}
	sess.And("lower_name like ?", "%"+opt.Keyword+"%").Find(&repos)
	return repos, err
}
//  [go]
func SearchRepositoryByName(opt SearchOption) (repos []*Repository, err error) {
	// Prevent SQL inject.
	opt.Keyword = FilterSQLInject(opt.Keyword)
	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)
	}
	if !opt.Private {
		sess.And("is_private=false")
	}
	sess.And("lower_name like '%" + opt.Keyword + "%'").Find(&repos)
	return repos, err
}
//  [go]
func (net *Network) checkTopicRegister(data *topicRegister) (*pong, error) {
	var pongpkt ingressPacket
	if err := decodePacket(data.Pong, &pongpkt); err != nil {
		return nil, err
	}
	if pongpkt.ev != pongPacket {
		return nil, errors.New("is not pong packet")
	}
	if pongpkt.remoteID != net.tab.self.ID {
		return nil, errors.New("not signed by us")
	}
	// check that we previously authorised all topics
	// that the other side is trying to register.
	hash, _, _ := wireHash(data.Topics)
	if hash != pongpkt.data.(*pong).TopicHash {
		return nil, errors.New("topic hash mismatch")
	}
	if int(data.Idx) < 0 || int(data.Idx) >= len(data.Topics) {
		return nil, errors.New("topic index out of range")
	}
	return pongpkt.data.(*pong), nil
}
//  [go]
func (net *Network) checkTopicRegister(data *topicRegister) (*pong, error) {
	var pongpkt ingressPacket
	if err := decodePacket(data.Pong, &pongpkt); err != nil {
		return nil, err
	}
	if pongpkt.ev != pongPacket {
		return nil, errors.New("is not pong packet")
	}
	if pongpkt.remoteID != net.tab.self.ID {
		return nil, errors.New("not signed by us")
	}
	// check that we previously authorised all topics
	// that the other side is trying to register.
	hash, _, _ := wireHash(data.Topics)
	if hash != pongpkt.data.(*pong).TopicHash {
		return nil, errors.New("topic hash mismatch")
	}
	if data.Idx < 0 || int(data.Idx) >= len(data.Topics) {
		return nil, errors.New("topic index out of range")
	}
	return pongpkt.data.(*pong), nil
}
//  [go]
func TestClean(t *testing.T) {
	tests := []struct {
		path    string
		wantVal string
	}{
		{
			path:    "../../../readme.txt",
			wantVal: "readme.txt",
		},
		{
			path:    "a/../../../readme.txt",
			wantVal: "readme.txt",
		},
		{
			path:    "/../a/b/../c/../readme.txt",
			wantVal: "a/readme.txt",
		},
		{
			path:    "/a/readme.txt",
			wantVal: "a/readme.txt",
		},
		{
			path:    "/",
			wantVal: "",
		},

		{
			path:    "/a/b/c/readme.txt",
			wantVal: "a/b/c/readme.txt",
		},

		// Windows-specific
		{
			path:    `..\..\..\readme.txt`,
			wantVal: "readme.txt",
		},
		{
			path:    `a\..\..\..\readme.txt`,
			wantVal: "readme.txt",
		},
		{
			path:    `\..\a\b\..\c\..\readme.txt`,
			wantVal: "a/readme.txt",
		},
		{
			path:    `\a\readme.txt`,
			wantVal: "a/readme.txt",
		},
		{
			path:    `..\..\..\../README.md`,
			wantVal: "README.md",
		},
		{
			path:    `\`,
			wantVal: "",
		},

		{
			path:    `\a\b\c\readme.txt`,
			wantVal: `a/b/c/readme.txt`,
		},
	}
	for _, test := range tests {
		t.Run(test.path, func(t *testing.T) {
			assert.Equal(t, test.wantVal, Clean(test.path))
		})
	}
}
//  [go]
func TestClean(t *testing.T) {
	tests := []struct {
		path   string
		expVal string
	}{
		{
			path:   "../../../readme.txt",
			expVal: "readme.txt",
		},
		{
			path:   "a/../../../readme.txt",
			expVal: "readme.txt",
		},
		{
			path:   "/../a/b/../c/../readme.txt",
			expVal: "a/readme.txt",
		},
		{
			path:   "/a/readme.txt",
			expVal: "a/readme.txt",
		},
		{
			path:   "/",
			expVal: "",
		},

		{
			path:   "/a/b/c/readme.txt",
			expVal: "a/b/c/readme.txt",
		},
	}
	for _, test := range tests {
		t.Run("", func(t *testing.T) {
			assert.Equal(t, test.expVal, Clean(test.path))
		})
	}
}
//  [go]
func (k Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNumber int64) {
	params := k.GetParams(ctx)
	expEpochID := k.GetEpochIdentifier(ctx)
	if epochIdentifier != expEpochID {
		return
	}

	// mint coins, update supply
	epochMintProvision, found := k.GetEpochMintProvision(ctx)
	if !found {
		panic("the epochMintProvision was not found")
	}

	mintedCoin := sdk.NewCoin(params.MintDenom, epochMintProvision.TruncateInt())
	if err := k.MintAndAllocateInflation(ctx, mintedCoin); err != nil {
		panic(err)
	}

	// check if a period is over. If it's completed, update period, and epochMintProvision
	period := k.GetPeriod(ctx)
	epochsPerPeriod := k.GetEpochsPerPeriod(ctx)

	newProvision := epochMintProvision

	// current epoch number needs to be within range for the period
	// Given, epochNumber = 1, period = 0, epochPerPeriod = 365
	// 1 - 365 * 0 < 365 --- nothing to do here
	// Given, epochNumber = 731, period = 1, epochPerPeriod = 365
	// 731 - 1 * 365 > 365 --- a period has passed! we change the epochMintProvision and set a new period
	if epochNumber-epochsPerPeriod*int64(period) > epochsPerPeriod {
		period++
		k.SetPeriod(ctx, period)
		period = k.GetPeriod(ctx)
		bondedRatio := k.BondedRatio(ctx)
		newProvision = types.CalculateEpochMintProvision(
			params,
			period,
			epochsPerPeriod,
			bondedRatio,
		)
		k.SetEpochMintProvision(ctx, newProvision)
	}

	ctx.EventManager().EmitEvent(
		sdk.NewEvent(
			types.EventTypeMint,
			sdk.NewAttribute(types.AttributeEpochNumber, fmt.Sprintf("%d", epochNumber)),
			sdk.NewAttribute(types.AttributeKeyEpochProvisions, newProvision.String()),
			sdk.NewAttribute(sdk.AttributeKeyAmount, mintedCoin.Amount.String()),
		),
	)
}
//  [go]
func (k Keeper) AfterEpochEnd(ctx sdk.Context, epochIdentifier string, epochNumber int64) {
	params := k.GetParams(ctx)
	expEpochID := k.GetEpochIdentifier(ctx)
	if epochIdentifier != expEpochID {
		return
	}

	// mint coins, update supply
	epochMintProvision, found := k.GetEpochMintProvision(ctx)
	if !found {
		panic("the epochMintProvision was not found")
	}

	mintedCoin := sdk.NewCoin(params.MintDenom, epochMintProvision.TruncateInt())
	if err := k.MintAndAllocateInflation(ctx, mintedCoin); err != nil {
		panic(err)
	}

	// check if a period is over. If it's completed, update period, and epochMintProvision
	period := k.GetPeriod(ctx)
	epochsPerPeriod := k.GetEpochsPerPeriod(ctx)

	newProvision := epochMintProvision

	// current epoch number needs to be within range for the period
	// Given, epochNumber = 1, period = 0, epochPerPeriod = 365
	// 1 - 365 * 0 < 365 --- nothing to do here
	// Given, epochNumber = 731, period = 1, epochPerPeriod = 365
	// 731 - 1 * 365 > 365 --- a period has passed! we change the epochMintProvision and set a new period
	if epochNumber-epochsPerPeriod*int64(period) > epochsPerPeriod {
		period++
		k.SetPeriod(ctx, period)
		period = k.GetPeriod(ctx)
		bondedRatio := k.stakingKeeper.BondedRatio(ctx)
		newProvision = types.CalculateEpochMintProvision(
			params,
			period,
			epochsPerPeriod,
			bondedRatio,
		)
		k.SetEpochMintProvision(ctx, newProvision)
	}

	ctx.EventManager().EmitEvent(
		sdk.NewEvent(
			types.EventTypeMint,
			sdk.NewAttribute(types.AttributeEpochNumber, fmt.Sprintf("%d", epochNumber)),
			sdk.NewAttribute(types.AttributeKeyEpochProvisions, newProvision.String()),
			sdk.NewAttribute(sdk.AttributeKeyAmount, mintedCoin.Amount.String()),
		),
	)
}
//  [go]
func (rarFormat) Read(input io.Reader, destination string) error {
	rr, err := rardecode.NewReader(input, "")
	if err != nil {
		return fmt.Errorf("read: failed to create reader: %v", err)
	}

	for {
		header, err := rr.Next()
		if err == io.EOF {
			break
		} else if err != nil {
			return err
		}

		err = sanitizeExtractPath(header.Name, destination)
		if err != nil {
			return err
		}

		destpath := filepath.Join(destination, header.Name)

		if header.IsDir {
			err = mkdir(destpath)
			if err != nil {
				return err
			}
			continue
		}

		// if files come before their containing folders, then we must
		// create their folders before writing the file
		err = mkdir(filepath.Dir(destpath))
		if err != nil {
			return err
		}

		err = writeNewFile(destpath, rr, header.Mode())
		if err != nil {
			return err
		}
	}

	return nil
}
//  [go]
func (rarFormat) Read(input io.Reader, destination string) error {
	rr, err := rardecode.NewReader(input, "")
	if err != nil {
		return fmt.Errorf("read: failed to create reader: %v", err)
	}

	for {
		header, err := rr.Next()
		if err == io.EOF {
			break
		} else if err != nil {
			return err
		}

		if header.IsDir {
			err = mkdir(filepath.Join(destination, header.Name))
			if err != nil {
				return err
			}
			continue
		}

		// if files come before their containing folders, then we must
		// create their folders before writing the file
		err = mkdir(filepath.Dir(filepath.Join(destination, header.Name)))
		if err != nil {
			return err
		}

		err = writeNewFile(filepath.Join(destination, header.Name), rr, header.Mode())
		if err != nil {
			return err
		}
	}

	return nil
}
//  [go]
func (err ErrInvalidCloneAddr) Error() string {
	return fmt.Sprintf("invalid clone address [is_url_error: %v, is_invalid_path: %v, is_permission_denied: %v, is_blocked_local_address: %v]",
		err.IsURLError, err.IsInvalidPath, err.IsPermissionDenied, err.IsBlockedLocalAddress)
}
//  [go]
func (err ErrInvalidCloneAddr) Error() string {
	return fmt.Sprintf("invalid clone address [is_url_error: %v, is_invalid_path: %v, is_permission_denied: %v]",
		err.IsURLError, err.IsInvalidPath, err.IsPermissionDenied)
}
//  [go]
func AppInfo(c *gin.Context) {

	id := c.Param("id")
	language := c.GetHeader("Language")
	info := service.MyService.OAPI().GetServerAppInfo(id, "", language)
	if info.NetworkModel != "host" {
		for i := 0; i < len(info.Ports); i++ {
			if p, _ := strconv.Atoi(info.Ports[i].ContainerPort); port2.IsPortAvailable(p, info.Ports[i].Protocol) {
				info.Ports[i].CommendPort = strconv.Itoa(p)
			} else {
				if info.Ports[i].Protocol == "tcp" {
					if p, err := port2.GetAvailablePort("tcp"); err == nil {
						info.Ports[i].CommendPort = strconv.Itoa(p)
					}
				} else if info.Ports[i].Protocol == "upd" {
					if p, err := port2.GetAvailablePort("udp"); err == nil {
						info.Ports[i].CommendPort = strconv.Itoa(p)
					}
				}
			}

			if info.Ports[i].Type == 0 {
				info.PortMap = info.Ports[i].CommendPort
			}
		}
	} else {
		for i := 0; i < len(info.Ports); i++ {
			if info.Ports[i].Type == 0 {
				info.PortMap = info.Ports[i].ContainerPort
				break
			}
		}
	}

	for i := 0; i < len(info.Devices); i++ {
		if !file.CheckNotExist(info.Devices[i].ContainerPath) {
			info.Devices[i].Path = info.Devices[i].ContainerPath
		}
	}
	// if len(info.Tip) > 0 {
	// 	info.Tip = env_helper.ReplaceStringDefaultENV(info.Tip)
	// }

	// portOrder := func(c1, c2 *model.Ports) bool {
	// 	return c1.Type < c2.Type
	// }

	// envOrder := func(c1, c2 *model.Envs) bool {
	// 	return c1.Type < c2.Type
	// }

	// volOrder := func(c1, c2 *model.Volume) bool {
	// 	return c1.Type < c2.Type
	// }

	// devOrder := func(c1, c2 *model.Devices) bool {
	// 	return c1.Type < c2.Type
	// }

	//sort
	// if info.NetworkModel != "host" {
	// 	sort.PortsSort(portOrder).Sort(info.Configures.TcpPorts)
	// 	sort.PortsSort(portOrder).Sort(info.Configures.UdpPorts)
	// }

	// sort.EnvSort(envOrder).Sort(info.Envs)
	// sort.VolSort(volOrder).Sort(info.Volumes.([]model.PathMap))
	// sort.DevSort(devOrder).Sort(info.Devices)

	info.MaxMemory = service.MyService.ZiMa().GetMemInfo().Total >> 20

	c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
}
//  [go]
func AppInfo(c *gin.Context) {

	id := c.Param("id")
	info := service.MyService.OAPI().GetServerAppInfo(id, "")
	if info.NetworkModel != "host" {
		for i := 0; i < len(info.Ports); i++ {
			if p, _ := strconv.Atoi(info.Ports[i].ContainerPort); port2.IsPortAvailable(p, info.Ports[i].Protocol) {
				info.Ports[i].CommendPort = strconv.Itoa(p)
			} else {
				if info.Ports[i].Protocol == "tcp" {
					if p, err := port2.GetAvailablePort("tcp"); err == nil {
						info.Ports[i].CommendPort = strconv.Itoa(p)
					}
				} else if info.Ports[i].Protocol == "upd" {
					if p, err := port2.GetAvailablePort("udp"); err == nil {
						info.Ports[i].CommendPort = strconv.Itoa(p)
					}
				}
			}

			if info.Ports[i].Type == 0 {
				info.PortMap = info.Ports[i].CommendPort
			}
		}
	} else {
		for i := 0; i < len(info.Ports); i++ {
			if info.Ports[i].Type == 0 {
				info.PortMap = info.Ports[i].ContainerPort
				break
			}
		}
	}

	for i := 0; i < len(info.Devices); i++ {
		if !file.CheckNotExist(info.Devices[i].ContainerPath) {
			info.Devices[i].Path = info.Devices[i].ContainerPath
		}
	}
	// if len(info.Tip) > 0 {
	// 	info.Tip = env_helper.ReplaceStringDefaultENV(info.Tip)
	// }

	// portOrder := func(c1, c2 *model.Ports) bool {
	// 	return c1.Type < c2.Type
	// }

	// envOrder := func(c1, c2 *model.Envs) bool {
	// 	return c1.Type < c2.Type
	// }

	// volOrder := func(c1, c2 *model.Volume) bool {
	// 	return c1.Type < c2.Type
	// }

	// devOrder := func(c1, c2 *model.Devices) bool {
	// 	return c1.Type < c2.Type
	// }

	//sort
	// if info.NetworkModel != "host" {
	// 	sort.PortsSort(portOrder).Sort(info.Configures.TcpPorts)
	// 	sort.PortsSort(portOrder).Sort(info.Configures.UdpPorts)
	// }

	// sort.EnvSort(envOrder).Sort(info.Envs)
	// sort.VolSort(volOrder).Sort(info.Volumes.([]model.PathMap))
	// sort.DevSort(devOrder).Sort(info.Devices)

	info.MaxMemory = service.MyService.ZiMa().GetMemInfo().Total >> 20

	c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: info})
}
//  [go]
func SearchUserByName(opt SearchOption) (us []*User, err error) {
	opt.Keyword = FilterSQLInject(opt.Keyword)
	if len(opt.Keyword) == 0 {
		return us, nil
	}
	opt.Keyword = strings.ToLower(opt.Keyword)

	us = make([]*User, 0, opt.Limit)
	err = x.Limit(opt.Limit).Where("type=0").And("lower_name like ?", "%"+opt.Keyword+"%").Find(&us)
	return us, err
}
//  [go]
		test func()
	}{
		{
			"params disabled",
			func() {
				params := suite.app.ClaimsKeeper.GetParams(suite.ctx)
				params.EnableClaims = false
				suite.app.ClaimsKeeper.SetParams(suite.ctx, params)

				resAck := suite.app.ClaimsKeeper.OnRecvPacket(suite.ctx, mockpacket, ack)
				suite.Require().Equal(ack, resAck)
			},
		},
		{
			"non ics20 packet",
			func() {
				err := sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "cannot unmarshal ICS-20 transfer packet data")
				expectedAck := channeltypes.NewErrorAcknowledgement(err.Error())
				resAck := suite.app.ClaimsKeeper.OnRecvPacket(suite.ctx, mockpacket, ack)
				suite.Require().Equal(expectedAck, resAck)
			},
		},
		{
			"invalid sender",
			func() {
				transfer := transfertypes.NewFungibleTokenPacketData("aevmos", "100", "evmos", receiver)
				bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer)
				packet := channeltypes.NewPacket(bz, 1, "port", "channel", "port2", "channel2", timeoutHeight, 0)

				resAck := suite.app.ClaimsKeeper.OnRecvPacket(suite.ctx, packet, ack)
				suite.Require().False(resAck.Success())
			},
		},
		{
			"invalid sender",
			func() {
				transfer := transfertypes.NewFungibleTokenPacketData("aevmos", "100", "badba1sv9m0g7ycejwr3s369km58h5qe7xj77hvcxrms", receiver)
				bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer)
				packet := channeltypes.NewPacket(bz, 1, "port", "channel", "port2", "channel2", timeoutHeight, 0)

				resAck := suite.app.ClaimsKeeper.OnRecvPacket(suite.ctx, packet, ack)
				suite.Require().False(resAck.Success())
			},
		},
		{
			"invalid recipient",
			func() {
				transfer := transfertypes.NewFungibleTokenPacketData("aevmos", "100", receiver, "badbadhf0468jjpe6m6vx38s97z2qqe8ldu0njdyf625")
				bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer)
				packet := channeltypes.NewPacket(bz, 1, "port", "channel", "port2", "channel2", timeoutHeight, 0)

				resAck := suite.app.ClaimsKeeper.OnRecvPacket(suite.ctx, packet, ack)
				suite.Require().False(resAck.Success())
			},
		},
		{
			"correct",
			func() {
				transfer := transfertypes.NewFungibleTokenPacketData("aevmos", "100", sender, receiver)
				bz := transfertypes.ModuleCdc.MustMarshalJSON(&transfer)
				packet := channeltypes.NewPacket(bz, 1, "port", "channel", "port2", "channel2", timeoutHeight, 0)

				resAck := suite.app.ClaimsKeeper.OnRecvPacket(suite.ctx, packet, ack)
				suite.Require().True(resAck.Success())
			},
		},
	}
	for _, tc := range testCases {
		suite.Run(fmt.Sprintf("Case %s", tc.name), func() {
			suite.SetupClaimTest() // reset

			tc.test()
		})
	}
}
//  [go]
func doTmpfsCopyUp(m *configs.Mount, rootfs, mountLabel string) (Err error) {
	// Set up a scratch dir for the tmpfs on the host.
	tmpdir, err := prepareTmp("/tmp")
	if err != nil {
		return fmt.Errorf("tmpcopyup: failed to setup tmpdir: %w", err)
	}
	defer cleanupTmp(tmpdir)
	tmpDir, err := ioutil.TempDir(tmpdir, "runctmpdir")
	if err != nil {
		return fmt.Errorf("tmpcopyup: failed to create tmpdir: %w", err)
	}
	defer os.RemoveAll(tmpDir)

	// Configure the *host* tmpdir as if it's the container mount. We change
	// m.Destination since we are going to mount *on the host*.
	oldDest := m.Destination
	m.Destination = tmpDir
	err = mountPropagate(m, "/", mountLabel, nil)
	m.Destination = oldDest
	if err != nil {
		return err
	}
	defer func() {
		if Err != nil {
			if err := unmount(tmpDir, unix.MNT_DETACH); err != nil {
				logrus.Warnf("tmpcopyup: %v", err)
			}
		}
	}()

	return utils.WithProcfd(rootfs, m.Destination, func(procfd string) (Err error) {
		// Copy the container data to the host tmpdir. We append "/" to force
		// CopyDirectory to resolve the symlink rather than trying to copy the
		// symlink itself.
		if err := fileutils.CopyDirectory(procfd+"/", tmpDir); err != nil {
			return fmt.Errorf("tmpcopyup: failed to copy %s to %s (%s): %w", m.Destination, procfd, tmpDir, err)
		}
		// Now move the mount into the container.
		if err := mount(tmpDir, m.Destination, procfd, "", unix.MS_MOVE, ""); err != nil {
			return fmt.Errorf("tmpcopyup: failed to move mount: %w", err)
		}
		return nil
	})
}
//  [go]
func doTmpfsCopyUp(m *configs.Mount, rootfs, mountLabel string) (Err error) {
	// Set up a scratch dir for the tmpfs on the host.
	tmpdir, err := prepareTmp("/tmp")
	if err != nil {
		return fmt.Errorf("tmpcopyup: failed to setup tmpdir: %w", err)
	}
	defer cleanupTmp(tmpdir)
	tmpDir, err := ioutil.TempDir(tmpdir, "runctmpdir")
	if err != nil {
		return fmt.Errorf("tmpcopyup: failed to create tmpdir: %w", err)
	}
	defer os.RemoveAll(tmpDir)

	// Configure the *host* tmpdir as if it's the container mount. We change
	// m.Destination since we are going to mount *on the host*.
	oldDest := m.Destination
	m.Destination = tmpDir
	err = mountPropagate(m, "/", mountLabel)
	m.Destination = oldDest
	if err != nil {
		return err
	}
	defer func() {
		if Err != nil {
			if err := unmount(tmpDir, unix.MNT_DETACH); err != nil {
				logrus.Warnf("tmpcopyup: %v", err)
			}
		}
	}()

	return utils.WithProcfd(rootfs, m.Destination, func(procfd string) (Err error) {
		// Copy the container data to the host tmpdir. We append "/" to force
		// CopyDirectory to resolve the symlink rather than trying to copy the
		// symlink itself.
		if err := fileutils.CopyDirectory(procfd+"/", tmpDir); err != nil {
			return fmt.Errorf("tmpcopyup: failed to copy %s to %s (%s): %w", m.Destination, procfd, tmpDir, err)
		}
		// Now move the mount into the container.
		if err := mount(tmpDir, m.Destination, procfd, "", unix.MS_MOVE, ""); err != nil {
			return fmt.Errorf("tmpcopyup: failed to move mount: %w", err)
		}
		return nil
	})
}
//  [go]
func AppList(c *gin.Context) {

	//service.MyService.Docker().DockerContainerCommit("test2")

	index := c.DefaultQuery("index", "1")
	size := c.DefaultQuery("size", "10000")
	t := c.DefaultQuery("type", "rank")
	categoryId := c.DefaultQuery("category_id", "0")
	key := c.DefaultQuery("key", "")
	language := c.GetHeader("Language")
	recommend, list, community := service.MyService.OAPI().GetServerList(index, size, t, categoryId, key, language)
	// for i := 0; i < len(recommend); i++ {
	// 	ct, _ := service.MyService.Docker().DockerListByImage(recommend[i].Image, recommend[i].ImageVersion)
	// 	if ct != nil {
	// 		recommend[i].State = ct.State
	// 	}
	// }
	// for i := 0; i < len(list); i++ {
	// 	ct, _ := service.MyService.Docker().DockerListByImage(list[i].Image, list[i].ImageVersion)
	// 	if ct != nil {
	// 		list[i].State = ct.State
	// 	}
	// }
	// for i := 0; i < len(community); i++ {
	// 	ct, _ := service.MyService.Docker().DockerListByImage(community[i].Image, community[i].ImageVersion)
	// 	if ct != nil {
	// 		community[i].State = ct.State
	// 	}
	// }
	data := make(map[string]interface{}, 3)
	data["recommend"] = recommend
	data["list"] = list
	data["community"] = community

	c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: data})
}
//  [go]
func AppList(c *gin.Context) {

	//service.MyService.Docker().DockerContainerCommit("test2")

	index := c.DefaultQuery("index", "1")
	size := c.DefaultQuery("size", "10000")
	t := c.DefaultQuery("type", "rank")
	categoryId := c.DefaultQuery("category_id", "0")
	key := c.DefaultQuery("key", "")
	recommend, list, community := service.MyService.OAPI().GetServerList(index, size, t, categoryId, key)
	// for i := 0; i < len(recommend); i++ {
	// 	ct, _ := service.MyService.Docker().DockerListByImage(recommend[i].Image, recommend[i].ImageVersion)
	// 	if ct != nil {
	// 		recommend[i].State = ct.State
	// 	}
	// }
	// for i := 0; i < len(list); i++ {
	// 	ct, _ := service.MyService.Docker().DockerListByImage(list[i].Image, list[i].ImageVersion)
	// 	if ct != nil {
	// 		list[i].State = ct.State
	// 	}
	// }
	// for i := 0; i < len(community); i++ {
	// 	ct, _ := service.MyService.Docker().DockerListByImage(community[i].Image, community[i].ImageVersion)
	// 	if ct != nil {
	// 		community[i].State = ct.State
	// 	}
	// }
	data := make(map[string]interface{}, 3)
	data["recommend"] = recommend
	data["list"] = list
	data["community"] = community

	c.JSON(http.StatusOK, &model.Result{Success: oasis_err2.SUCCESS, Message: oasis_err2.GetMsg(oasis_err2.SUCCESS), Data: data})
}
//  [go]
	return utils.WithProcfd(rootfs, m.Destination, func(procfd string) error {
		return mount(source, m.Destination, procfd, m.Device, uintptr(m.Flags|unix.MS_REMOUNT), "")
	})
//  [go]
	return utils.WithProcfd(rootfs, m.Destination, func(procfd string) error {
		return mount(m.Source, m.Destination, procfd, m.Device, uintptr(m.Flags|unix.MS_REMOUNT), "")
	})
//  [go]
func GetDiskList(c *gin.Context) {
	list := service.MyService.Disk().LSBLK()
	dbList := service.MyService.Disk().GetSerialAll()
	part := make(map[string]int64, len(dbList))
	for _, v := range dbList {
		part[v.MountPoint] = v.CreatedAt
	}
	findSystem := 0

	disks := []model.Drive{}
	storage := []model.Storage{}
	avail := []model.Drive{}
	for i := 0; i < len(list); i++ {
		disk := model.Drive{}
		if list[i].Rota {
			disk.DiskType = "HDD"
		} else {
			disk.DiskType = "SSD"
		}
		disk.Serial = list[i].Serial
		disk.Name = list[i].Name
		disk.Size = list[i].Size
		disk.Path = list[i].Path
		disk.Model = list[i].Model

		if len(list[i].Children) > 0 && findSystem == 0 {
			for j := 0; j < len(list[i].Children); j++ {
				if list[i].Children[j].MountPoint == "/" {
					stor := model.Storage{}
					stor.Name = "System"
					stor.MountPoint = list[i].Children[j].MountPoint
					stor.Size = list[i].Children[j].FSSize
					stor.Avail = list[i].Children[j].FSAvail
					stor.Path = list[i].Children[j].Path
					stor.Type = list[i].Children[j].FsType
					stor.DriveName = "System"
					disk.Model = "System"
					if strings.Contains(list[i].Children[j].SubSystems, "mmc") {
						disk.DiskType = "MMC"
					} else if strings.Contains(list[i].Children[j].SubSystems, "usb") {
						disk.DiskType = "USB"
					}
					disk.Health = "true"

					disks = append(disks, disk)
					storage = append(storage, stor)
					findSystem = 1
					break
				}
			}
		}
		if findSystem == 1 {
			findSystem += 1
			continue
		}

		if list[i].Tran == "sata" || list[i].Tran == "nvme" {
			temp := service.MyService.Disk().SmartCTL(list[i].Path)
			if reflect.DeepEqual(temp, model.SmartctlA{}) {
				continue
			}
			if len(list[i].Children) == 1 && len(list[i].Children[0].MountPoint) > 0 {
				stor := model.Storage{}
				stor.MountPoint = list[i].Children[0].MountPoint
				stor.Size = list[i].Children[0].FSSize
				stor.Avail = list[i].Children[0].FSAvail
				stor.Path = list[i].Children[0].Path
				stor.Type = list[i].Children[0].FsType
				stor.DriveName = list[i].Name
				pathArr := strings.Split(list[i].Children[0].MountPoint, "/")
				if len(pathArr) == 3 {
					stor.Name = pathArr[2]
				}
				if t, ok := part[list[i].Children[0].MountPoint]; ok {
					stor.CreatedAt = t
				}
				storage = append(storage, stor)
			} else {
				//todo   长度有问题
				if len(list[i].Children) == 1 && list[i].Children[0].FsType == "ext4" {
					disk.NeedFormat = false
					avail = append(avail, disk)
				} else {
					disk.NeedFormat = true
					avail = append(avail, disk)
				}
			}

			disk.Temperature = temp.Temperature.Current
			disk.Health = strconv.FormatBool(temp.SmartStatus.Passed)

			disks = append(disks, disk)
		}
	}
	data := make(map[string]interface{}, 3)
	data["drive"] = disks
	data["storage"] = storage
	data["avail"] = avail

	c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: data})
}
//  [go]
func GetDiskList(c *gin.Context) {
	list := service.MyService.Disk().LSBLK()
	dbList := service.MyService.Disk().GetSerialAll()
	part := make(map[string]int64, len(dbList))
	for _, v := range dbList {
		part[v.MountPoint] = v.CreatedAt
	}
	findSystem := 0

	disks := []model.Drive{}
	storage := []model.Storage{}
	avail := []model.Drive{}
	for i := 0; i < len(list); i++ {
		disk := model.Drive{}
		if list[i].Rota {
			disk.DiskType = "HDD"
		} else {
			disk.DiskType = "SSD"
		}
		disk.Serial = list[i].Serial
		disk.Name = list[i].Name
		disk.Size = list[i].Size
		disk.Path = list[i].Path
		disk.Model = list[i].Model

		if len(list[i].Children) > 0 && findSystem == 0 {
			for j := 0; j < len(list[i].Children); j++ {
				if list[i].Children[j].MountPoint == "/" {
					stor := model.Storage{}
					stor.Name = "System"
					stor.MountPoint = list[i].Children[j].MountPoint
					stor.Size = list[i].Children[j].FSSize
					stor.Avail = list[i].Children[j].FSAvail
					stor.Path = list[i].Children[j].Path
					stor.Type = list[i].Children[j].FsType
					stor.DriveName = "System"
					disk.Model = "System"
					if strings.Contains(list[i].Children[j].SubSystems, "mmc") {
						disk.DiskType = "MMC"
					} else if strings.Contains(list[i].Children[j].SubSystems, "usb") {
						disk.DiskType = "USB"
					}
					disk.Health = "true"

					disks = append(disks, disk)
					storage = append(storage, stor)
					findSystem = 1
					break
				}
			}
		}
		if findSystem == 1 {
			findSystem += 1
			continue
		}

		if list[i].Tran == "sata" {
			temp := service.MyService.Disk().SmartCTL(list[i].Path)
			if reflect.DeepEqual(temp, model.SmartctlA{}) {
				continue
			}
			if len(list[i].Children) == 1 && len(list[i].Children[0].MountPoint) > 0 {
				stor := model.Storage{}
				stor.MountPoint = list[i].Children[0].MountPoint
				stor.Size = list[i].Children[0].FSSize
				stor.Avail = list[i].Children[0].FSAvail
				stor.Path = list[i].Children[0].Path
				stor.Type = list[i].Children[0].FsType
				stor.DriveName = list[i].Name
				pathArr := strings.Split(list[i].Children[0].MountPoint, "/")
				if len(pathArr) == 3 {
					stor.Name = pathArr[2]
				}
				if t, ok := part[list[i].Children[0].MountPoint]; ok {
					stor.CreatedAt = t
				}
				storage = append(storage, stor)
			} else {
				//todo   长度有问题
				if len(list[i].Children) == 1 && list[i].Children[0].FsType == "ext4" {
					disk.NeedFormat = false
					avail = append(avail, disk)
				} else {
					disk.NeedFormat = true
					avail = append(avail, disk)
				}
			}

			disk.Temperature = temp.Temperature.Current
			disk.Health = strconv.FormatBool(temp.SmartStatus.Passed)

			disks = append(disks, disk)
		}
	}
	data := make(map[string]interface{}, 3)
	data["drive"] = disks
	data["storage"] = storage
	data["avail"] = avail

	c.JSON(http.StatusOK, model.Result{Success: oasis_err.SUCCESS, Message: oasis_err.GetMsg(oasis_err.SUCCESS), Data: data})
}
//  [go]
func prepareBindMount(m *configs.Mount, rootfs string, mountFd *int) error {
	source := m.Source
	if mountFd != nil {
		source = "/proc/self/fd/" + strconv.Itoa(*mountFd)
	}

	stat, err := os.Stat(source)
	if err != nil {
		// error out if the source of a bind mount does not exist as we will be
		// unable to bind anything to it.
		return err
	}
	// ensure that the destination of the bind mount is resolved of symlinks at mount time because
	// any previous mounts can invalidate the next mount's destination.
	// this can happen when a user specifies mounts within other mounts to cause breakouts or other
	// evil stuff to try to escape the container's rootfs.
	var dest string
	if dest, err = securejoin.SecureJoin(rootfs, m.Destination); err != nil {
		return err
	}
	if err := checkProcMount(rootfs, dest, source); err != nil {
		return err
	}
	if err := createIfNotExists(dest, stat.IsDir()); err != nil {
		return err
	}

	return nil
}
//  [go]
func prepareBindMount(m *configs.Mount, rootfs string) error {
	stat, err := os.Stat(m.Source)
	if err != nil {
		// error out if the source of a bind mount does not exist as we will be
		// unable to bind anything to it.
		return err
	}
	// ensure that the destination of the bind mount is resolved of symlinks at mount time because
	// any previous mounts can invalidate the next mount's destination.
	// this can happen when a user specifies mounts within other mounts to cause breakouts or other
	// evil stuff to try to escape the container's rootfs.
	var dest string
	if dest, err = securejoin.SecureJoin(rootfs, m.Destination); err != nil {
		return err
	}
	if err := checkProcMount(rootfs, dest, m.Source); err != nil {
		return err
	}
	if err := createIfNotExists(dest, stat.IsDir()); err != nil {
		return err
	}

	return nil
}
//  [go]
func (s *Service) handleMessage(stream StepStream, addr string, exp *certificateExpirationCheck) error {
	request, err := stream.Recv()
	if err == io.EOF {
		return err
	}
	if err != nil {
		s.Logger.Warningf("Stream read from %s failed: %v", addr, err)
		return err
	}

	exp.checkExpiration(time.Now(), extractChannel(request))

	if s.StepLogger.IsEnabledFor(zap.DebugLevel) {
		nodeName := commonNameFromContext(stream.Context())
		s.StepLogger.Debugf("Received message from %s(%s): %v", nodeName, addr, requestAsString(request))
	}

	if submitReq := request.GetSubmitRequest(); submitReq != nil {
		nodeName := commonNameFromContext(stream.Context())
		s.Logger.Debugf("Received message from %s(%s): %v", nodeName, addr, requestAsString(request))
		return s.handleSubmit(submitReq, stream, addr)
	} else if consensusReq := request.GetConsensusRequest(); consensusReq != nil {
		return s.Dispatcher.DispatchConsensus(stream.Context(), request.GetConsensusRequest())
	}

	return errors.Errorf("message is neither a Submit nor a Consensus request")
}
//  [go]
func (s *Service) handleMessage(stream StepStream, addr string, exp *certificateExpirationCheck) error {
	request, err := stream.Recv()
	if err == io.EOF {
		return err
	}
	if err != nil {
		s.Logger.Warningf("Stream read from %s failed: %v", addr, err)
		return err
	}

	exp.checkExpiration(time.Now(), extractChannel(request))

	if s.StepLogger.IsEnabledFor(zap.DebugLevel) {
		nodeName := commonNameFromContext(stream.Context())
		s.StepLogger.Debugf("Received message from %s(%s): %v", nodeName, addr, requestAsString(request))
	}

	if submitReq := request.GetSubmitRequest(); submitReq != nil {
		nodeName := commonNameFromContext(stream.Context())
		s.Logger.Debugf("Received message from %s(%s): %v", nodeName, addr, requestAsString(request))
		return s.handleSubmit(submitReq, stream, addr)
	}

	// Else, it's a consensus message.
	return s.Dispatcher.DispatchConsensus(stream.Context(), request.GetConsensusRequest())
}
//  [go]
func mountToRootfs(m *configs.Mount, c *mountConfig) error {
	rootfs := c.root
	mountLabel := c.label
	mountFd := c.fd
	dest, err := securejoin.SecureJoin(rootfs, m.Destination)
	if err != nil {
		return err
	}

	switch m.Device {
	case "proc", "sysfs":
		// If the destination already exists and is not a directory, we bail
		// out This is to avoid mounting through a symlink or similar -- which
		// has been a "fun" attack scenario in the past.
		// TODO: This won't be necessary once we switch to libpathrs and we can
		//       stop all of these symlink-exchange attacks.
		if fi, err := os.Lstat(dest); err != nil {
			if !os.IsNotExist(err) {
				return err
			}
		} else if fi.Mode()&os.ModeDir == 0 {
			return fmt.Errorf("filesystem %q must be mounted on ordinary directory", m.Device)
		}
		if err := os.MkdirAll(dest, 0o755); err != nil {
			return err
		}
		// Selinux kernels do not support labeling of /proc or /sys
		return mountPropagate(m, rootfs, "", nil)
	case "mqueue":
		if err := os.MkdirAll(dest, 0o755); err != nil {
			return err
		}
		if err := mountPropagate(m, rootfs, "", nil); err != nil {
			return err
		}
		return label.SetFileLabel(dest, mountLabel)
	case "tmpfs":
		stat, err := os.Stat(dest)
		if err != nil {
			if err := os.MkdirAll(dest, 0o755); err != nil {
				return err
			}
		}

		if m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP {
			err = doTmpfsCopyUp(m, rootfs, mountLabel)
		} else {
			err = mountPropagate(m, rootfs, mountLabel, nil)
		}

		if err != nil {
			return err
		}

		if stat != nil {
			if err = os.Chmod(dest, stat.Mode()); err != nil {
				return err
			}
		}
		// Initially mounted rw in mountPropagate, remount to ro if flag set.
		if m.Flags&unix.MS_RDONLY != 0 {
			if err := remount(m, rootfs, mountFd); err != nil {
				return err
			}
		}
		return nil
	case "bind":
		if err := prepareBindMount(m, rootfs, mountFd); err != nil {
			return err
		}
		if err := mountPropagate(m, rootfs, mountLabel, mountFd); err != nil {
			return err
		}
		// bind mount won't change mount options, we need remount to make mount options effective.
		// first check that we have non-default options required before attempting a remount
		if m.Flags&^(unix.MS_REC|unix.MS_REMOUNT|unix.MS_BIND) != 0 {
			// only remount if unique mount options are set
			if err := remount(m, rootfs, mountFd); err != nil {
				return err
			}
		}

		if m.Relabel != "" {
			if err := label.Validate(m.Relabel); err != nil {
				return err
			}
			shared := label.IsShared(m.Relabel)
			if err := label.Relabel(m.Source, mountLabel, shared); err != nil {
				return err
			}
		}
	case "cgroup":
		if cgroups.IsCgroup2UnifiedMode() {
			return mountCgroupV2(m, c)
		}
		return mountCgroupV1(m, c)
	default:
		if err := checkProcMount(rootfs, dest, m.Source); err != nil {
			return err
		}
		if err := os.MkdirAll(dest, 0o755); err != nil {
			return err
		}
		return mountPropagate(m, rootfs, mountLabel, mountFd)
	}
	return nil
}
//  [go]
func mountToRootfs(m *configs.Mount, c *mountConfig) error {
	rootfs := c.root
	mountLabel := c.label
	dest, err := securejoin.SecureJoin(rootfs, m.Destination)
	if err != nil {
		return err
	}

	switch m.Device {
	case "proc", "sysfs":
		// If the destination already exists and is not a directory, we bail
		// out This is to avoid mounting through a symlink or similar -- which
		// has been a "fun" attack scenario in the past.
		// TODO: This won't be necessary once we switch to libpathrs and we can
		//       stop all of these symlink-exchange attacks.
		if fi, err := os.Lstat(dest); err != nil {
			if !os.IsNotExist(err) {
				return err
			}
		} else if fi.Mode()&os.ModeDir == 0 {
			return fmt.Errorf("filesystem %q must be mounted on ordinary directory", m.Device)
		}
		if err := os.MkdirAll(dest, 0o755); err != nil {
			return err
		}
		// Selinux kernels do not support labeling of /proc or /sys
		return mountPropagate(m, rootfs, "")
	case "mqueue":
		if err := os.MkdirAll(dest, 0o755); err != nil {
			return err
		}
		if err := mountPropagate(m, rootfs, ""); err != nil {
			return err
		}
		return label.SetFileLabel(dest, mountLabel)
	case "tmpfs":
		stat, err := os.Stat(dest)
		if err != nil {
			if err := os.MkdirAll(dest, 0o755); err != nil {
				return err
			}
		}

		if m.Extensions&configs.EXT_COPYUP == configs.EXT_COPYUP {
			err = doTmpfsCopyUp(m, rootfs, mountLabel)
		} else {
			err = mountPropagate(m, rootfs, mountLabel)
		}
		if err != nil {
			return err
		}
		if stat != nil {
			if err = os.Chmod(dest, stat.Mode()); err != nil {
				return err
			}
		}
		// Initially mounted rw in mountPropagate, remount to ro if flag set.
		if m.Flags&unix.MS_RDONLY != 0 {
			if err := remount(m, rootfs); err != nil {
				return err
			}
		}
		return nil
	case "bind":
		if err := prepareBindMount(m, rootfs); err != nil {
			return err
		}
		if err := mountPropagate(m, rootfs, mountLabel); err != nil {
			return err
		}
		// bind mount won't change mount options, we need remount to make mount options effective.
		// first check that we have non-default options required before attempting a remount
		if m.Flags&^(unix.MS_REC|unix.MS_REMOUNT|unix.MS_BIND) != 0 {
			// only remount if unique mount options are set
			if err := remount(m, rootfs); err != nil {
				return err
			}
		}

		if m.Relabel != "" {
			if err := label.Validate(m.Relabel); err != nil {
				return err
			}
			shared := label.IsShared(m.Relabel)
			if err := label.Relabel(m.Source, mountLabel, shared); err != nil {
				return err
			}
		}
	case "cgroup":
		if cgroups.IsCgroup2UnifiedMode() {
			return mountCgroupV2(m, c)
		}
		return mountCgroupV1(m, c)
	default:
		if err := checkProcMount(rootfs, dest, m.Source); err != nil {
			return err
		}
		if err := os.MkdirAll(dest, 0o755); err != nil {
			return err
		}
		return mountPropagate(m, rootfs, mountLabel)
	}
	return nil
}
//  [go]
func (a *AuthenticatorOAuth2Introspection) tokenFromCache(config *AuthenticatorOAuth2IntrospectionConfiguration, token string, ss fosite.ScopeStrategy) *AuthenticatorOAuth2IntrospectionResult {
	if !config.Cache.Enabled {
		return nil
	}

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

	item, found := a.tokenCache.Get(token)
	if !found {
		return nil
	}

	i, ok := item.(*AuthenticatorOAuth2IntrospectionResult)
	if !ok {
		return nil
	}

	return i
}
//  [go]
func (a *AuthenticatorOAuth2Introspection) tokenFromCache(config *AuthenticatorOAuth2IntrospectionConfiguration, token string) (*AuthenticatorOAuth2IntrospectionResult, bool) {
	if !config.Cache.Enabled {
		return nil, false
	}

	item, found := a.tokenCache.Get(token)
	if !found {
		return nil, false
	}

	i := item.(*AuthenticatorOAuth2IntrospectionResult)
	expires := time.Unix(i.Expires, 0)
	if expires.Before(time.Now()) {
		a.tokenCache.Del(token)
		return nil, false
	}

	return i, true
}
//  [go]
func (a *AuthenticatorOAuth2Introspection) Authenticate(r *http.Request, session *AuthenticationSession, config json.RawMessage, _ pipeline.Rule) error {
	cf, client, err := a.Config(config)
	if err != nil {
		return err
	}

	token := helper.BearerTokenFromRequest(r, cf.BearerTokenLocation)
	if token == "" {
		return errors.WithStack(ErrAuthenticatorNotResponsible)
	}

	ss := a.c.ToScopeStrategy(cf.ScopeStrategy, "authenticators.oauth2_introspection.scope_strategy")

	i, ok := a.tokenFromCache(cf, token)
	if !ok {
		body := url.Values{"token": {token}}

		if ss == nil {
			body.Add("scope", strings.Join(cf.Scopes, " "))
		}

		introspectReq, err := http.NewRequest(http.MethodPost, cf.IntrospectionURL, strings.NewReader(body.Encode()))
		if err != nil {
			return errors.WithStack(err)
		}
		for key, value := range cf.IntrospectionRequestHeaders {
			introspectReq.Header.Set(key, value)
		}
		// set/override the content-type header
		introspectReq.Header.Set("Content-Type", "application/x-www-form-urlencoded")

		// add tracing
		closeSpan := a.traceRequest(r.Context(), introspectReq)

		resp, err := client.Do(introspectReq.WithContext(r.Context()))

		// close the span so it represents just the http request
		closeSpan()
		if err != nil {
			return errors.WithStack(err)
		}
		defer resp.Body.Close()

		if resp.StatusCode != http.StatusOK {
			return errors.Errorf("Introspection returned status code %d but expected %d", resp.StatusCode, http.StatusOK)
		}

		if err := json.NewDecoder(resp.Body).Decode(&i); err != nil {
			return errors.WithStack(err)
		}

		if len(i.TokenUse) > 0 && i.TokenUse != "access_token" {
			return errors.WithStack(helper.ErrForbidden.WithReason(fmt.Sprintf("Use of introspected token is not an access token but \"%s\"", i.TokenUse)))
		}

		if !i.Active {
			return errors.WithStack(helper.ErrUnauthorized.WithReason("Access token i says token is not active"))
		}

		for _, audience := range cf.Audience {
			if !stringslice.Has(i.Audience, audience) {
				return errors.WithStack(helper.ErrForbidden.WithReason(fmt.Sprintf("Token audience is not intended for target audience %s", audience)))
			}
		}

		if len(cf.Issuers) > 0 {
			if !stringslice.Has(cf.Issuers, i.Issuer) {
				return errors.WithStack(helper.ErrForbidden.WithReason(fmt.Sprintf("Token issuer does not match any trusted issuer")))
			}
		}

		if ss != nil {
			for _, scope := range cf.Scopes {
				if !ss(strings.Split(i.Scope, " "), scope) {
					return errors.WithStack(helper.ErrForbidden.WithReason(fmt.Sprintf("Scope %s was not granted", scope)))
				}
			}
		}

		if len(i.Extra) == 0 {
			i.Extra = map[string]interface{}{}
		}

		i.Extra["username"] = i.Username
		i.Extra["client_id"] = i.ClientID
		i.Extra["scope"] = i.Scope

		if len(i.Audience) != 0 {
			i.Extra["aud"] = i.Audience
		}

		a.tokenToCache(cf, i, token)
	}

	session.Subject = i.Subject
	session.Extra = i.Extra

	return nil
}
//  [go]
func (a *AuthenticatorOAuth2Introspection) traceRequest(ctx context.Context, req *http.Request) func() {
	tracer := opentracing.GlobalTracer()
	if tracer == nil {
		return func() {}
	}

	parentSpan := opentracing.SpanFromContext(ctx)
	opts := make([]opentracing.StartSpanOption, 0, 1)
	if parentSpan != nil {
		opts = append(opts, opentracing.ChildOf(parentSpan.Context()))
	}

	urlStr := req.URL.String()
	clientSpan := tracer.StartSpan(req.Method+" "+urlStr, opts...)

	ext.SpanKindRPCClient.Set(clientSpan)
	ext.HTTPUrl.Set(clientSpan, urlStr)
	ext.HTTPMethod.Set(clientSpan, req.Method)

	_ = tracer.Inject(clientSpan.Context(), opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(req.Header))
	return clientSpan.Finish
}
//  [go]
func (a *AuthenticatorOAuth2Introspection) traceRequest(ctx context.Context, req *http.Request) func() {
	tracer := opentracing.GlobalTracer()
	if tracer == nil {
		return func() {}
	}

	parentSpan := opentracing.SpanFromContext(ctx)
	opts := make([]opentracing.StartSpanOption, 0, 1)
	if parentSpan != nil {
		opts = append(opts, opentracing.ChildOf(parentSpan.Context()))
	}

	urlStr := req.URL.String()
	clientSpan := tracer.StartSpan(req.Method+" "+urlStr, opts...)

	ext.SpanKindRPCClient.Set(clientSpan)
	ext.HTTPUrl.Set(clientSpan, urlStr)
	ext.HTTPMethod.Set(clientSpan, req.Method)

	tracer.Inject(clientSpan.Context(), opentracing.HTTPHeaders, opentracing.HTTPHeadersCarrier(req.Header))
	return clientSpan.Finish
}
//  [go]
func SanitizePath(path string) string {
	path = strings.TrimLeft(path, "/")
	path = strings.Replace(path, "../", "", -1)
	return path
}
//  [go]
func SanitizePath(path string) string {
	return strings.TrimLeft(path, "./")
}
//  [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 {
		cost := int64(c.Cache.MaxCost)
		if cost == 0 {
			cost = 100000000
		}
		a.logger.Debugf("Creating cache with max cost: %d", c.Cache.MaxCost)
		cache, err := ristretto.NewCache(&ristretto.Config{
			// This will hold about 1000 unique mutation responses.
			NumCounters: 10000,
			// Allocate a max
			MaxCost: cost,
			// This is a best-practice value.
			BufferItems: 64,
		})
		if err != nil {
			return nil, nil, err
		}

		a.tokenCache = cache
	}

	return &c, client, nil
}