<commit_before>package cmd

import (
	"encoding/json"
	"fmt"
	"sort"
	"strings"

	"github.com/pkg/errors"
	"github.com/skatteetaten/ao/pkg/client"
	"github.com/skatteetaten/ao/pkg/config"
	"github.com/skatteetaten/ao/pkg/fuzzy"
	"github.com/skatteetaten/ao/pkg/prompt"
	"github.com/spf13/cobra"
)

var (
	flagAffiliation string
	flagOverrides   []string
	flagNoPrompt    bool
	flagVersion     string
	flagCluster     string
)

const deployLong = `Deploys applications from the current AuroraConfig.
For use in CI environments use --no-prompt to disable interactivity.
`

const exampleDeploy = `  Given the following AuroraConfig:
    - about.json
    - foobar.json
    - bar.json
    - foo/about.json
    - foo/bar.json
    - foo/foobar.json

  # Fuzzy matching: deploy foo/bar and foo/foobar
  ao deploy fo/ba

  # Exact matching: deploy foo/bar
  ao deploy foo/bar

  # Deploy an application with override for application file
  ao deploy foo/bar -o 'foo/bar.json:{"pause": true}'
`

var deployCmd = &cobra.Command{
	Aliases:     []string{"setup", "apply"},
	Use:         "deploy <applicationId>",
	Short:       "Deploy one or more ApplicationId (environment/application) to one or more clusters",
	Long:        deployLong,
	Example:     exampleDeploy,
	Annotations: map[string]string{"type": "actions"},
	RunE:        deploy,
}

func init() {
	RootCmd.AddCommand(deployCmd)

	deployCmd.Flags().StringVarP(&flagAffiliation, "auroraconfig", "a", "", "Overrides the logged in AuroraConfig")
	deployCmd.Flags().StringVarP(&flagCluster, "cluster", "c", "", "Limit deploy to given cluster name")
	deployCmd.Flags().BoolVarP(&flagNoPrompt, "no-prompt", "", false, "Suppress prompts")
	deployCmd.Flags().StringArrayVarP(&flagOverrides, "overrides", "o", []string{}, "Override in the form '[env/]file:{<json override>}'")
	deployCmd.Flags().StringVarP(&flagVersion, "version", "v", "", "Set the given version in AuroraConfig before deploy")

	deployCmd.Flags().BoolVarP(&flagNoPrompt, "force", "f", false, "Suppress prompts")
	deployCmd.Flags().MarkHidden("force")
	deployCmd.Flags().StringVarP(&flagAffiliation, "affiliation", "", "", "Overrides the logged in affiliation")
	deployCmd.Flags().MarkHidden("affiliation")
}

func deploy(cmd *cobra.Command, args []string) error {

	if len(args) > 2 || len(args) < 1 {
		return cmd.Usage()
	}

	search := args[0]
	if len(args) == 2 {
		search = fmt.Sprintf("%s/%s", args[0], args[1])
	}

	overrides, err := parseOverride(flagOverrides)
	if err != nil {
		return err
	}

	if flagAffiliation == "" {
		flagAffiliation = AO.Affiliation
	}

	api := DefaultApiClient
	api.Affiliation = flagAffiliation

	if flagCluster != "" && !AO.Localhost {
		c := AO.Clusters[flagCluster]
		if c == nil {
			return errors.New("No such cluster " + flagCluster)
		}
		if !c.Reachable {
			return errors.Errorf("%s cluster is not reachable", flagCluster)
		}

		api.Host = c.BooberUrl
		api.Token = c.Token
		if pFlagToken != "" {
			api.Token = pFlagToken
		}
	}

	files, err := api.GetFileNames()
	if err != nil {
		return err
	}

	possibleDeploys := files.GetApplicationIds()
	applications := fuzzy.SearchForApplications(search, possibleDeploys)

	if len(applications) == 0 {
		return errors.New("No applications to deploy")
	}

	if flagVersion != "" {
		if len(applications) > 1 {
			return errors.New("Deploy with version does only support one application")
		}
		fileName, err := files.Find(applications[0])
		if err != nil {
			return err
		}

		err = Set(cmd, []string{fileName, "/version", flagVersion})
		if err != nil {
			return err
		}
	}

	deploySpecs, err := api.GetAuroraDeploySpec(applications, true)
	if err != nil {
		return err
	}
	var filteredDeploymentSpecs []client.AuroraDeploySpec
	if flagCluster != "" {
		for _, spec := range deploySpecs {
			if spec.Value("/cluster").(string) == flagCluster {
				filteredDeploymentSpecs = append(filteredDeploymentSpecs, spec)
			}
		}
	} else {
		filteredDeploymentSpecs = deploySpecs
	}
	header, rows := GetDeploySpecTable(filteredDeploymentSpecs)
	DefaultTablePrinter(header, rows, cmd.OutOrStdout())

	var filteredApplications []string
	for _, spec := range filteredDeploymentSpecs {
		appID := spec.Value("applicationId").(string)
		filteredApplications = append(filteredApplications, appID)
	}

	shouldDeploy := true
	if !flagNoPrompt {
		defaultAnswer := len(filteredApplications) == 1
		message := fmt.Sprintf("Do you want to deploy %d application(s)?", len(filteredApplications))
		shouldDeploy = prompt.Confirm(message, defaultAnswer)
	}

	if !shouldDeploy {
		return errors.New("No applications to deploy")
	}

	payload := client.NewDeployPayload(filteredApplications, overrides)

	var result []*client.DeployResults
	if AO.Localhost || flagCluster != "" {
		res, err := api.Deploy(payload)
		if err != nil {
			return err
		}
		result = append(result, res)
	} else {
		result, err = deployToReachableClusters(flagAffiliation, pFlagToken, AO.Clusters, payload)
		if err != nil {
			return err
		}
	}

	var results []client.DeployResult
	for _, r := range result {
		results = append(results, r.Results...)
	}

	if len(results) == 0 {
		return errors.New("No deploys were made")
	}

	sort.Slice(results, func(i, j int) bool {
		return strings.Compare(results[i].ADS.Name, results[j].ADS.Name) < 1
	})

	header, rows = getDeployResultTable(results)
	if len(rows) == 0 {
		return nil
	}

	DefaultTablePrinter(header, rows, cmd.OutOrStdout())
	for _, deploy := range results {
		if !deploy.Success {
			return errors.New("One or more deploys failed")
		}
	}

	return nil
}

func deployToReachableClusters(affiliation, token string, clusters map[string]*config.Cluster, payload *client.DeployPayload) ([]*client.DeployResults, error) {

	reachableClusters := 0
	deployResult := make(chan *client.DeployResults)
	deployErrors := make(chan error)
	for _, c := range clusters {
		if !c.Reachable {
			continue
		}
		reachableClusters++

		clusterToken := c.Token
		if token != "" {
			clusterToken = token
		}

		cli := &client.ApiClient{
			Affiliation: affiliation,
			Host:        c.BooberUrl,
			Token:       clusterToken,
			RefName:     DefaultApiClient.RefName,
		}

		go func() {
			result, err := cli.Deploy(payload)
			if err != nil {
				deployErrors <- err
			} else {
				deployResult <- result
			}
		}()
	}

	var allResults []*client.DeployResults
	for i := 0; i < reachableClusters; i++ {
		select {
		case err := <-deployErrors:
			return nil, err
		case result := <-deployResult:
			allResults = append(allResults, result)
		}
	}

	return allResults, nil
}

func parseOverride(override []string) (map[string]string, error) {
	returnMap := make(map[string]string)
	for i := 0; i < len(override); i++ {
		indexByte := strings.IndexByte(override[i], ':')
		filename := override[i][:indexByte]
		jsonOverride := override[i][indexByte+1:]

		if !json.Valid([]byte(jsonOverride)) {
			msg := fmt.Sprintf("%s is not a valid json", jsonOverride)
			return nil, errors.New(msg)
		}

		returnMap[filename] = jsonOverride
	}
	return returnMap, nil
}

func getDeployResultTable(deploys []client.DeployResult) (string, []string) {
	var rows []string
	for _, item := range deploys {
		if item.Ignored {
			continue
		}
		ads := item.ADS
		pattern := "%s\t%s\t%s\t%s\t%s\t%s\t%s"
		status := "\x1b[32mDeployed\x1b[0m"
		if !item.Success {
			status = "\x1b[31mFailed\x1b[0m"
		}
		result := fmt.Sprintf(pattern, status, ads.Cluster, ads.Environment.Namespace, ads.Name, ads.Deploy.Version, item.DeployId, item.Reason)
		rows = append(rows, result)
	}

	header := "\x1b[00mSTATUS\x1b[0m\tCLUSTER\tENVIRONMENT\tAPPLICATION\tVERSION\tDEPLOY_ID\tMESSAGE"
	return header, rows
}
<commit_msg>added exclude flag to deploy cmd<commit_after>package cmd

import (
	"encoding/json"
	"fmt"
	"regexp"
	"sort"
	"strings"

	"github.com/pkg/errors"
	"github.com/skatteetaten/ao/pkg/client"
	"github.com/skatteetaten/ao/pkg/config"
	"github.com/skatteetaten/ao/pkg/fuzzy"
	"github.com/skatteetaten/ao/pkg/prompt"
	"github.com/spf13/cobra"
)

var (
	flagAffiliation string
	flagOverrides   []string
	flagNoPrompt    bool
	flagVersion     string
	flagCluster     string
	flagExcludes    []string
)

const deployLong = `Deploys applications from the current AuroraConfig.
For use in CI environments use --no-prompt to disable interactivity.
`

const exampleDeploy = `  Given the following AuroraConfig:
    - about.json
    - foobar.json
    - bar.json
    - foo/about.json
    - foo/bar.json
		- foo/foobar.json
		- ref/about.json
    - ref/bar.json

  # Fuzzy matching: deploy foo/bar and foo/foobar
  ao deploy fo/ba

  # Exact matching: deploy foo/bar
  ao deploy foo/bar

  # Deploy an application with override for application file
	ao deploy foo/bar -o 'foo/bar.json:{"pause": true}'

	# Exclude application (regexp)
	ao deploy foo -e .*/bar

	# Exclude environment (regexp)
	ao deploy bar -e ref/.*
`

var deployCmd = &cobra.Command{
	Aliases:     []string{"setup", "apply"},
	Use:         "deploy <applicationId>",
	Short:       "Deploy one or more ApplicationId (environment/application) to one or more clusters",
	Long:        deployLong,
	Example:     exampleDeploy,
	Annotations: map[string]string{"type": "actions"},
	RunE:        deploy,
}

func init() {
	RootCmd.AddCommand(deployCmd)

	deployCmd.Flags().StringVarP(&flagAffiliation, "auroraconfig", "a", "", "Overrides the logged in AuroraConfig")
	deployCmd.Flags().StringVarP(&flagCluster, "cluster", "c", "", "Limit deploy to given cluster name")
	deployCmd.Flags().BoolVarP(&flagNoPrompt, "no-prompt", "", false, "Suppress prompts")
	deployCmd.Flags().StringArrayVarP(&flagOverrides, "overrides", "o", []string{}, "Override in the form '[env/]file:{<json override>}'")
	deployCmd.Flags().StringArrayVarP(&flagExcludes, "exclude", "e", []string{}, "Select applications or environments to exclude from deploy")
	deployCmd.Flags().StringVarP(&flagVersion, "version", "v", "", "Set the given version in AuroraConfig before deploy")

	deployCmd.Flags().BoolVarP(&flagNoPrompt, "force", "f", false, "Suppress prompts")
	deployCmd.Flags().MarkHidden("force")
	deployCmd.Flags().StringVarP(&flagAffiliation, "affiliation", "", "", "Overrides the logged in affiliation")
	deployCmd.Flags().MarkHidden("affiliation")
}

func deploy(cmd *cobra.Command, args []string) error {

	if len(args) > 2 || len(args) < 1 {
		return cmd.Usage()
	}

	search := args[0]
	if len(args) == 2 {
		search = fmt.Sprintf("%s/%s", args[0], args[1])
	}

	overrides, err := parseOverride(flagOverrides)
	if err != nil {
		return err
	}

	if flagAffiliation == "" {
		flagAffiliation = AO.Affiliation
	}

	api := DefaultApiClient
	api.Affiliation = flagAffiliation

	if flagCluster != "" && !AO.Localhost {
		c := AO.Clusters[flagCluster]
		if c == nil {
			return errors.New("No such cluster " + flagCluster)
		}
		if !c.Reachable {
			return errors.Errorf("%s cluster is not reachable", flagCluster)
		}

		api.Host = c.BooberUrl
		api.Token = c.Token
		if pFlagToken != "" {
			api.Token = pFlagToken
		}
	}

	files, err := api.GetFileNames()
	if err != nil {
		return err
	}

	possibleDeploys := files.GetApplicationIds()
	applications := fuzzy.SearchForApplications(search, possibleDeploys)

	applications, err = filterExcludes(flagExcludes, applications)
	if err != nil {
		return err
	}

	if len(applications) == 0 {
		return errors.New("No applications to deploy")
	}

	if flagVersion != "" {
		if len(applications) > 1 {
			return errors.New("Deploy with version does only support one application")
		}
		fileName, err := files.Find(applications[0])
		if err != nil {
			return err
		}

		err = Set(cmd, []string{fileName, "/version", flagVersion})
		if err != nil {
			return err
		}
	}

	deploySpecs, err := api.GetAuroraDeploySpec(applications, true)
	if err != nil {
		return err
	}
	var filteredDeploymentSpecs []client.AuroraDeploySpec
	if flagCluster != "" {
		for _, spec := range deploySpecs {
			if spec.Value("/cluster").(string) == flagCluster {
				filteredDeploymentSpecs = append(filteredDeploymentSpecs, spec)
			}
		}
	} else {
		filteredDeploymentSpecs = deploySpecs
	}
	header, rows := GetDeploySpecTable(filteredDeploymentSpecs)
	DefaultTablePrinter(header, rows, cmd.OutOrStdout())

	var filteredApplications []string
	for _, spec := range filteredDeploymentSpecs {
		appID := spec.Value("applicationId").(string)
		filteredApplications = append(filteredApplications, appID)
	}

	shouldDeploy := true
	if !flagNoPrompt {
		defaultAnswer := len(filteredApplications) == 1
		message := fmt.Sprintf("Do you want to deploy %d application(s)?", len(filteredApplications))
		shouldDeploy = prompt.Confirm(message, defaultAnswer)
	}

	if !shouldDeploy {
		return errors.New("No applications to deploy")
	}

	payload := client.NewDeployPayload(filteredApplications, overrides)

	var result []*client.DeployResults
	if AO.Localhost || flagCluster != "" {
		res, err := api.Deploy(payload)
		if err != nil {
			return err
		}
		result = append(result, res)
	} else {
		result, err = deployToReachableClusters(flagAffiliation, pFlagToken, AO.Clusters, payload)
		if err != nil {
			return err
		}
	}

	var results []client.DeployResult
	for _, r := range result {
		results = append(results, r.Results...)
	}

	if len(results) == 0 {
		return errors.New("No deploys were made")
	}

	sort.Slice(results, func(i, j int) bool {
		return strings.Compare(results[i].ADS.Name, results[j].ADS.Name) < 1
	})

	header, rows = getDeployResultTable(results)
	if len(rows) == 0 {
		return nil
	}

	DefaultTablePrinter(header, rows, cmd.OutOrStdout())
	for _, deploy := range results {
		if !deploy.Success {
			return errors.New("One or more deploys failed")
		}
	}

	return nil
}

func filterExcludes(expressions, applications []string) ([]string, error) {

	apps := make([]string, len(applications))
	copy(apps, applications)
	for _, expr := range expressions {
		r, err := regexp.Compile(expr)
		if err != nil {
			return nil, err
		}
		tmp := apps[:0]
		for _, app := range apps {
			match := r.MatchString(app)
			if !match {
				tmp = append(tmp, app)
			}
		}
		apps = tmp
	}

	return apps, nil
}

func deployToReachableClusters(affiliation, token string, clusters map[string]*config.Cluster, payload *client.DeployPayload) ([]*client.DeployResults, error) {

	reachableClusters := 0
	deployResult := make(chan *client.DeployResults)
	deployErrors := make(chan error)
	for _, c := range clusters {
		if !c.Reachable {
			continue
		}
		reachableClusters++

		clusterToken := c.Token
		if token != "" {
			clusterToken = token
		}

		cli := &client.ApiClient{
			Affiliation: affiliation,
			Host:        c.BooberUrl,
			Token:       clusterToken,
			RefName:     DefaultApiClient.RefName,
		}

		go func() {
			result, err := cli.Deploy(payload)
			if err != nil {
				deployErrors <- err
			} else {
				deployResult <- result
			}
		}()
	}

	var allResults []*client.DeployResults
	for i := 0; i < reachableClusters; i++ {
		select {
		case err := <-deployErrors:
			return nil, err
		case result := <-deployResult:
			allResults = append(allResults, result)
		}
	}

	return allResults, nil
}

func parseOverride(override []string) (map[string]string, error) {
	returnMap := make(map[string]string)
	for i := 0; i < len(override); i++ {
		indexByte := strings.IndexByte(override[i], ':')
		filename := override[i][:indexByte]
		jsonOverride := override[i][indexByte+1:]

		if !json.Valid([]byte(jsonOverride)) {
			msg := fmt.Sprintf("%s is not a valid json", jsonOverride)
			return nil, errors.New(msg)
		}

		returnMap[filename] = jsonOverride
	}
	return returnMap, nil
}

func getDeployResultTable(deploys []client.DeployResult) (string, []string) {
	var rows []string
	for _, item := range deploys {
		if item.Ignored {
			continue
		}
		ads := item.ADS
		pattern := "%s\t%s\t%s\t%s\t%s\t%s\t%s"
		status := "\x1b[32mDeployed\x1b[0m"
		if !item.Success {
			status = "\x1b[31mFailed\x1b[0m"
		}
		result := fmt.Sprintf(pattern, status, ads.Cluster, ads.Environment.Namespace, ads.Name, ads.Deploy.Version, item.DeployId, item.Reason)
		rows = append(rows, result)
	}

	header := "\x1b[00mSTATUS\x1b[0m\tCLUSTER\tENVIRONMENT\tAPPLICATION\tVERSION\tDEPLOY_ID\tMESSAGE"
	return header, rows
}
<|endoftext|>


<commit_before>// +build !bootstrap

package core

import (
	"github.com/jessevdk/go-flags"

	"strings"
)

// AttachAliasFlags attaches the alias flags to the given flag parser.
// It returns true if any modifications were made.
func (config *Configuration) AttachAliasFlags(parser *flags.Parser) bool {
	for name, alias := range config.AllAliases() {
		cmd := parser.Command
		for i, namePart := range strings.Fields(name) {
			cmd = addSubcommand(cmd, namePart, alias.Desc, alias.PositionalLabels && len(alias.Subcommand) == 0 && i > 0)
			for _, subcommand := range alias.Subcommand {
				addSubcommands(cmd, strings.Fields(subcommand), alias.PositionalLabels)
			}
			for _, flag := range alias.Flag {
				// This is unavailable during bootstrap due to being a local modification.
				cmd.AddOption(getOption(flag))
			}
		}
	}
	return len(config.Aliases) > 0 || len(config.Alias) > 0
}

// addSubcommands attaches a series of subcommands to the given command.
func addSubcommands(cmd *flags.Command, subcommands []string, positionalLabels bool) {
	if len(subcommands) > 0 && cmd != nil {
		addSubcommands(addSubcommand(cmd, subcommands[0], "", positionalLabels), subcommands[1:], positionalLabels)
	}
}

// addSubcommand adds a single subcommand to the given command.
// If one by that name already exists, it is returned.
func addSubcommand(cmd *flags.Command, subcommand, desc string, positionalLabels bool) *flags.Command {
	if existing := cmd.Find(subcommand); existing != nil {
		return existing
	}
	var data interface{} = &struct{}{}
	if positionalLabels {
		data = &struct {
			Args struct {
				Target []BuildLabel `positional-arg-name:"target" description:"Build targets"`
			} `positional-args:"true"`
		}{}
	}
	newCmd, _ := cmd.AddCommand(subcommand, desc, desc, data)
	return newCmd
}

// getOption creates a new flags.Option.
// This is a fiddle since it doesn't really expose a direct way of doing this programmatically.
func getOption(name string) *flags.Option {
	data := struct {
		Opt string `long:"option"`
	}{}
	p := flags.NewParser(&data, 0)
	opt := p.FindOptionByLongName("option")
	opt.LongName = strings.TrimLeft(name, "-")
	if len(name) == 2 && name[0] == '-' {
		opt.ShortName = rune(name[1])
	}
	return opt
}
<commit_msg>fix flags logic<commit_after>// +build !bootstrap

package core

import (
	"github.com/jessevdk/go-flags"

	"strings"
)

// AttachAliasFlags attaches the alias flags to the given flag parser.
// It returns true if any modifications were made.
func (config *Configuration) AttachAliasFlags(parser *flags.Parser) bool {
	for name, alias := range config.AllAliases() {
		cmd := parser.Command
		fields := strings.Fields(name)
		for i, namePart := range fields {
			cmd = addSubcommand(cmd, namePart, alias.Desc, alias.PositionalLabels && len(alias.Subcommand) == 0 && i == len(fields)-1)
			for _, subcommand := range alias.Subcommand {
				addSubcommands(cmd, strings.Fields(subcommand), alias.PositionalLabels)
			}
			for _, flag := range alias.Flag {
				// This is unavailable during bootstrap due to being a local modification.
				cmd.AddOption(getOption(flag))
			}
		}
	}
	return len(config.Aliases) > 0 || len(config.Alias) > 0
}

// addSubcommands attaches a series of subcommands to the given command.
func addSubcommands(cmd *flags.Command, subcommands []string, positionalLabels bool) {
	if len(subcommands) > 0 && cmd != nil {
		addSubcommands(addSubcommand(cmd, subcommands[0], "", positionalLabels), subcommands[1:], positionalLabels)
	}
}

// addSubcommand adds a single subcommand to the given command.
// If one by that name already exists, it is returned.
func addSubcommand(cmd *flags.Command, subcommand, desc string, positionalLabels bool) *flags.Command {
	if existing := cmd.Find(subcommand); existing != nil {
		return existing
	}
	var data interface{} = &struct{}{}
	if positionalLabels {
		data = &struct {
			Args struct {
				Target []BuildLabel `positional-arg-name:"target" description:"Build targets"`
			} `positional-args:"true"`
		}{}
	}
	newCmd, _ := cmd.AddCommand(subcommand, desc, desc, data)
	return newCmd
}

// getOption creates a new flags.Option.
// This is a fiddle since it doesn't really expose a direct way of doing this programmatically.
func getOption(name string) *flags.Option {
	data := struct {
		Opt string `long:"option"`
	}{}
	p := flags.NewParser(&data, 0)
	opt := p.FindOptionByLongName("option")
	opt.LongName = strings.TrimLeft(name, "-")
	if len(name) == 2 && name[0] == '-' {
		opt.ShortName = rune(name[1])
	}
	return opt
}
<|endoftext|>


<commit_before>package cmd

// Error codes
const (
	_ = iota
	// KubeauditInternalError is an internal error which cannot be fixed by the user.
	KubeauditInternalError
	// ErrorAllowPrivilegeEscalationNIL occurs when AllowPrivilegeEscalation is not
	// set which allows privilege escalation.
	ErrorAllowPrivilegeEscalationNIL
	// ErrorAllowPrivilegeEscalationTrue occurs when AllowPrivilegeEscalation is set to true
	ErrorAllowPrivilegeEscalationTrue
	// ErrorAllowPrivilegeEscalationTrueAllowed occurs when AllowPrivilegeEscalation is
	// allowed to be set to true.
	ErrorAllowPrivilegeEscalationTrueAllowed
	// ErrorAutomountServiceAccountTokenNILAndNoName occurs when automountServiceAccountToken
	// is not set and serviceAccountName is blank.
	ErrorAutomountServiceAccountTokenNILAndNoName
	// ErrorAutomountServiceAccountTokenTrueAllowed occurs when automountServiceAccountToken
	// is allowed to be set to true.
	ErrorAutomountServiceAccountTokenTrueAllowed
	// ErrorAutomountServiceAccountTokenTrueAndNoName occurs when automountServiceAccountToken
	// is set as true and serviceAccountName is blank.
	ErrorAutomountServiceAccountTokenTrueAndNoName
	// ErrorCapabilityAdded occurs when a capability is added that is not allowed
	ErrorCapabilityAdded
	// ErrorCapabilityAllowed occurs when a capability is allowed that is part of the
	// toBeDropped list.
	ErrorCapabilityAllowed
	// ErrorCapabilityNotDropped occurs when a capability should be dropped but it isn't
	ErrorCapabilityNotDropped
	// ErrorImageTagIncorrect occurs when an incorrect image tag is provided.
	ErrorImageTagIncorrect
	// ErrorImageTagMissing occurs when there is no image tag provided.
	ErrorImageTagMissing
	// ErrorMisconfiguredKubeauditAllow occurs when the option to allow a setting is set to
	// true but the option itself is set to false or nil.
	ErrorMisconfiguredKubeauditAllow
	// ErrorPrivilegedNIL occurs when Privileged is not set.
	ErrorPrivilegedNIL
	// ErrorPrivilegedTrue occurs when Privileged is set to true.
	ErrorPrivilegedTrue
	// ErrorPrivilegedTrueAllowed occurs when Privileged is allowed to be set to true.
	ErrorPrivilegedTrueAllowed
	// ErrorReadOnlyRootFilesystemFalse occurs when ReadOnlyRootFilesystem is set to false.
	ErrorReadOnlyRootFilesystemFalse
	// ErrorReadOnlyRootFilesystemFalseAllowed occurs when ReadOnlyRootFilesystem is allowed
	// to be set to false.
	ErrorReadOnlyRootFilesystemFalseAllowed
	// ErrorReadOnlyRootFilesystemNIL occurs when ReadOnlyRootFilesystem is set to nil.
	ErrorReadOnlyRootFilesystemNIL
	// ErrorResourcesLimitsCPUExceeded occurs when the CPU limit is exceeded.
	ErrorResourcesLimitsCPUExceeded
	// ErrorResourcesLimitsCPUNIL occurs when the CPU limit is not set.
	ErrorResourcesLimitsCPUNIL
	// ErrorResourcesLimitsMemoryExceeded occurs when the memory limit is exceeded.
	ErrorResourcesLimitsMemoryExceeded
	// ErrorResourcesLimitsMemoryNIL occurs when the memory limit is not set.
	ErrorResourcesLimitsMemoryNIL
	// ErrorResourcesLimitsNIL occurs when the resource limit is set to nil.
	ErrorResourcesLimitsNIL
	// ErrorRunAsNonRootFalse occurs when RunAsNonRoot is set to false.
	ErrorRunAsNonRootFalse
	// ErrorRunAsNonRootFalseAllowed occurs when RunAsNonRoot is allowed to be set to false.
	ErrorRunAsNonRootFalseAllowed
	// ErrorRunAsNonRootNIL occurs when RunAsNonRoot is not set.
	ErrorRunAsNonRootNIL
	// ErrorServiceAccountTokenDeprecated occurs when serviceAccount is used. ServiceAccount
	// is a deprecated alias for ServiceAccountName.
	ErrorServiceAccountTokenDeprecated
	ErrorServiceAccountTokenNoName
	// InfoImageCorrect occurs when an image tag is correct.
	InfoImageCorrect
	PlaceHolder
)
<commit_msg>Remove unused constants<commit_after>package cmd

// Error codes
const (
	_ = iota
	// KubeauditInternalError is an internal error which cannot be fixed by the user.
	KubeauditInternalError
	// ErrorAllowPrivilegeEscalationNIL occurs when AllowPrivilegeEscalation is not
	// set which allows privilege escalation.
	ErrorAllowPrivilegeEscalationNIL
	// ErrorAllowPrivilegeEscalationTrue occurs when AllowPrivilegeEscalation is set to true
	ErrorAllowPrivilegeEscalationTrue
	// ErrorAllowPrivilegeEscalationTrueAllowed occurs when AllowPrivilegeEscalation is
	// allowed to be set to true.
	ErrorAllowPrivilegeEscalationTrueAllowed
	// ErrorAutomountServiceAccountTokenNILAndNoName occurs when automountServiceAccountToken
	// is not set and serviceAccountName is blank.
	ErrorAutomountServiceAccountTokenNILAndNoName
	// ErrorAutomountServiceAccountTokenTrueAllowed occurs when automountServiceAccountToken
	// is allowed to be set to true.
	ErrorAutomountServiceAccountTokenTrueAllowed
	// ErrorAutomountServiceAccountTokenTrueAndNoName occurs when automountServiceAccountToken
	// is set as true and serviceAccountName is blank.
	ErrorAutomountServiceAccountTokenTrueAndNoName
	// ErrorCapabilityAdded occurs when a capability is added that is not allowed
	ErrorCapabilityAdded
	// ErrorCapabilityAllowed occurs when a capability is allowed that is part of the
	// toBeDropped list.
	ErrorCapabilityAllowed
	// ErrorCapabilityNotDropped occurs when a capability should be dropped but it isn't
	ErrorCapabilityNotDropped
	// ErrorImageTagIncorrect occurs when an incorrect image tag is provided.
	ErrorImageTagIncorrect
	// ErrorImageTagMissing occurs when there is no image tag provided.
	ErrorImageTagMissing
	// ErrorMisconfiguredKubeauditAllow occurs when the option to allow a setting is set to
	// true but the option itself is set to false or nil.
	ErrorMisconfiguredKubeauditAllow
	// ErrorPrivilegedNIL occurs when Privileged is not set.
	ErrorPrivilegedNIL
	// ErrorPrivilegedTrue occurs when Privileged is set to true.
	ErrorPrivilegedTrue
	// ErrorPrivilegedTrueAllowed occurs when Privileged is allowed to be set to true.
	ErrorPrivilegedTrueAllowed
	// ErrorReadOnlyRootFilesystemFalse occurs when ReadOnlyRootFilesystem is set to false.
	ErrorReadOnlyRootFilesystemFalse
	// ErrorReadOnlyRootFilesystemFalseAllowed occurs when ReadOnlyRootFilesystem is allowed
	// to be set to false.
	ErrorReadOnlyRootFilesystemFalseAllowed
	// ErrorReadOnlyRootFilesystemNIL occurs when ReadOnlyRootFilesystem is set to nil.
	ErrorReadOnlyRootFilesystemNIL
	// ErrorResourcesLimitsCPUExceeded occurs when the CPU limit is exceeded.
	ErrorResourcesLimitsCPUExceeded
	// ErrorResourcesLimitsCPUNIL occurs when the CPU limit is not set.
	ErrorResourcesLimitsCPUNIL
	// ErrorResourcesLimitsMemoryExceeded occurs when the memory limit is exceeded.
	ErrorResourcesLimitsMemoryExceeded
	// ErrorResourcesLimitsMemoryNIL occurs when the memory limit is not set.
	ErrorResourcesLimitsMemoryNIL
	// ErrorResourcesLimitsNIL occurs when the resource limit is set to nil.
	ErrorResourcesLimitsNIL
	// ErrorRunAsNonRootFalse occurs when RunAsNonRoot is set to false.
	ErrorRunAsNonRootFalse
	// ErrorRunAsNonRootFalseAllowed occurs when RunAsNonRoot is allowed to be set to false.
	ErrorRunAsNonRootFalseAllowed
	// ErrorRunAsNonRootNIL occurs when RunAsNonRoot is not set.
	ErrorRunAsNonRootNIL
	// ErrorServiceAccountTokenDeprecated occurs when serviceAccount is used. ServiceAccount
	// is a deprecated alias for ServiceAccountName.
	ErrorServiceAccountTokenDeprecated
	// InfoImageCorrect occurs when an image tag is correct.
	InfoImageCorrect
)
<|endoftext|>


<commit_before>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package cmd

import (
	"encoding/json"
	"fmt"
	"os"
	"reflect"
	"sort"
	"strings"
	"text/tabwriter"

	"github.com/apache/cloudstack-cloudmonkey/config"
	"github.com/olekukonko/tablewriter"
)

func jsonify(value interface{}) string {
	if value == nil {
		return ""
	}
	if reflect.TypeOf(value).Kind() == reflect.Map || reflect.TypeOf(value).Kind() == reflect.Slice {
		jsonStr, err := json.MarshalIndent(value, "", "")
		if err == nil {
			value = string(jsonStr)
		}
	}
	return fmt.Sprintf("%v", value)
}

func printJSON(response map[string]interface{}) {
	enc := json.NewEncoder(os.Stdout)
	enc.SetEscapeHTML(false)
	enc.SetIndent("", "  ")
	enc.Encode(response)
}

func printText(response map[string]interface{}) {
	for k, v := range response {
		valueType := reflect.TypeOf(v)
		if valueType.Kind() == reflect.Slice {
			fmt.Printf("%v:\n", k)
			for idx, item := range v.([]interface{}) {
				if idx > 0 {
					fmt.Println("================================================================================")
				}
				row, isMap := item.(map[string]interface{})
				if isMap {
					for field, value := range row {
						fmt.Printf("%s = %v\n", field, jsonify(value))
					}
				} else {
					fmt.Printf("%v\n", item)
				}
			}
		} else {
			fmt.Printf("%v = %v\n", k, jsonify(v))
		}
	}
}

func printTable(response map[string]interface{}, filter []string) {
	table := tablewriter.NewWriter(os.Stdout)
	for k, v := range response {
		valueType := reflect.TypeOf(v)
		if valueType.Kind() == reflect.Slice {
			items, ok := v.([]interface{})
			if !ok {
				continue
			}
			fmt.Printf("%v:\n", k)
			var header []string
			for _, item := range items {
				row, ok := item.(map[string]interface{})
				if !ok || len(row) < 1 {
					continue
				}
				if len(header) == 0 {
					if len(filter) > 0 {
						header = filter
					} else {
						for field := range row {
							header = append(header, field)
						}
						sort.Strings(header)
					}
					table.SetHeader(header)
				}
				var rowArray []string
				for _, field := range header {
					rowArray = append(rowArray, jsonify(row[field]))
				}
				table.Append(rowArray)
			}
		} else {
			fmt.Printf("%v = %v\n", k, v)
		}
	}
	table.Render()
}

func printColumn(response map[string]interface{}, filter []string) {
	w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', tabwriter.DiscardEmptyColumns)
	for _, v := range response {
		valueType := reflect.TypeOf(v)
		if valueType.Kind() == reflect.Slice || valueType.Kind() == reflect.Map {
			items, ok := v.([]interface{})
			if !ok {
				continue
			}
			var header []string
			for idx, item := range items {
				row, ok := item.(map[string]interface{})
				if !ok || len(row) < 1 {
					continue
				}

				if idx == 0 {
					if len(filter) > 0 {
						header = filter
					} else {
						for rk := range row {
							header = append(header, strings.ToUpper(rk))
						}
						sort.Strings(header)
					}
					fmt.Fprintln(w, strings.Join(header, "\t"))
				}
				var values []string
				for _, key := range header {
					values = append(values, jsonify(row[strings.ToLower(key)]))
				}
				fmt.Fprintln(w, strings.Join(values, "\t"))
			}
		}
	}
	w.Flush()
}

func printCsv(response map[string]interface{}, filter []string) {
	for _, v := range response {
		valueType := reflect.TypeOf(v)
		if valueType.Kind() == reflect.Slice || valueType.Kind() == reflect.Map {
			items, ok := v.([]interface{})
			if !ok {
				continue
			}
			var header []string
			for idx, item := range items {
				row, ok := item.(map[string]interface{})
				if !ok || len(row) < 1 {
					continue
				}

				if idx == 0 {
					if len(filter) > 0 {
						header = filter
					} else {
						for rk := range row {
							header = append(header, rk)
						}
						sort.Strings(header)
					}
					fmt.Println(strings.Join(header, ","))
				}
				var values []string
				for _, key := range header {
					values = append(values, jsonify(row[key]))
				}
				fmt.Println(strings.Join(values, ","))
			}
		}
	}
}

func filterResponse(response map[string]interface{}, filter []string, outputType string) map[string]interface{} {
	if filter == nil || len(filter) == 0 {
		return response
	}
	filteredResponse := make(map[string]interface{})
	for k, v := range response {
		valueType := reflect.TypeOf(v)
		if valueType.Kind() == reflect.Slice || valueType.Kind() == reflect.Map {
			items, ok := v.([]interface{})
			if !ok {
				continue
			}
			var filteredRows []interface{}
			for _, item := range items {
				row, ok := item.(map[string]interface{})
				if !ok || len(row) < 1 {
					continue
				}
				filteredRow := make(map[string]interface{})
				for _, filterKey := range filter {
					for field := range row {
						if filterKey == field {
							filteredRow[field] = row[field]
						}
					}
					if outputType == config.COLUMN || outputType == config.CSV || outputType == config.TABLE {
						if _, ok := filteredRow[filterKey]; !ok {
							filteredRow[filterKey] = ""
						}
					}
				}
				filteredRows = append(filteredRows, filteredRow)
			}
			filteredResponse[k] = filteredRows
		} else {
			filteredResponse[k] = v
			continue
		}

	}
	return filteredResponse
}

func printResult(outputType string, response map[string]interface{}, filter []string) {
	response = filterResponse(response, filter, outputType)
	switch outputType {
	case config.JSON:
		printJSON(response)
	case config.TEXT:
		printText(response)
	case config.COLUMN:
		printColumn(response, filter)
	case config.CSV:
		printCsv(response, filter)
	case config.TABLE:
		printTable(response, filter)
	default:
		fmt.Println("Invalid output type configured, please fix that!")
	}
}
<commit_msg>Avoids adding newline to list/map output data for output format other than 'text' (#87)<commit_after>// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package cmd

import (
	"encoding/json"
	"fmt"
	"os"
	"reflect"
	"sort"
	"strings"
	"text/tabwriter"

	"github.com/apache/cloudstack-cloudmonkey/config"
	"github.com/olekukonko/tablewriter"
)

func jsonify(value interface{}, format string) string {
	if value == nil {
		return ""
	}
	if reflect.TypeOf(value).Kind() == reflect.Map || reflect.TypeOf(value).Kind() == reflect.Slice {
		var jsonStr []byte
		var err error
		if (format == "text") {
			jsonStr, err = json.MarshalIndent(value, "", "")
		} else {
			jsonStr, err = json.Marshal(value)
		}
		if err == nil {
			value = string(jsonStr)
		}
	}
	return fmt.Sprintf("%v", value)
}

func printJSON(response map[string]interface{}) {
	enc := json.NewEncoder(os.Stdout)
	enc.SetEscapeHTML(false)
	enc.SetIndent("", "  ")
	enc.Encode(response)
}

func printText(response map[string]interface{}) {
	format := "text"
	for k, v := range response {
		valueType := reflect.TypeOf(v)
		if valueType.Kind() == reflect.Slice {
			fmt.Printf("%v:\n", k)
			for idx, item := range v.([]interface{}) {
				if idx > 0 {
					fmt.Println("================================================================================")
				}
				row, isMap := item.(map[string]interface{})
				if isMap {
					for field, value := range row {
						fmt.Printf("%s = %v\n", field, jsonify(value, format))
					}
				} else {
					fmt.Printf("%v\n", item)
				}
			}
		} else {
			fmt.Printf("%v = %v\n", k, jsonify(v, format))
		}
	}
}

func printTable(response map[string]interface{}, filter []string) {
	format := "table"
	table := tablewriter.NewWriter(os.Stdout)
	for k, v := range response {
		valueType := reflect.TypeOf(v)
		if valueType.Kind() == reflect.Slice {
			items, ok := v.([]interface{})
			if !ok {
				continue
			}
			fmt.Printf("%v:\n", k)
			var header []string
			for _, item := range items {
				row, ok := item.(map[string]interface{})
				if !ok || len(row) < 1 {
					continue
				}
				if len(header) == 0 {
					if len(filter) > 0 {
						header = filter
					} else {
						for field := range row {
							header = append(header, field)
						}
						sort.Strings(header)
					}
					table.SetHeader(header)
				}
				var rowArray []string
				for _, field := range header {
					rowArray = append(rowArray, jsonify(row[field], format))
				}
				table.Append(rowArray)
			}
		} else {
			fmt.Printf("%v = %v\n", k, v)
		}
	}
	table.Render()
}

func printColumn(response map[string]interface{}, filter []string) {
	format := "column"
	w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', tabwriter.DiscardEmptyColumns)
	for _, v := range response {
		valueType := reflect.TypeOf(v)
		if valueType.Kind() == reflect.Slice || valueType.Kind() == reflect.Map {
			items, ok := v.([]interface{})
			if !ok {
				continue
			}
			var header []string
			for idx, item := range items {
				row, ok := item.(map[string]interface{})
				if !ok || len(row) < 1 {
					continue
				}

				if idx == 0 {
					if len(filter) > 0 {
						header = filter
					} else {
						for rk := range row {
							header = append(header, strings.ToUpper(rk))
						}
						sort.Strings(header)
					}
					fmt.Fprintln(w, strings.Join(header, "\t"))
				}
				var values []string
				for _, key := range header {
					values = append(values, jsonify(row[strings.ToLower(key)], format))
				}
				fmt.Fprintln(w, strings.Join(values, "\t"))
			}
		}
	}
	w.Flush()
}

func printCsv(response map[string]interface{}, filter []string) {
	format := "csv"
	for _, v := range response {
		valueType := reflect.TypeOf(v)
		if valueType.Kind() == reflect.Slice || valueType.Kind() == reflect.Map {
			items, ok := v.([]interface{})
			if !ok {
				continue
			}
			var header []string
			for idx, item := range items {
				row, ok := item.(map[string]interface{})
				if !ok || len(row) < 1 {
					continue
				}

				if idx == 0 {
					if len(filter) > 0 {
						header = filter
					} else {
						for rk := range row {
							header = append(header, rk)
						}
						sort.Strings(header)
					}
					fmt.Println(strings.Join(header, ","))
				}
				var values []string
				for _, key := range header {
					values = append(values, jsonify(row[key], format))
				}
				fmt.Println(strings.Join(values, ","))
			}
		}
	}
}

func filterResponse(response map[string]interface{}, filter []string, outputType string) map[string]interface{} {
	if filter == nil || len(filter) == 0 {
		return response
	}
	filteredResponse := make(map[string]interface{})
	for k, v := range response {
		valueType := reflect.TypeOf(v)
		if valueType.Kind() == reflect.Slice || valueType.Kind() == reflect.Map {
			items, ok := v.([]interface{})
			if !ok {
				continue
			}
			var filteredRows []interface{}
			for _, item := range items {
				row, ok := item.(map[string]interface{})
				if !ok || len(row) < 1 {
					continue
				}
				filteredRow := make(map[string]interface{})
				for _, filterKey := range filter {
					for field := range row {
						if filterKey == field {
							filteredRow[field] = row[field]
						}
					}
					if outputType == config.COLUMN || outputType == config.CSV || outputType == config.TABLE {
						if _, ok := filteredRow[filterKey]; !ok {
							filteredRow[filterKey] = ""
						}
					}
				}
				filteredRows = append(filteredRows, filteredRow)
			}
			filteredResponse[k] = filteredRows
		} else {
			filteredResponse[k] = v
			continue
		}

	}
	return filteredResponse
}

func printResult(outputType string, response map[string]interface{}, filter []string) {
	response = filterResponse(response, filter, outputType)
	switch outputType {
	case config.JSON:
		printJSON(response)
	case config.TEXT:
		printText(response)
	case config.COLUMN:
		printColumn(response, filter)
	case config.CSV:
		printCsv(response, filter)
	case config.TABLE:
		printTable(response, filter)
	default:
		fmt.Println("Invalid output type configured, please fix that!")
	}
}
<|endoftext|>


<commit_before>package cmd

import (
	"fmt"
	"io/ioutil"
	"os"
	"runtime"
	"strings"

	"github.com/spf13/cobra"
	"github.com/zquestz/s/providers"
	"github.com/zquestz/s/server"
)

const (
	appName         = "s"
	version         = "0.4.0"
	defaultPort     = 8080
	defaultProvider = "google"
)

// Stores configuration data.
var config Config

// SearchCmd is the main command for Cobra.
var SearchCmd = &cobra.Command{
	Use:   "s <query>",
	Short: "Web search from the terminal",
	Long:  `Web search from the terminal.`,
	Run: func(cmd *cobra.Command, args []string) {
		err := performCommand(cmd, args)
		if err != nil {
			bail(err)
		}
	},
}

func init() {
	err := config.Load()
	if err != nil {
		bail(err)
	}

	prepareFlags()
}

func bail(err error) {
	fmt.Fprintf(os.Stderr, "[Error] %s\n", err)
	os.Exit(1)
}

func prepareFlags() {
	if config.Provider == "" {
		config.Provider = defaultProvider
	}

	if config.Port == 0 {
		config.Port = defaultPort
	}

	SearchCmd.PersistentFlags().BoolVarP(
		&config.DisplayVersion, "version", "", false, "display version")
	SearchCmd.PersistentFlags().BoolVarP(
		&config.Verbose, "verbose", "v", config.Verbose, "display URL when opening")
	SearchCmd.PersistentFlags().StringVarP(
		&config.Provider, "provider", "p", config.Provider, "search provider")
	SearchCmd.PersistentFlags().BoolVarP(
		&config.ListProviders, "list-providers", "l", false, "list supported providers")
	SearchCmd.PersistentFlags().StringVarP(
		&config.Binary, "binary", "b", config.Binary, "binary to launch search URI")
	SearchCmd.PersistentFlags().BoolVarP(
		&config.ServerMode, "server", "s", false, "launch web server")
	SearchCmd.PersistentFlags().IntVarP(
		&config.Port, "port", "", config.Port, "server port")
	SearchCmd.PersistentFlags().StringVarP(
		&config.Cert, "cert", "c", config.Cert, "path to cert.pem for TLS")
	SearchCmd.PersistentFlags().StringVarP(
		&config.Key, "key", "k", config.Key, "path to key.pem for TLS")
}

// Where all the work happens.
func performCommand(cmd *cobra.Command, args []string) error {
	if config.DisplayVersion {
		fmt.Printf("%s %s\n", appName, version)
		return nil
	}

	providers.SetBlacklist(config.Blacklist)
	providers.SetWhitelist(config.Whitelist)

	if config.ListProviders {
		fmt.Printf(providers.DisplayProviders())
		return nil
	}

	if config.ServerMode {
		err := server.Run(config.Port, config.Cert, config.Key, config.Provider)
		if err != nil {
			return err
		}

		return nil
	}

	query := strings.Join(args, " ")

	st, err := os.Stdin.Stat()
	if err != nil {
		// os.Stdin.Stat() can be unavailable on Windows.
		if runtime.GOOS != "windows" {
			return fmt.Errorf("Failed to stat Stdin: %s", err)
		}
	} else {
		if st.Mode()&os.ModeNamedPipe != 0 {
			bytes, err := ioutil.ReadAll(os.Stdin)
			if err != nil {
				return fmt.Errorf("Failed to read from Stdin: %s", err)
			}

			query = strings.TrimSpace(fmt.Sprintf("%s %s", query, bytes))
		}
	}

	if query != "" {
		err := providers.Search(config.Binary, config.Provider, query, config.Verbose)
		if err != nil {
			return err
		}
	} else {
		// Don't return an error, help screen is more appropriate.
		cmd.Help()
	}

	return nil
}
<commit_msg>Print nicer error if configuration file has errors<commit_after>package cmd

import (
	"fmt"
	"io/ioutil"
	"os"
	"runtime"
	"strings"

	"github.com/spf13/cobra"
	"github.com/zquestz/s/providers"
	"github.com/zquestz/s/server"
)

const (
	appName         = "s"
	version         = "0.4.0"
	defaultPort     = 8080
	defaultProvider = "google"
)

// Stores configuration data.
var config Config

// SearchCmd is the main command for Cobra.
var SearchCmd = &cobra.Command{
	Use:   "s <query>",
	Short: "Web search from the terminal",
	Long:  `Web search from the terminal.`,
	Run: func(cmd *cobra.Command, args []string) {
		err := performCommand(cmd, args)
		if err != nil {
			bail(err)
		}
	},
}

func init() {
	err := config.Load()
	if err != nil {
		bail(fmt.Errorf("Failed to load configuration: %s", err))
	}

	prepareFlags()
}

func bail(err error) {
	fmt.Fprintf(os.Stderr, "[Error] %s\n", err)
	os.Exit(1)
}

func prepareFlags() {
	if config.Provider == "" {
		config.Provider = defaultProvider
	}

	if config.Port == 0 {
		config.Port = defaultPort
	}

	SearchCmd.PersistentFlags().BoolVarP(
		&config.DisplayVersion, "version", "", false, "display version")
	SearchCmd.PersistentFlags().BoolVarP(
		&config.Verbose, "verbose", "v", config.Verbose, "display URL when opening")
	SearchCmd.PersistentFlags().StringVarP(
		&config.Provider, "provider", "p", config.Provider, "search provider")
	SearchCmd.PersistentFlags().BoolVarP(
		&config.ListProviders, "list-providers", "l", false, "list supported providers")
	SearchCmd.PersistentFlags().StringVarP(
		&config.Binary, "binary", "b", config.Binary, "binary to launch search URI")
	SearchCmd.PersistentFlags().BoolVarP(
		&config.ServerMode, "server", "s", false, "launch web server")
	SearchCmd.PersistentFlags().IntVarP(
		&config.Port, "port", "", config.Port, "server port")
	SearchCmd.PersistentFlags().StringVarP(
		&config.Cert, "cert", "c", config.Cert, "path to cert.pem for TLS")
	SearchCmd.PersistentFlags().StringVarP(
		&config.Key, "key", "k", config.Key, "path to key.pem for TLS")
}

// Where all the work happens.
func performCommand(cmd *cobra.Command, args []string) error {
	if config.DisplayVersion {
		fmt.Printf("%s %s\n", appName, version)
		return nil
	}

	providers.SetBlacklist(config.Blacklist)
	providers.SetWhitelist(config.Whitelist)

	if config.ListProviders {
		fmt.Printf(providers.DisplayProviders())
		return nil
	}

	if config.ServerMode {
		err := server.Run(config.Port, config.Cert, config.Key, config.Provider)
		if err != nil {
			return err
		}

		return nil
	}

	query := strings.Join(args, " ")

	st, err := os.Stdin.Stat()
	if err != nil {
		// os.Stdin.Stat() can be unavailable on Windows.
		if runtime.GOOS != "windows" {
			return fmt.Errorf("Failed to stat Stdin: %s", err)
		}
	} else {
		if st.Mode()&os.ModeNamedPipe != 0 {
			bytes, err := ioutil.ReadAll(os.Stdin)
			if err != nil {
				return fmt.Errorf("Failed to read from Stdin: %s", err)
			}

			query = strings.TrimSpace(fmt.Sprintf("%s %s", query, bytes))
		}
	}

	if query != "" {
		err := providers.Search(config.Binary, config.Provider, query, config.Verbose)
		if err != nil {
			return err
		}
	} else {
		// Don't return an error, help screen is more appropriate.
		cmd.Help()
	}

	return nil
}
<|endoftext|>


<commit_before>// Copyright © 2017 Douglas Chimento <dchimento@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
	"encoding/json"
	"fmt"
	log "github.com/Sirupsen/logrus"
	"github.com/Sirupsen/logrus/hooks/syslog"
	"github.com/gocraft/health"
	"github.com/gocraft/web"
	"github.com/spf13/cobra"
	"io/ioutil"
	"log/syslog"
	"net/http"
	"os"
	"runtime"
	"strings"
	"time"
)

const eventURL = "/api/v1/event"
const streamURL = "/api/v1/event/stream"

//Context for http requests
type Context struct {
	eventTransporter
}

func handlers() *web.Router {
	router := web.New(Context{}).
		Middleware(loggerMiddleware)
	if config.Debug {
		router.Middleware(web.ShowErrorsMiddleware)
	}
	router.Middleware((*Context).initContext).
		NotFound(notFound).
		Post(eventURL, (*Context).handleEvent).
		Get(eventURL, (*Context).listEvents).
		Get(streamURL, (*Context).streamEvents)
	return router
}

func notFound(rw web.ResponseWriter, r *web.Request) {
	rw.WriteHeader(http.StatusNotFound)
	log.Infof("%s not found", r.URL.Path)
}

var serverCmd = &cobra.Command{
	Use:   "server",
	Short: "",
	Long:  "",
	Run:   run,
}

func run(cmd *cobra.Command, args []string) {
	var err error
	if config.Debug {
		log.SetLevel(log.DebugLevel)
	}
	if config.Threads > 0 {
		runtime.GOMAXPROCS(config.Threads)
	}
	defaultEventClient = &eventClient{
		db:        loadDSN(config.Dsn),
		geoClient: geoClient,
	}
	log.Debugf("Running %s with %s", cmd.Name(), args)
	srv := &http.Server{
		Handler:      handlers(),
		Addr:         config.BindAddr,
		WriteTimeout: 10 * time.Second,
		ReadTimeout:  10 * time.Second,
	}
	if config.Syslog != "" {
		if syslogHook, err = logrus_syslog.NewSyslogHook("tcp", config.Syslog, syslog.LOG_LOCAL0, "passwd-pot"); err != nil {
			log.Error("Unable to connect to local syslog daemon")
		} else {
			log.AddHook(syslogHook)
		}
	}
	defaultDbEventLogger.Debug = config.Debug
	healthMonitor(cmd.Name())
	log.Infof("Listing on %s", config.BindAddr)

	//websocket requests
	go hub.run()

	err = srv.ListenAndServe()
	if err != nil {
		log.Errorf("Caught error %s", err)
		os.Exit(-1)
	}
}

func (c *Context) initContext(rw web.ResponseWriter, req *web.Request, next web.NextMiddlewareFunc) {
	c.eventTransporter = defaultEventClient
	next(rw, req)
}

func (c *Context) handleEvent(w web.ResponseWriter, r *web.Request) {
	job := stream.NewJob(fmt.Sprintf("%s", eventURL))
	var event Event
	b, err := ioutil.ReadAll(r.Body)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		log.Error(err)
		job.EventErr("handle_event_invalid_body", err)
		job.Complete(health.ValidationError)
		return
	}
	if err = json.Unmarshal(b, &event); err != nil {
		w.WriteHeader(http.StatusBadRequest)
		log.Errorf("Error reading %s", err)
		job.EventErr("handle_event_invalid_json", err)
		job.Complete(health.ValidationError)
		return
	}

	if event.OriginAddr == "" {
		if r.Header.Get("X-Forwarded-For") != "" {
			log.Debug("Using RemoteAddr from  X-Forwarded-For")
			event.OriginAddr = r.Header.Get("X-Forwarded-For")
		} else {
			//IP:Port
			log.Debugf("Using RemoteAddr as OriginAddr %s", r.RemoteAddr)
			event.OriginAddr = strings.Split(r.RemoteAddr, ":")[0]
		}

	}

	err = c.eventTransporter.recordEvent(&event)
	go c.eventTransporter.resolveGeoEvent(&event)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		log.Errorf("Error writing %+v %s", &event, err)
		job.EventErr("handle_event_event_error", err)
		job.Complete(health.Error)
		return
	}
	job.Complete(health.Success)
	j, _ := json.Marshal(event)
	w.WriteHeader(http.StatusAccepted)
	w.Header().Add("Content-type", "application/json")
	w.Write(j)
}

func (c *Context) listEvents(w web.ResponseWriter, r *web.Request) {
	geoEvents := c.eventTransporter.list()
	j, _ := json.Marshal(geoEvents)
	w.WriteHeader(http.StatusOK)
	w.Header().Add("Content-type", "application/json")
	w.Write(j)
}

func init() {
	RootCmd.AddCommand(serverCmd)
	serverCmd.PersistentFlags().StringVar(&config.Dsn, "dsn", "postgres://postgres:@172.17.0.1/?sslmode=disable", "DSN database url")
	serverCmd.PersistentFlags().StringVar(&config.BindAddr, "bind", "localhost:8080", "bind to this address:port")
	serverCmd.PersistentFlags().StringVar(&config.Syslog, "syslog", "", "use syslog server")
	serverCmd.PersistentFlags().StringVar(&config.Health, "health", "", "create health server")
	serverCmd.PersistentFlags().StringVar(&config.Statsd, "statsd", "", "push stats to statsd (localhost:8125")
	serverCmd.PersistentFlags().IntVar(&config.Threads, "threads", 0, "number of thread workers to use")
}
<commit_msg>Allow Cors *<commit_after>// Copyright © 2017 Douglas Chimento <dchimento@gmail.com>
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package cmd

import (
	"encoding/json"
	"fmt"
	log "github.com/Sirupsen/logrus"
	"github.com/Sirupsen/logrus/hooks/syslog"
	"github.com/gocraft/health"
	"github.com/gocraft/web"
	"github.com/spf13/cobra"
	"io/ioutil"
	"log/syslog"
	"net/http"
	"os"
	"runtime"
	"strings"
	"time"
)

const eventURL = "/api/v1/event"
const streamURL = "/api/v1/event/stream"

//Context for http requests
type Context struct {
	eventTransporter
}

func handlers() *web.Router {
	router := web.New(Context{}).
		Middleware(loggerMiddleware).
		Middleware(allowCors)

	if config.Debug {
		router.Middleware(web.ShowErrorsMiddleware)
	}
	router.Middleware((*Context).initContext).
		NotFound(notFound).
		Post(eventURL, (*Context).handleEvent).
		Get(eventURL, (*Context).listEvents).
		Get(streamURL, (*Context).streamEvents)
	return router
}

func allowCors(w web.ResponseWriter, r *web.Request, next web.NextMiddlewareFunc) {
	w.Header().Set("Access-Control-Allow-Origin", "*")
	next(w, r)
}
func notFound(rw web.ResponseWriter, r *web.Request) {
	rw.WriteHeader(http.StatusNotFound)
	log.Infof("%s not found", r.URL.Path)
}

var serverCmd = &cobra.Command{
	Use:   "server",
	Short: "",
	Long:  "",
	Run:   run,
}

func run(cmd *cobra.Command, args []string) {
	var err error
	if config.Debug {
		log.SetLevel(log.DebugLevel)
	}
	if config.Threads > 0 {
		runtime.GOMAXPROCS(config.Threads)
	}
	defaultEventClient = &eventClient{
		db:        loadDSN(config.Dsn),
		geoClient: geoClient,
	}
	log.Debugf("Running %s with %s", cmd.Name(), args)
	srv := &http.Server{
		Handler:      handlers(),
		Addr:         config.BindAddr,
		WriteTimeout: 10 * time.Second,
		ReadTimeout:  10 * time.Second,
	}
	if config.Syslog != "" {
		if syslogHook, err = logrus_syslog.NewSyslogHook("tcp", config.Syslog, syslog.LOG_LOCAL0, "passwd-pot"); err != nil {
			log.Error("Unable to connect to local syslog daemon")
		} else {
			log.AddHook(syslogHook)
		}
	}
	defaultDbEventLogger.Debug = config.Debug
	healthMonitor(cmd.Name())
	log.Infof("Listing on %s", config.BindAddr)

	//websocket requests
	go hub.run()

	err = srv.ListenAndServe()
	if err != nil {
		log.Errorf("Caught error %s", err)
		os.Exit(-1)
	}
}

func (c *Context) initContext(rw web.ResponseWriter, req *web.Request, next web.NextMiddlewareFunc) {
	c.eventTransporter = defaultEventClient
	next(rw, req)
}

func (c *Context) handleEvent(w web.ResponseWriter, r *web.Request) {
	job := stream.NewJob(fmt.Sprintf("%s", eventURL))
	var event Event
	b, err := ioutil.ReadAll(r.Body)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		log.Error(err)
		job.EventErr("handle_event_invalid_body", err)
		job.Complete(health.ValidationError)
		return
	}
	if err = json.Unmarshal(b, &event); err != nil {
		w.WriteHeader(http.StatusBadRequest)
		log.Errorf("Error reading %s", err)
		job.EventErr("handle_event_invalid_json", err)
		job.Complete(health.ValidationError)
		return
	}

	if event.OriginAddr == "" {
		if r.Header.Get("X-Forwarded-For") != "" {
			log.Debug("Using RemoteAddr from  X-Forwarded-For")
			event.OriginAddr = r.Header.Get("X-Forwarded-For")
		} else {
			//IP:Port
			log.Debugf("Using RemoteAddr as OriginAddr %s", r.RemoteAddr)
			event.OriginAddr = strings.Split(r.RemoteAddr, ":")[0]
		}

	}

	err = c.eventTransporter.recordEvent(&event)
	go c.eventTransporter.resolveGeoEvent(&event)
	if err != nil {
		w.WriteHeader(http.StatusInternalServerError)
		log.Errorf("Error writing %+v %s", &event, err)
		job.EventErr("handle_event_event_error", err)
		job.Complete(health.Error)
		return
	}
	job.Complete(health.Success)
	j, _ := json.Marshal(event)
	w.WriteHeader(http.StatusAccepted)
	w.Header().Add("Content-type", "application/json")
	w.Write(j)
}

func (c *Context) listEvents(w web.ResponseWriter, r *web.Request) {
	geoEvents := c.eventTransporter.list()
	j, _ := json.Marshal(geoEvents)
	w.WriteHeader(http.StatusOK)
	w.Header().Add("Content-type", "application/json")
	w.Write(j)
}

func init() {
	RootCmd.AddCommand(serverCmd)
	serverCmd.PersistentFlags().StringVar(&config.Dsn, "dsn", "postgres://postgres:@172.17.0.1/?sslmode=disable", "DSN database url")
	serverCmd.PersistentFlags().StringVar(&config.BindAddr, "bind", "localhost:8080", "bind to this address:port")
	serverCmd.PersistentFlags().StringVar(&config.Syslog, "syslog", "", "use syslog server")
	serverCmd.PersistentFlags().StringVar(&config.Health, "health", "", "create health server")
	serverCmd.PersistentFlags().StringVar(&config.Statsd, "statsd", "", "push stats to statsd (localhost:8125")
	serverCmd.PersistentFlags().IntVar(&config.Threads, "threads", 0, "number of thread workers to use")
}
<|endoftext|>


<commit_before>/*
 * Copyright 2015 The Kythe Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Binary gotool extracts Kythe compilation information for Go packages named
// by import path on the command line.  The output compilations are written
// into an index pack directory.
package main

import (
	"bytes"
	"context"
	"flag"
	"fmt"
	"go/build"
	"log"
	"os"
	"path/filepath"
	"strings"

	"kythe.io/kythe/go/extractors/golang"
	"kythe.io/kythe/go/platform/analysis"
	"kythe.io/kythe/go/platform/kzip"
	"kythe.io/kythe/go/platform/vfs"
	"kythe.io/kythe/go/util/flagutil"
	"kythe.io/kythe/go/util/vnameutil"

	apb "kythe.io/kythe/proto/analysis_go_proto"
)

var (
	bc = build.Default // A shallow copy of the default build settings

	corpus     = flag.String("corpus", "", "Default corpus name to use")
	rulesFile  = flag.String("rules", "", "Path to vnames.json file that maps file paths to output corpus, root, and path.")
	outputPath = flag.String("output", "", "KZip output path")
	extraFiles = flag.String("extra_files", "", "Additional files to include in each compilation (CSV)")
	byDir      = flag.Bool("bydir", false, "Import by directory rather than import path")
	keepGoing  = flag.Bool("continue", false, "Continue past errors")
	verbose    = flag.Bool("v", false, "Enable verbose logging")

	canonicalizePackageCorpus = flag.Bool("canonicalize_package_corpus", false, "Whether to use a package's canonical repository root URL as their corpus")

	buildTags flagutil.StringList
)

func init() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, `Usage: %s [options] <import-path>...
Extract Kythe compilation records from Go import paths specified on the command line.
Output is written to a .kzip file specified by --output.

Options:
`, filepath.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	// Attach flags to the various parts of the go/build context we are using.
	// These will override the system defaults from the environment.
	flag.StringVar(&bc.GOARCH, "goarch", bc.GOARCH, "Go system architecture tag")
	flag.StringVar(&bc.GOOS, "goos", bc.GOOS, "Go operating system tag")
	flag.StringVar(&bc.GOPATH, "gopath", bc.GOPATH, "Go library path")
	flag.StringVar(&bc.GOROOT, "goroot", bc.GOROOT, "Go system root")
	flag.BoolVar(&bc.CgoEnabled, "gocgo", bc.CgoEnabled, "Whether to allow cgo")
	flag.StringVar(&bc.Compiler, "gocompiler", bc.Compiler, "Which Go compiler to use")
	flag.Var(&buildTags, "buildtags", "Comma-separated list of Go +build tags to enable during extraction.")

	// TODO(fromberger): Attach flags to the build and release tags (maybe).
}

func maybeFatal(msg string, args ...interface{}) {
	log.Printf(msg, args...)
	if !*keepGoing {
		os.Exit(1)
	}
}

func maybeLog(msg string, args ...interface{}) {
	if *verbose {
		log.Printf(msg, args...)
	}
}

func main() {
	flag.Parse()

	bc.BuildTags = buildTags

	if *outputPath == "" {
		log.Fatal("You must provide a non-empty --output path")
	}

	// Rules for rewriting package and file VNames.
	var rules vnameutil.Rules
	if *rulesFile != "" {
		var err error
		rules, err = vnameutil.LoadRules(*rulesFile)
		if err != nil {
			log.Fatalf("loading rules file: %v", err)
		}
	}

	ctx := context.Background()
	ext := &golang.Extractor{
		BuildContext: bc,

		PackageVNameOptions: golang.PackageVNameOptions{
			DefaultCorpus:             *corpus,
			Rules:                     rules,
			CanonicalizePackageCorpus: *canonicalizePackageCorpus,
		},
	}
	if *extraFiles != "" {
		ext.ExtraFiles = strings.Split(*extraFiles, ",")
		for i, path := range ext.ExtraFiles {
			var err error
			ext.ExtraFiles[i], err = filepath.Abs(path)
			if err != nil {
				log.Fatalf("Error finding absolute path of %s: %v", path, err)
			}
		}
	}

	locate := ext.Locate
	if *byDir {
		locate = func(path string) ([]*golang.Package, error) {
			pkg, err := ext.ImportDir(path)
			if err != nil {
				return nil, err
			}
			return []*golang.Package{pkg}, nil
		}
	}
	for _, path := range flag.Args() {
		pkgs, err := locate(path)
		if err != nil {
			maybeFatal("Error locating %q: %v", path, err)
		}
		for _, pkg := range pkgs {
			maybeLog("Found %q in %s", pkg.Path, pkg.BuildPackage.Dir)
		}
	}

	if err := ext.Extract(); err != nil {
		maybeFatal("Error in extraction: %v", err)
	}

	maybeLog("Writing %d package(s) to %q", len(ext.Packages), *outputPath)
	w, err := kzipWriter(ctx, *outputPath)
	if err != nil {
		maybeFatal("Error creating kzip writer: %v", err)
	}
	for _, pkg := range ext.Packages {
		maybeLog("Package %q:\n\t// %s", pkg.Path, pkg.BuildPackage.Doc)
		if err := pkg.EachUnit(ctx, func(cu *apb.CompilationUnit, fetcher analysis.Fetcher) error {
			if _, err := w.AddUnit(cu, nil); err != nil {
				return err
			}
			for _, ri := range cu.RequiredInput {
				fd, err := fetcher.Fetch(ri.Info.Path, ri.Info.Digest)
				if err != nil {
					return err
				}
				if _, err := w.AddFile(bytes.NewReader(fd)); err != nil {
					return err
				}
			}
			return nil
		}); err != nil {
			maybeFatal("Error writing %q: %v", pkg.Path, err)
		}
	}
	if err := w.Close(); err != nil {
		maybeFatal("Error closing output: %v", err)
	}
}

func kzipWriter(ctx context.Context, path string) (*kzip.Writer, error) {
	if err := vfs.MkdirAll(ctx, filepath.Dir(path), 0755); err != nil {
		log.Fatalf("Unable to create output directory: %v", err)
	}
	f, err := vfs.Create(ctx, path)
	if err != nil {
		log.Fatalf("Unable to create output file: %v", err)
	}
	return kzip.NewWriteCloser(f)
}
<commit_msg>chore: Fixup binary comment (#4367)<commit_after>/*
 * Copyright 2015 The Kythe Authors. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// Binary gotool extracts Kythe compilation information for Go packages named
// by import path on the command line.  The output compilations are written
// into a kzip.
package main

import (
	"bytes"
	"context"
	"flag"
	"fmt"
	"go/build"
	"log"
	"os"
	"path/filepath"
	"strings"

	"kythe.io/kythe/go/extractors/golang"
	"kythe.io/kythe/go/platform/analysis"
	"kythe.io/kythe/go/platform/kzip"
	"kythe.io/kythe/go/platform/vfs"
	"kythe.io/kythe/go/util/flagutil"
	"kythe.io/kythe/go/util/vnameutil"

	apb "kythe.io/kythe/proto/analysis_go_proto"
)

var (
	bc = build.Default // A shallow copy of the default build settings

	corpus     = flag.String("corpus", "", "Default corpus name to use")
	rulesFile  = flag.String("rules", "", "Path to vnames.json file that maps file paths to output corpus, root, and path.")
	outputPath = flag.String("output", "", "KZip output path")
	extraFiles = flag.String("extra_files", "", "Additional files to include in each compilation (CSV)")
	byDir      = flag.Bool("bydir", false, "Import by directory rather than import path")
	keepGoing  = flag.Bool("continue", false, "Continue past errors")
	verbose    = flag.Bool("v", false, "Enable verbose logging")

	canonicalizePackageCorpus = flag.Bool("canonicalize_package_corpus", false, "Whether to use a package's canonical repository root URL as their corpus")

	buildTags flagutil.StringList
)

func init() {
	flag.Usage = func() {
		fmt.Fprintf(os.Stderr, `Usage: %s [options] <import-path>...
Extract Kythe compilation records from Go import paths specified on the command line.
Output is written to a .kzip file specified by --output.

Options:
`, filepath.Base(os.Args[0]))
		flag.PrintDefaults()
	}

	// Attach flags to the various parts of the go/build context we are using.
	// These will override the system defaults from the environment.
	flag.StringVar(&bc.GOARCH, "goarch", bc.GOARCH, "Go system architecture tag")
	flag.StringVar(&bc.GOOS, "goos", bc.GOOS, "Go operating system tag")
	flag.StringVar(&bc.GOPATH, "gopath", bc.GOPATH, "Go library path")
	flag.StringVar(&bc.GOROOT, "goroot", bc.GOROOT, "Go system root")
	flag.BoolVar(&bc.CgoEnabled, "gocgo", bc.CgoEnabled, "Whether to allow cgo")
	flag.StringVar(&bc.Compiler, "gocompiler", bc.Compiler, "Which Go compiler to use")
	flag.Var(&buildTags, "buildtags", "Comma-separated list of Go +build tags to enable during extraction.")

	// TODO(fromberger): Attach flags to the build and release tags (maybe).
}

func maybeFatal(msg string, args ...interface{}) {
	log.Printf(msg, args...)
	if !*keepGoing {
		os.Exit(1)
	}
}

func maybeLog(msg string, args ...interface{}) {
	if *verbose {
		log.Printf(msg, args...)
	}
}

func main() {
	flag.Parse()

	bc.BuildTags = buildTags

	if *outputPath == "" {
		log.Fatal("You must provide a non-empty --output path")
	}

	// Rules for rewriting package and file VNames.
	var rules vnameutil.Rules
	if *rulesFile != "" {
		var err error
		rules, err = vnameutil.LoadRules(*rulesFile)
		if err != nil {
			log.Fatalf("loading rules file: %v", err)
		}
	}

	ctx := context.Background()
	ext := &golang.Extractor{
		BuildContext: bc,

		PackageVNameOptions: golang.PackageVNameOptions{
			DefaultCorpus:             *corpus,
			Rules:                     rules,
			CanonicalizePackageCorpus: *canonicalizePackageCorpus,
		},
	}
	if *extraFiles != "" {
		ext.ExtraFiles = strings.Split(*extraFiles, ",")
		for i, path := range ext.ExtraFiles {
			var err error
			ext.ExtraFiles[i], err = filepath.Abs(path)
			if err != nil {
				log.Fatalf("Error finding absolute path of %s: %v", path, err)
			}
		}
	}

	locate := ext.Locate
	if *byDir {
		locate = func(path string) ([]*golang.Package, error) {
			pkg, err := ext.ImportDir(path)
			if err != nil {
				return nil, err
			}
			return []*golang.Package{pkg}, nil
		}
	}
	for _, path := range flag.Args() {
		pkgs, err := locate(path)
		if err != nil {
			maybeFatal("Error locating %q: %v", path, err)
		}
		for _, pkg := range pkgs {
			maybeLog("Found %q in %s", pkg.Path, pkg.BuildPackage.Dir)
		}
	}

	if err := ext.Extract(); err != nil {
		maybeFatal("Error in extraction: %v", err)
	}

	maybeLog("Writing %d package(s) to %q", len(ext.Packages), *outputPath)
	w, err := kzipWriter(ctx, *outputPath)
	if err != nil {
		maybeFatal("Error creating kzip writer: %v", err)
	}
	for _, pkg := range ext.Packages {
		maybeLog("Package %q:\n\t// %s", pkg.Path, pkg.BuildPackage.Doc)
		if err := pkg.EachUnit(ctx, func(cu *apb.CompilationUnit, fetcher analysis.Fetcher) error {
			if _, err := w.AddUnit(cu, nil); err != nil {
				return err
			}
			for _, ri := range cu.RequiredInput {
				fd, err := fetcher.Fetch(ri.Info.Path, ri.Info.Digest)
				if err != nil {
					return err
				}
				if _, err := w.AddFile(bytes.NewReader(fd)); err != nil {
					return err
				}
			}
			return nil
		}); err != nil {
			maybeFatal("Error writing %q: %v", pkg.Path, err)
		}
	}
	if err := w.Close(); err != nil {
		maybeFatal("Error closing output: %v", err)
	}
}

func kzipWriter(ctx context.Context, path string) (*kzip.Writer, error) {
	if err := vfs.MkdirAll(ctx, filepath.Dir(path), 0755); err != nil {
		log.Fatalf("Unable to create output directory: %v", err)
	}
	f, err := vfs.Create(ctx, path)
	if err != nil {
		log.Fatalf("Unable to create output file: %v", err)
	}
	return kzip.NewWriteCloser(f)
}
<|endoftext|>


<commit_before>// Copyright 2012-2017 the u-root Authors. All rights reserved
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Ed is a simple line-oriented editor
//
// Synopsis:
//     dd
//
// Description:
//
// Options:
package main

import (
	"bufio"
	"flag"
	"io"
	"log"
	"os"
	"regexp"
)

type editorArg func(Editor) error

var (
	d                  = flag.Bool("d", false, "debug")
	debug              = func(s string, i ...interface{}) {}
	fail               = log.Printf
	f           Editor = &file{}
	num                = regexp.MustCompile("^[0-9][0-9]*")
	startsearch        = regexp.MustCompile("^/[^/]/")
	endsearch          = regexp.MustCompile("^,/[^/]/")
	editors            = map[string]func(...editorArg) (Editor, error){
		"text": NewTextEditor,
		"bin":  NewBinEditor,
	}
	fileType = flag.String("t", "text", "type of file")
)

func readerio(r io.Reader) editorArg {
	return func(f Editor) error {
		_, err := f.Read(r, 0, 0)
		return err
	}
}

func readFile(n string) editorArg {
	return func(f Editor) error {
		r, err := os.Open(n)
		if err != nil {
			return err
		}
		if _, err := f.Read(r, 0, 0); err != nil {
			return err
		}
		return nil
	}
}

func main() {
	var (
		args []editorArg
		err  error
	)

	flag.Parse()

	if *d {
		debug = log.Printf
	}

	e, ok := editors[*fileType]
	if !ok {
		flag.Usage()
	}

	if len(flag.Args()) == 1 {
		args = append(args, readFile(flag.Args()[0]))
	}

	ed, err := e(args...)
	if err != nil {
		log.Fatalf("%v", err)
	}

	// Now just eat the lines, and turn them into commands.
	// The format is a regular language.
	// [start][,end]command[rest of line]
	s := bufio.NewScanner(os.Stdin)

	for s.Scan() {
		if err := DoCommand(ed, s.Text()); err != nil {
			log.Printf(err.Error())
		}
	}
}
<commit_msg>Correct description and synopsis for ed<commit_after>// Copyright 2012-2017 the u-root Authors. All rights reserved
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// ED(1)               Unix Programmer's Manual                ED(1)
//
// NAME
//   ed - text editor
//
// SYNOPSIS
//   ed [ - ] [ -d ] [ name ]
//
// DESCRIPTION
//   Ed is the standard text editor.
//
// OPTIONS
package main

import (
	"bufio"
	"flag"
	"io"
	"log"
	"os"
	"regexp"
)

type editorArg func(Editor) error

var (
	d                  = flag.Bool("d", false, "debug")
	debug              = func(s string, i ...interface{}) {}
	fail               = log.Printf
	f           Editor = &file{}
	num                = regexp.MustCompile("^[0-9][0-9]*")
	startsearch        = regexp.MustCompile("^/[^/]/")
	endsearch          = regexp.MustCompile("^,/[^/]/")
	editors            = map[string]func(...editorArg) (Editor, error){
		"text": NewTextEditor,
		"bin":  NewBinEditor,
	}
	fileType = flag.String("t", "text", "type of file")
)

func readerio(r io.Reader) editorArg {
	return func(f Editor) error {
		_, err := f.Read(r, 0, 0)
		return err
	}
}

func readFile(n string) editorArg {
	return func(f Editor) error {
		r, err := os.Open(n)
		if err != nil {
			return err
		}
		if _, err := f.Read(r, 0, 0); err != nil {
			return err
		}
		return nil
	}
}

func main() {
	var (
		args []editorArg
		err  error
	)

	flag.Parse()

	if *d {
		debug = log.Printf
	}

	e, ok := editors[*fileType]
	if !ok {
		flag.Usage()
	}

	if len(flag.Args()) == 1 {
		args = append(args, readFile(flag.Args()[0]))
	}

	ed, err := e(args...)
	if err != nil {
		log.Fatalf("%v", err)
	}

	// Now just eat the lines, and turn them into commands.
	// The format is a regular language.
	// [start][,end]command[rest of line]
	s := bufio.NewScanner(os.Stdin)

	for s.Scan() {
		if err := DoCommand(ed, s.Text()); err != nil {
			log.Printf(err.Error())
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"testing"

	"github.com/kylelemons/go-rpcgen/examples/echo/echoservice"
)

var server = flag.String("server", "localhost:9999", "RPC server address")

func TestEcho(t *testing.T) {
	tests := []string{
		"this is a test",
		"woo, more tests\n",
		"",
	}

	go main()

	echo, err := echoservice.DialEchoService(*server)
	if err != nil {
		t.Fatalf("dial: %s", err)
	}

	for _, test := range tests {
		in := &echoservice.Payload{Message:&test}
		out := &echoservice.Payload{}
		if err := echo.Echo(in, out); err != nil {
			t.Fatalf("echo: %s", err)
		}
		if out.Message == nil {
			t.Fatalf("echo: no message returned")
		}
		if got, want := *out.Message, test; got != want {
			t.Errorf("echo(%q) = %q, want %q", test, got, want)
		}
	}
}
<commit_msg>Added flag.Parse just in case<commit_after>package main

import (
	"flag"
	"testing"

	"github.com/kylelemons/go-rpcgen/examples/echo/echoservice"
)

var server = flag.String("server", "localhost:9999", "RPC server address")

func TestEcho(t *testing.T) {
	flag.Parse()

	tests := []string{
		"this is a test",
		"woo, more tests\n",
		"",
	}

	go main()

	echo, err := echoservice.DialEchoService(*server)
	if err != nil {
		t.Fatalf("dial: %s", err)
	}

	for _, test := range tests {
		in := &echoservice.Payload{Message:&test}
		out := &echoservice.Payload{}
		if err := echo.Echo(in, out); err != nil {
			t.Fatalf("echo: %s", err)
		}
		if out.Message == nil {
			t.Fatalf("echo: no message returned")
		}
		if got, want := *out.Message, test; got != want {
			t.Errorf("echo(%q) = %q, want %q", test, got, want)
		}
	}
}
<|endoftext|>


<commit_before>package oauth2Utils

import (
	"encoding/base64"
	"github.com/RangelReale/osin"
	"github.com/astaxie/beego/context"
	"net/http"
	"strings"

	. "github.com/francoishill/goangi2/utils/cookieUtils"
)

const (
	cOSIN_ACCESS_OUTPUT_ACCESS_TOKEN_MAP_KEY         = "access_token"
	cSCOPE_ALL_SCCOPES_FOR_WEB_PASWORD_AUTHENTICATED = "all_web_pwd"
)

type StringPredicate func(string) bool

var OsinServerObject *osin.Server

type IExpectedUser interface {
	GetRands() string
	GetPassword() string
	GetId() int64
	IAmAUser()
}

type iAuthUserProvider interface {
	DoVerifyUser(userName, password string) (bool, IExpectedUser) //This can handle both login/register
}

func checkError(err error) {
	if err != nil {
		panic(err)
	}
}

func InjectCodeIntoFormIfWasPassedViaAuthorizationHeader(request *http.Request) {
	authorizationHeader := request.Header.Get("Authorization")
	accessTokenFromAuthHeader := ""
	if strings.HasPrefix(authorizationHeader, "Bearer ") {
		//This means if the "code" was set in the get/set form it will be overwritten if we use the Authorization header
		accessTokenFromAuthHeader = authorizationHeader[7:]
		request.ParseForm()
		request.Form.Set("code", accessTokenFromAuthHeader)
	}
}

func OverwriteOsinResponseErrorWithOwn(osinResponse *osin.Response) {
	errKey, ok := osinResponse.Output["error"].(string)
	if ok {
		if errKey == osin.E_INVALID_REQUEST {
			osinResponse.SetError(errKey, errorMapKeys[errKey])
		}
	}
}

func OverwriteOsinResponseErrorWithOwn_SpecifyErrorKey(osinResponse *osin.Response, errorKey string) {
	osinResponse.SetError(errorKey, errorMapKeys[errorKey])
}

func GetAuthorizedContextFromAccessToken(osinResponse *osin.Response, ctx *context.Context) *AuthorizedContext {
	InjectCodeIntoFormIfWasPassedViaAuthorizationHeader(ctx.Request)

	var usr IExpectedUser
	var castedToUserType bool

	ir := OsinServerObject.HandleInfoRequest(osinResponse, ctx.Request)
	if ir == nil {
		panic(createOsinAuthorizeError(E_INVALID_AUTH_DATA, errorMapKeys[E_INVALID_AUTH_DATA]))
	}

	if ir.AccessData.UserData == nil {
		panic(createOsinAuthorizeError(E_ACCESS_DATA_MISSING_USER, errorMapKeys[E_ACCESS_DATA_MISSING_USER]+"(1)"))
	}
	if strings.Trim(ir.AccessData.AccessToken, " ") == "" {
		panic(createOsinAuthorizeError(E_ACCESS_DATA_MISSING_USER, errorMapKeys[E_ACCESS_DATA_MISSING_USER]+"(2)"))
	}
	usr, castedToUserType = ir.AccessData.UserData.(IExpectedUser)
	if !castedToUserType {
		panic(createOsinAuthorizeError(E_ACCESS_DATA_MISSING_USER, errorMapKeys[E_ACCESS_DATA_MISSING_USER]+"(3)"))
	}

	return CreateAuthorizedContext(usr, ir.AccessData.Scope, ir.AccessData.AccessToken)
}

func CheckRequiredScopeSatisfied(responseWriter http.ResponseWriter, authorizedScope string, functionToCheckRequiredScope StringPredicate) {
	if authorizedScope == cSCOPE_ALL_SCCOPES_FOR_WEB_PASWORD_AUTHENTICATED {
		return
	}

	if !functionToCheckRequiredScope(authorizedScope) {
		panic(createOsinAuthorizeError(E_INSUFFICIENT_SCOPE, errorMapKeys[E_INSUFFICIENT_SCOPE]))
	}
}

func ServeAccessTokenWithRouter(ctx *context.Context) {
	w := ctx.ResponseWriter
	r := ctx.Request

	InjectCodeIntoFormIfWasPassedViaAuthorizationHeader(r)

	resp := OsinServerObject.NewResponse()
	defer resp.Close()

	if ir := OsinServerObject.HandleInfoRequest(resp, r); ir != nil {
		OsinServerObject.FinishInfoRequest(resp, r, ir)
	}

	if resp.IsError {
		OverwriteOsinResponseErrorWithOwn(resp)
	}
	osin.OutputJSON(resp, w, r)
}

func setExpirationForAccessRequest(accessRequest *osin.AccessRequest) {
	accessRequest.Expiration = 60 * 60 * 24 * 365 * 10 //Ten years
	//accessRequest.Expiration = 60 * 60 * 24 * 365 * 1 //One year
	// accessRequest.Expiration = 60 * 60 * 24 //One day
	//beego.Warning("Currently hardcoded the access token expiration to one year, is this correct?")
}

func ExtractAccessTokenFromSuccessfulResponseData(responseData osin.ResponseData) (string, bool) {
	if token, ok := responseData[cOSIN_ACCESS_OUTPUT_ACCESS_TOKEN_MAP_KEY]; ok {
		if stringToken, ok := token.(string); ok {
			return stringToken, true
		}
	}

	return "", false
}

type outputHandlerFunc func(ctx *context.Context) bool

func replaceHeadersInlineForWebClient(ctx *context.Context, cookieSecurityContext *CookieSecurityContext) {
	ctx.Request.Form.Del("client")

	basicAuthorizationToken := base64.StdEncoding.EncodeToString([]byte(cookieSecurityContext.WebOauth2ClientId + ":" + cookieSecurityContext.WebOauth2ClientSecret))
	ctx.Request.Header.Set("Authorization", "Basic "+basicAuthorizationToken)

	ctx.Request.Form.Set("grant_type", "password")
	ctx.Request.Form.Set("scope", cSCOPE_ALL_SCCOPES_FOR_WEB_PASWORD_AUTHENTICATED)
}

func AuthorizeAndServeNewAccessTokenWithRouter(ctx *context.Context, cookieSecurityContext *CookieSecurityContext, authUserProvider iAuthUserProvider, setCookies bool, successfulOutputHandler outputHandlerFunc) {
	resp := OsinServerObject.NewResponse()
	defer resp.Close()

	r := ctx.Request
	w := ctx.ResponseWriter

	isWebClient := ctx.Request.Form.Get("client") == "web"

	if isWebClient {
		replaceHeadersInlineForWebClient(ctx, cookieSecurityContext)
	}

	var userId int64

	ar := OsinServerObject.HandleAccessRequest(resp, r)
	if ar != nil {
		switch ar.Type {
		/*case osin.AUTHORIZATION_CODE:
		ar.Authorized = true*/
		case osin.REFRESH_TOKEN:
			ar.Authorized = true
			setExpirationForAccessRequest(ar)
		case osin.PASSWORD:
			var tmpUser IExpectedUser
			ar.Authorized, tmpUser = authUserProvider.DoVerifyUser(ar.Username, ar.Password)
			if !ar.Authorized {
				OverwriteOsinResponseErrorWithOwn_SpecifyErrorKey(resp, E_EMAIL_DOES_NOT_EXIST_OR_PASSWORD_INCORRECT)
			} else {
				ar.UserData = tmpUser
				userId = tmpUser.GetId()
			}
			setExpirationForAccessRequest(ar)

			/*case osin.CLIENT_CREDENTIALS:
			ar.Authorized = true*/
		}
		OsinServerObject.FinishAccessRequest(resp, r, ar)
	}

	if resp.IsError {
		if resp.InternalError != nil {
			OverwriteOsinResponseErrorWithOwn(resp)
		}

		resp.ErrorStatusCode = 401
		resp.StatusCode = 401
	} else {
		resp.Output["user_id"] = userId
		resp.Output["success"] = true
	}

	if setCookies && !resp.IsError {
		if accessToken, ok := ExtractAccessTokenFromSuccessfulResponseData(resp.Output); ok {
			if ar != nil && ar.UserData != nil {
				if usr, ok := ar.UserData.(IExpectedUser); ok {
					SetUserCookies(ctx, usr.GetId())
				}
			}

			SetEncryptedAccessTokenInCookie(ctx, accessToken)
		}
	}

	if successfulOutputHandler != nil {
		if handledOutput := successfulOutputHandler(ctx); handledOutput {
			return
		}
	}

	err := osin.OutputJSON(resp, w, r)
	checkError(err)
}

func InitOsinServerObject() {
	sconfig := osin.NewServerConfig()

	sconfig.AllowGetAccessRequest = false
	sconfig.AllowedAuthorizeTypes = osin.AllowedAuthorizeType{osin.CODE, osin.TOKEN}
	sconfig.AllowedAccessTypes = osin.AllowedAccessType{
		// osin.AUTHORIZATION_CODE,
		osin.REFRESH_TOKEN,
		osin.PASSWORD,
		// osin.CLIENT_CREDENTIALS,
	}
	OsinServerObject = osin.NewServer(sconfig, NewOAuth2Storage())
}
<commit_msg>Added default osin `sconfig.ErrorStatusCode = 401`.<commit_after>package oauth2Utils

import (
	"encoding/base64"
	"github.com/RangelReale/osin"
	"github.com/astaxie/beego/context"
	"net/http"
	"strings"

	. "github.com/francoishill/goangi2/utils/cookieUtils"
)

const (
	cOSIN_ACCESS_OUTPUT_ACCESS_TOKEN_MAP_KEY         = "access_token"
	cSCOPE_ALL_SCCOPES_FOR_WEB_PASWORD_AUTHENTICATED = "all_web_pwd"
)

type StringPredicate func(string) bool

var OsinServerObject *osin.Server

type IExpectedUser interface {
	GetRands() string
	GetPassword() string
	GetId() int64
	IAmAUser()
}

type iAuthUserProvider interface {
	DoVerifyUser(userName, password string) (bool, IExpectedUser) //This can handle both login/register
}

func checkError(err error) {
	if err != nil {
		panic(err)
	}
}

func InjectCodeIntoFormIfWasPassedViaAuthorizationHeader(request *http.Request) {
	authorizationHeader := request.Header.Get("Authorization")
	accessTokenFromAuthHeader := ""
	if strings.HasPrefix(authorizationHeader, "Bearer ") {
		//This means if the "code" was set in the get/set form it will be overwritten if we use the Authorization header
		accessTokenFromAuthHeader = authorizationHeader[7:]
		request.ParseForm()
		request.Form.Set("code", accessTokenFromAuthHeader)
	}
}

func OverwriteOsinResponseErrorWithOwn(osinResponse *osin.Response) {
	errKey, ok := osinResponse.Output["error"].(string)
	if ok {
		if errKey == osin.E_INVALID_REQUEST {
			osinResponse.SetError(errKey, errorMapKeys[errKey])
		}
	}
}

func OverwriteOsinResponseErrorWithOwn_SpecifyErrorKey(osinResponse *osin.Response, errorKey string) {
	osinResponse.SetError(errorKey, errorMapKeys[errorKey])
}

func GetAuthorizedContextFromAccessToken(osinResponse *osin.Response, ctx *context.Context) *AuthorizedContext {
	InjectCodeIntoFormIfWasPassedViaAuthorizationHeader(ctx.Request)

	var usr IExpectedUser
	var castedToUserType bool

	ir := OsinServerObject.HandleInfoRequest(osinResponse, ctx.Request)
	if ir == nil {
		panic(createOsinAuthorizeError(E_INVALID_AUTH_DATA, errorMapKeys[E_INVALID_AUTH_DATA]))
	}

	if ir.AccessData.UserData == nil {
		panic(createOsinAuthorizeError(E_ACCESS_DATA_MISSING_USER, errorMapKeys[E_ACCESS_DATA_MISSING_USER]+"(1)"))
	}
	if strings.Trim(ir.AccessData.AccessToken, " ") == "" {
		panic(createOsinAuthorizeError(E_ACCESS_DATA_MISSING_USER, errorMapKeys[E_ACCESS_DATA_MISSING_USER]+"(2)"))
	}
	usr, castedToUserType = ir.AccessData.UserData.(IExpectedUser)
	if !castedToUserType {
		panic(createOsinAuthorizeError(E_ACCESS_DATA_MISSING_USER, errorMapKeys[E_ACCESS_DATA_MISSING_USER]+"(3)"))
	}

	return CreateAuthorizedContext(usr, ir.AccessData.Scope, ir.AccessData.AccessToken)
}

func CheckRequiredScopeSatisfied(responseWriter http.ResponseWriter, authorizedScope string, functionToCheckRequiredScope StringPredicate) {
	if authorizedScope == cSCOPE_ALL_SCCOPES_FOR_WEB_PASWORD_AUTHENTICATED {
		return
	}

	if !functionToCheckRequiredScope(authorizedScope) {
		panic(createOsinAuthorizeError(E_INSUFFICIENT_SCOPE, errorMapKeys[E_INSUFFICIENT_SCOPE]))
	}
}

func ServeAccessTokenWithRouter(ctx *context.Context) {
	w := ctx.ResponseWriter
	r := ctx.Request

	InjectCodeIntoFormIfWasPassedViaAuthorizationHeader(r)

	resp := OsinServerObject.NewResponse()
	defer resp.Close()

	if ir := OsinServerObject.HandleInfoRequest(resp, r); ir != nil {
		OsinServerObject.FinishInfoRequest(resp, r, ir)
	}

	if resp.IsError {
		OverwriteOsinResponseErrorWithOwn(resp)
	}
	osin.OutputJSON(resp, w, r)
}

func setExpirationForAccessRequest(accessRequest *osin.AccessRequest) {
	accessRequest.Expiration = 60 * 60 * 24 * 365 * 10 //Ten years
	//accessRequest.Expiration = 60 * 60 * 24 * 365 * 1 //One year
	// accessRequest.Expiration = 60 * 60 * 24 //One day
	//beego.Warning("Currently hardcoded the access token expiration to one year, is this correct?")
}

func ExtractAccessTokenFromSuccessfulResponseData(responseData osin.ResponseData) (string, bool) {
	if token, ok := responseData[cOSIN_ACCESS_OUTPUT_ACCESS_TOKEN_MAP_KEY]; ok {
		if stringToken, ok := token.(string); ok {
			return stringToken, true
		}
	}

	return "", false
}

type outputHandlerFunc func(ctx *context.Context) bool

func replaceHeadersInlineForWebClient(ctx *context.Context, cookieSecurityContext *CookieSecurityContext) {
	ctx.Request.Form.Del("client")

	basicAuthorizationToken := base64.StdEncoding.EncodeToString([]byte(cookieSecurityContext.WebOauth2ClientId + ":" + cookieSecurityContext.WebOauth2ClientSecret))
	ctx.Request.Header.Set("Authorization", "Basic "+basicAuthorizationToken)

	ctx.Request.Form.Set("grant_type", "password")
	ctx.Request.Form.Set("scope", cSCOPE_ALL_SCCOPES_FOR_WEB_PASWORD_AUTHENTICATED)
}

func AuthorizeAndServeNewAccessTokenWithRouter(ctx *context.Context, cookieSecurityContext *CookieSecurityContext, authUserProvider iAuthUserProvider, setCookies bool, successfulOutputHandler outputHandlerFunc) {
	resp := OsinServerObject.NewResponse()
	defer resp.Close()

	r := ctx.Request
	w := ctx.ResponseWriter

	isWebClient := ctx.Request.Form.Get("client") == "web"

	if isWebClient {
		replaceHeadersInlineForWebClient(ctx, cookieSecurityContext)
	}

	var userId int64

	ar := OsinServerObject.HandleAccessRequest(resp, r)
	if ar != nil {
		switch ar.Type {
		/*case osin.AUTHORIZATION_CODE:
		ar.Authorized = true*/
		case osin.REFRESH_TOKEN:
			ar.Authorized = true
			setExpirationForAccessRequest(ar)
		case osin.PASSWORD:
			var tmpUser IExpectedUser
			ar.Authorized, tmpUser = authUserProvider.DoVerifyUser(ar.Username, ar.Password)
			if !ar.Authorized {
				OverwriteOsinResponseErrorWithOwn_SpecifyErrorKey(resp, E_EMAIL_DOES_NOT_EXIST_OR_PASSWORD_INCORRECT)
			} else {
				ar.UserData = tmpUser
				userId = tmpUser.GetId()
			}
			setExpirationForAccessRequest(ar)

			/*case osin.CLIENT_CREDENTIALS:
			ar.Authorized = true*/
		}
		OsinServerObject.FinishAccessRequest(resp, r, ar)
	}

	if resp.IsError {
		if resp.InternalError != nil {
			OverwriteOsinResponseErrorWithOwn(resp)
		}

		resp.ErrorStatusCode = 401
		resp.StatusCode = 401
	} else {
		resp.Output["user_id"] = userId
		resp.Output["success"] = true
	}

	if setCookies && !resp.IsError {
		if accessToken, ok := ExtractAccessTokenFromSuccessfulResponseData(resp.Output); ok {
			if ar != nil && ar.UserData != nil {
				if usr, ok := ar.UserData.(IExpectedUser); ok {
					SetUserCookies(ctx, usr.GetId())
				}
			}

			SetEncryptedAccessTokenInCookie(ctx, accessToken)
		}
	}

	if successfulOutputHandler != nil {
		if handledOutput := successfulOutputHandler(ctx); handledOutput {
			return
		}
	}

	err := osin.OutputJSON(resp, w, r)
	checkError(err)
}

func InitOsinServerObject() {
	sconfig := osin.NewServerConfig()

	sconfig.AllowGetAccessRequest = false
	sconfig.AllowedAuthorizeTypes = osin.AllowedAuthorizeType{osin.CODE, osin.TOKEN}
	sconfig.AllowedAccessTypes = osin.AllowedAccessType{
		// osin.AUTHORIZATION_CODE,
		osin.REFRESH_TOKEN,
		osin.PASSWORD,
		// osin.CLIENT_CREDENTIALS,
	}
	sconfig.ErrorStatusCode = 401
	OsinServerObject = osin.NewServer(sconfig, NewOAuth2Storage())
}
<|endoftext|>