<commit_before>package trie

import (
	"fmt"
	"strings"

	"github.com/philharnish/forge/src/data/graph/bloom/mask"
	"github.com/philharnish/forge/src/data/graph/bloom/node"
	"github.com/philharnish/forge/src/data/graph/bloom/weight"
)

// Trie with bloom-filter style optimizations.
type Trie struct {
	*node.Node
	links []trieLink
}

type trieLink struct {
	prefix string
	node   *Trie
}

func NewTrie(matchWeight ...weight.Weight) *Trie {
	return &Trie{
		Node:  node.NewNode(matchWeight...),
		links: nil,
	}
}

func (trie *Trie) Root() *node.Node {
	return trie.Node
}

func (trie *Trie) Items(acceptor node.NodeAcceptor) node.NodeItems {
	return newTrieItems(acceptor, trie)
}

func (trie *Trie) Link(path string, child *Trie) error {
	if len(path) == 0 {
		return fmt.Errorf("attempted to link empty key")
	}
	edgeMask, runeLength, err := mask.EdgeMaskAndLength(path)
	if err != nil {
		return fmt.Errorf("error while linking: %w", err)
	}
	// Inherit maxWeight.
	trie.Weight(child.MaxWeight)
	// Provide anything ANY children provides (including the edge itself).
	trie.ProvideMask |= edgeMask | mask.Mask(child.ProvideMask)
	if child.RequireMask == mask.UNSET {
		// Ignore the child's require mask if it is UNSET.
		trie.RequireMask &= edgeMask
	} else {
		// Require anything ALL children requires (including the edge itself).
		trie.RequireMask &= edgeMask | mask.Mask(child.RequireMask)
	}
	// Inherit matching lengths.
	trie.LengthsMask |= child.LengthsMask << runeLength
	link := trieLink{
		path,
		child,
	}
	// Optimized path for first link.
	if trie.links == nil {
		trie.links = []trieLink{
			link,
		}
		return nil
	}
	// append(...) will ensure there is room for all (old+new) links.
	trie.links = append(trie.links, link)
	// Scan links to validate they are in sorted order and there are no duplicates.
	links := trie.links
	for second := len(links) - 1; second > 0; second-- {
		first := second - 1
		if links[first].prefix[0] == links[second].prefix[0] {
			if trie.links[first].prefix == links[second].prefix {
				// Proposed link already exists.
				return fmt.Errorf("link '%s' already exists", path)
			}
			// Attempt to reuse link.
			return fmt.Errorf("splitting an existing link is currently unsupported")
		}
		if links[second].node.MaxWeight > links[first].node.MaxWeight {
			// The second node is better than first; swap.
			links[first], links[second] = links[second], links[first]
		}
	}
	return nil
}

func (trie *Trie) Get(path string) *Trie {
	child, remaining := trie.seek(path, nil)
	if remaining == "" {
		return child
	}
	return nil
}

func (trie *Trie) Add(path string, matchWeight weight.Weight) error {
	runes := []rune(path)
	edgeMasks, err := mask.AlphabetMasks(runes)
	if err != nil {
		return err
	}
	if len(edgeMasks) != len(path) {
		return fmt.Errorf("unicode paths are unsupported")
	}
	parent, remaining := trie.seek(path, edgeMasks)
	if remaining == "" {
		return fmt.Errorf("node %s already exists at '%s'", parent.String(), path)
	}
	return parent.Link(remaining, NewTrie(matchWeight))
}

func (trie *Trie) seek(path string, provideMasks []mask.Mask) (child *Trie, remaining string) {
	for _, link := range trie.links {
		if path == link.prefix {
			return link.node, ""
		} else if strings.HasPrefix(path, link.prefix) {
			remainingPath := path[len(link.prefix):]
			if provideMasks != nil {
				trie.Node.LengthsMask |= mask.Mask(1 << len(provideMasks))
				for i, _ := range link.prefix {
					trie.Node.ProvideMask |= provideMasks[i]
				}
				provideMasks = provideMasks[len(link.prefix):]
			}
			return link.node.seek(remainingPath, provideMasks)
		}
	}
	return trie, path
}

func (trie *Trie) Satisfies(other *Trie) bool {
	return other.RequireMask&trie.ProvideMask == other.RequireMask &&
		trie.LengthsMask&other.LengthsMask > 0
}

func (trie *Trie) String() string {
	return node.Format("Trie", trie.Node)
}
<commit_msg>Simplify "i, _ := range" expression.<commit_after>package trie

import (
	"fmt"
	"strings"

	"github.com/philharnish/forge/src/data/graph/bloom/mask"
	"github.com/philharnish/forge/src/data/graph/bloom/node"
	"github.com/philharnish/forge/src/data/graph/bloom/weight"
)

// Trie with bloom-filter style optimizations.
type Trie struct {
	*node.Node
	links []trieLink
}

type trieLink struct {
	prefix string
	node   *Trie
}

func NewTrie(matchWeight ...weight.Weight) *Trie {
	return &Trie{
		Node:  node.NewNode(matchWeight...),
		links: nil,
	}
}

func (trie *Trie) Root() *node.Node {
	return trie.Node
}

func (trie *Trie) Items(acceptor node.NodeAcceptor) node.NodeItems {
	return newTrieItems(acceptor, trie)
}

func (trie *Trie) Link(path string, child *Trie) error {
	if len(path) == 0 {
		return fmt.Errorf("attempted to link empty key")
	}
	edgeMask, runeLength, err := mask.EdgeMaskAndLength(path)
	if err != nil {
		return fmt.Errorf("error while linking: %w", err)
	}
	// Inherit maxWeight.
	trie.Weight(child.MaxWeight)
	// Provide anything ANY children provides (including the edge itself).
	trie.ProvideMask |= edgeMask | mask.Mask(child.ProvideMask)
	if child.RequireMask == mask.UNSET {
		// Ignore the child's require mask if it is UNSET.
		trie.RequireMask &= edgeMask
	} else {
		// Require anything ALL children requires (including the edge itself).
		trie.RequireMask &= edgeMask | mask.Mask(child.RequireMask)
	}
	// Inherit matching lengths.
	trie.LengthsMask |= child.LengthsMask << runeLength
	link := trieLink{
		path,
		child,
	}
	// Optimized path for first link.
	if trie.links == nil {
		trie.links = []trieLink{
			link,
		}
		return nil
	}
	// append(...) will ensure there is room for all (old+new) links.
	trie.links = append(trie.links, link)
	// Scan links to validate they are in sorted order and there are no duplicates.
	links := trie.links
	for second := len(links) - 1; second > 0; second-- {
		first := second - 1
		if links[first].prefix[0] == links[second].prefix[0] {
			if trie.links[first].prefix == links[second].prefix {
				// Proposed link already exists.
				return fmt.Errorf("link '%s' already exists", path)
			}
			// Attempt to reuse link.
			return fmt.Errorf("splitting an existing link is currently unsupported")
		}
		if links[second].node.MaxWeight > links[first].node.MaxWeight {
			// The second node is better than first; swap.
			links[first], links[second] = links[second], links[first]
		}
	}
	return nil
}

func (trie *Trie) Get(path string) *Trie {
	child, remaining := trie.seek(path, nil)
	if remaining == "" {
		return child
	}
	return nil
}

func (trie *Trie) Add(path string, matchWeight weight.Weight) error {
	runes := []rune(path)
	edgeMasks, err := mask.AlphabetMasks(runes)
	if err != nil {
		return err
	}
	if len(edgeMasks) != len(path) {
		return fmt.Errorf("unicode paths are unsupported")
	}
	parent, remaining := trie.seek(path, edgeMasks)
	if remaining == "" {
		return fmt.Errorf("node %s already exists at '%s'", parent.String(), path)
	}
	return parent.Link(remaining, NewTrie(matchWeight))
}

func (trie *Trie) seek(path string, provideMasks []mask.Mask) (child *Trie, remaining string) {
	for _, link := range trie.links {
		if path == link.prefix {
			return link.node, ""
		} else if strings.HasPrefix(path, link.prefix) {
			remainingPath := path[len(link.prefix):]
			if provideMasks != nil {
				trie.Node.LengthsMask |= mask.Mask(1 << len(provideMasks))
				for i := range link.prefix {
					trie.Node.ProvideMask |= provideMasks[i]
				}
				provideMasks = provideMasks[len(link.prefix):]
			}
			return link.node.seek(remainingPath, provideMasks)
		}
	}
	return trie, path
}

func (trie *Trie) Satisfies(other *Trie) bool {
	return other.RequireMask&trie.ProvideMask == other.RequireMask &&
		trie.LengthsMask&other.LengthsMask > 0
}

func (trie *Trie) String() string {
	return node.Format("Trie", trie.Node)
}
<|endoftext|>


<commit_before>package common

import (
	"fmt"
	"github.com/mitchellh/goamz/ec2"
	"github.com/mitchellh/multistep"
	"github.com/mitchellh/packer/packer"
)

type StepModifyAttributes struct {
	Users        []string
	Groups       []string
	ProductCodes []string
	Description  string
}

func (s *StepModifyAttributes) Run(state map[string]interface{}) multistep.StepAction {
	ec2conn := state["ec2"].(*ec2.EC2)
	ui := state["ui"].(packer.Ui)
	amis := state["amis"].(map[string]string)
	ami := amis[ec2conn.Region.Name]

	options := &ec2.ModifyImageAttribute{
		Description:  s.Description,
		AddUsers:     s.Users,
		AddGroups:    s.Groups,
		ProductCodes: s.ProductCodes,
	}

	ui.Say("Modifying AMI attributes...")
	_, err := ec2conn.ModifyImageAttribute(ami, options)
	if err != nil {
		err := fmt.Errorf("Error modify AMI attributes: %s", err)
		state["error"] = err
		ui.Error(err.Error())
		return multistep.ActionHalt
	}

	return multistep.ActionContinue
}

func (s *StepModifyAttributes) Cleanup(state map[string]interface{}) {
	// No cleanup...
}
<commit_msg>builder/amazon/common: on modify AMI attributes, skip if no work<commit_after>package common

import (
	"fmt"
	"github.com/mitchellh/goamz/ec2"
	"github.com/mitchellh/multistep"
	"github.com/mitchellh/packer/packer"
)

type StepModifyAttributes struct {
	Users        []string
	Groups       []string
	ProductCodes []string
	Description  string
}

func (s *StepModifyAttributes) Run(state map[string]interface{}) multistep.StepAction {
	ec2conn := state["ec2"].(*ec2.EC2)
	ui := state["ui"].(packer.Ui)
	amis := state["amis"].(map[string]string)
	ami := amis[ec2conn.Region.Name]

	// Determine if there is any work to do.
	valid := false
	valid = valid || s.Description != ""
	valid = valid || (s.Users != nil && len(s.Users) > 0)
	valid = valid || (s.Groups != nil && len(s.Groups) > 0)
	valid = valid || (s.ProductCodes != nil && len(s.ProductCodes) > 0)

	if !valid {
		return multistep.ActionContinue
	}

	options := &ec2.ModifyImageAttribute{
		Description:  s.Description,
		AddUsers:     s.Users,
		AddGroups:    s.Groups,
		ProductCodes: s.ProductCodes,
	}

	ui.Say("Modifying AMI attributes...")
	_, err := ec2conn.ModifyImageAttribute(ami, options)
	if err != nil {
		err := fmt.Errorf("Error modify AMI attributes: %s", err)
		state["error"] = err
		ui.Error(err.Error())
		return multistep.ActionHalt
	}

	return multistep.ActionContinue
}

func (s *StepModifyAttributes) Cleanup(state map[string]interface{}) {
	// No cleanup...
}
<|endoftext|>


<commit_before>// +build integration

/*
 * 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 tests

import (
	"testing"
	"github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/common"
	"github.com/stretchr/testify/assert"
	"os"
	"fmt"
)

var wskprops = common.GetWskprops()

func TestCloudant(t *testing.T) {
	wskprops := common.GetWskpropsFromEnvVars(common.BLUEMIX_APIHOST, common.BLUEMIX_NAMESPACE, common.BLUEMIX_AUTH)
	err := common.ValidateWskprops(wskprops)
	if err != nil {
		fmt.Println(err.Error())
		fmt.Println("Wsk properties are not properly configured, so tests are skipped.")
	} else {
		wskdeploy := common.NewWskdeploy()
		_, err := wskdeploy.DeployWithCredentials(manifestPath, deploymentPath, wskprops)
		assert.Equal(t, nil, err, "Failed to deploy the manifest file.")
		_, err = wskdeploy.UndeployWithCredentials(manifestPath, deploymentPath, wskprops)
		assert.Equal(t, nil, err, "Failed to undeploy the manifest file.")
	}
}

var (
	manifestPath = os.Getenv("GOPATH") + "/src/github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/cloudant/manifest.yml"
	deploymentPath = ""
)

<commit_msg>Correct the path of manifest.yaml for cloudant integration test (#525)<commit_after>// +build integration

/*
 * 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 tests

import (
	"testing"
	"github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/common"
	"github.com/stretchr/testify/assert"
	"os"
	"fmt"
)

func TestCloudant(t *testing.T) {
	wskprops := common.GetWskpropsFromEnvVars(common.BLUEMIX_APIHOST, common.BLUEMIX_NAMESPACE, common.BLUEMIX_AUTH)
	err := common.ValidateWskprops(wskprops)
	if err != nil {
		fmt.Println(err.Error())
		fmt.Println("Wsk properties are not properly configured, so tests are skipped.")
	} else {
		wskdeploy := common.NewWskdeploy()
		_, err := wskdeploy.DeployWithCredentials(manifestPath, deploymentPath, wskprops)
		assert.Equal(t, nil, err, "Failed to deploy the manifest file.")
		_, err = wskdeploy.UndeployWithCredentials(manifestPath, deploymentPath, wskprops)
		assert.Equal(t, nil, err, "Failed to undeploy the manifest file.")
	}
}

var (
	manifestPath = os.Getenv("GOPATH") + "/src/github.com/apache/incubator-openwhisk-wskdeploy/tests/src/integration/cloudant/manifest.yaml"
	deploymentPath = ""
)

<|endoftext|>


<commit_before>// Copyright 2019 Istio Authors
//
// 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 trustdomain

import (
	"reflect"
	"testing"
)

func TestReplaceTrustDomainAliases(t *testing.T) {
	testCases := []struct {
		name              string
		trustDomainBundle Bundle
		principals        []string
		expect            []string
	}{
		{
			name:              "No trust domain aliases (no change in trust domain)",
			trustDomainBundle: NewTrustDomainBundle("cluster.local", nil),
			principals:        []string{"cluster.local/ns/foo/sa/bar"},
			expect:            []string{"cluster.local/ns/foo/sa/bar"},
		},
		{
			name:              "Principal with *",
			trustDomainBundle: NewTrustDomainBundle("cluster.local", nil),
			principals:        []string{"*"},
			expect:            []string{"*"},
		},
		{
			name:              "Principal with * prefix",
			trustDomainBundle: NewTrustDomainBundle("cluster.local", nil),
			principals:        []string{"*/ns/foo/sa/bar"},
			expect:            []string{"*/ns/foo/sa/bar"},
		},
		{
			name:              "One trust domain alias, one principal",
			trustDomainBundle: NewTrustDomainBundle("td2", []string{"td1"}),
			principals:        []string{"td1/ns/foo/sa/bar"},
			expect:            []string{"td2/ns/foo/sa/bar", "td1/ns/foo/sa/bar"},
		},
		{
			name:              "One trust domain alias, two principals",
			trustDomainBundle: NewTrustDomainBundle("td1", []string{"cluster.local"}),
			principals:        []string{"cluster.local/ns/foo/sa/bar", "cluster.local/ns/yyy/sa/zzz"},
			expect:            []string{"td1/ns/foo/sa/bar", "cluster.local/ns/foo/sa/bar", "td1/ns/yyy/sa/zzz", "cluster.local/ns/yyy/sa/zzz"},
		},
		{
			name:              "One trust domain alias, principals with * as-is",
			trustDomainBundle: NewTrustDomainBundle("td1", []string{"cluster.local"}),
			principals:        []string{"*/ns/foo/sa/bar", "*sa/zzz", "*"},
			expect:            []string{"*/ns/foo/sa/bar", "*sa/zzz", "*"},
		},
		{
			name:              "Two trust domain aliases, two principals",
			trustDomainBundle: NewTrustDomainBundle("td2", []string{"td1", "cluster.local"}),
			principals:        []string{"cluster.local/ns/foo/sa/bar", "td1/ns/yyy/sa/zzz"},
			expect: []string{"td2/ns/foo/sa/bar", "td1/ns/foo/sa/bar", "cluster.local/ns/foo/sa/bar",
				"td2/ns/yyy/sa/zzz", "td1/ns/yyy/sa/zzz", "cluster.local/ns/yyy/sa/zzz"},
		},
		{
			name:              "Two trust domain aliases with * prefix in trust domain",
			trustDomainBundle: NewTrustDomainBundle("td2", []string{"foo-td1", "cluster.local"}),
			principals:        []string{"*-td1/ns/foo/sa/bar"},
			expect:            []string{"td2/ns/foo/sa/bar", "*-td1/ns/foo/sa/bar", "cluster.local/ns/foo/sa/bar"},
		},
		{
			name:              "Principals not match any trust domains",
			trustDomainBundle: NewTrustDomainBundle("td1", []string{"td2"}),
			principals:        []string{"some-td/ns/foo/sa/bar"},
			expect:            []string{"some-td/ns/foo/sa/bar"},
		},
		{
			name:              "Principals match one alias",
			trustDomainBundle: NewTrustDomainBundle("td1", []string{"td2", "some-td"}),
			principals:        []string{"some-td/ns/foo/sa/bar"},
			expect:            []string{"td1/ns/foo/sa/bar", "td2/ns/foo/sa/bar", "some-td/ns/foo/sa/bar"},
		},
		{
			name:              "One principal match one alias",
			trustDomainBundle: NewTrustDomainBundle("new-td", []string{"td2", "td3"}),
			principals:        []string{"td1/ns/some-ns/sa/some-sa", "td2/ns/foo/sa/bar"},
			expect: []string{"td1/ns/some-ns/sa/some-sa", "new-td/ns/foo/sa/bar",
				"td2/ns/foo/sa/bar", "td3/ns/foo/sa/bar"},
		},
		{
			name:              "Trust domain is empty string",
			trustDomainBundle: NewTrustDomainBundle("new-td", []string{"td2", "td3"}),
			principals:        []string{"/ns/some-ns/sa/some-sa"},
			expect:            []string{"/ns/some-ns/sa/some-sa"},
		},
		{
			name:              "No duplicated principals for prefix",
			trustDomainBundle: NewTrustDomainBundle("new-td", []string{"old-td"}),
			principals:        []string{"*-td/ns/some-ns/sa/some-sa"},
			// Rather than output *-td/ns/some-ns/sa/some-sa once for each trust domain.
			expect:            []string{"*-td/ns/some-ns/sa/some-sa"},
		},
	}

	for _, tc := range testCases {
		got := tc.trustDomainBundle.ReplaceTrustDomainAliases(tc.principals)
		if !reflect.DeepEqual(got, tc.expect) {
			t.Errorf("%s failed. Expect: %s. Got: %s", tc.name, tc.expect, got)
		}
	}
}

func TestReplaceTrustDomainInPrincipal(t *testing.T) {
	cases := []struct {
		trustDomainIn string
		principal     string
		out           string
	}{
		{principal: "spiffe://cluster.local/ns/foo/sa/bar", out: ""},
		{principal: "sa/test-sa/ns/default", out: ""},
		{trustDomainIn: "td", principal: "cluster.local/ns/foo/sa/bar", out: "td/ns/foo/sa/bar"},
		{trustDomainIn: "abc", principal: "xyz/ns/foo/sa/bar", out: "abc/ns/foo/sa/bar"},
	}

	for _, c := range cases {
		got := replaceTrustDomainInPrincipal(c.trustDomainIn, c.principal)
		if got != c.out {
			t.Errorf("expect %s, but got %s", c.out, got)
		}
	}
}

func TestGetTrustDomainFromSpiffeIdentity(t *testing.T) {
	cases := []struct {
		principal string
		out       string
	}{
		{principal: "spiffe://cluster.local/ns/foo/sa/bar", out: ""},
		{principal: "sa/test-sa/ns/default", out: ""},
		{principal: "cluster.local/ns/foo/sa/bar", out: "cluster.local"},
		{principal: "xyz/ns/foo/sa/bar", out: "xyz"},
	}

	for _, c := range cases {
		got, _ := getTrustDomainFromSpiffeIdentity(c.principal)
		if got != c.out {
			t.Errorf("expect %s, but got %s", c.out, got)
		}
	}
}

func TestIsTrustDomainBeingEnforced(t *testing.T) {
	cases := []struct {
		principal string
		want      bool
	}{
		{principal: "cluster.local/ns/foo/sa/bar", want: true},
		{principal: "*/ns/foo/sa/bar", want: false},
		{principal: "*-td/ns/foo/sa/bar", want: true},
		{principal: "*/sa/bar", want: false},
		{principal: "*", want: false},
		{principal: "/ns/foo/sa/bar", want: true},
	}

	for _, c := range cases {
		got := isTrustDomainBeingEnforced(c.principal)
		if got != c.want {
			t.Errorf("expect %v, but got %v", c.want, got)
		}
	}
}
<commit_msg>Run go format (#18572)<commit_after>// Copyright 2019 Istio Authors
//
// 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 trustdomain

import (
	"reflect"
	"testing"
)

func TestReplaceTrustDomainAliases(t *testing.T) {
	testCases := []struct {
		name              string
		trustDomainBundle Bundle
		principals        []string
		expect            []string
	}{
		{
			name:              "No trust domain aliases (no change in trust domain)",
			trustDomainBundle: NewTrustDomainBundle("cluster.local", nil),
			principals:        []string{"cluster.local/ns/foo/sa/bar"},
			expect:            []string{"cluster.local/ns/foo/sa/bar"},
		},
		{
			name:              "Principal with *",
			trustDomainBundle: NewTrustDomainBundle("cluster.local", nil),
			principals:        []string{"*"},
			expect:            []string{"*"},
		},
		{
			name:              "Principal with * prefix",
			trustDomainBundle: NewTrustDomainBundle("cluster.local", nil),
			principals:        []string{"*/ns/foo/sa/bar"},
			expect:            []string{"*/ns/foo/sa/bar"},
		},
		{
			name:              "One trust domain alias, one principal",
			trustDomainBundle: NewTrustDomainBundle("td2", []string{"td1"}),
			principals:        []string{"td1/ns/foo/sa/bar"},
			expect:            []string{"td2/ns/foo/sa/bar", "td1/ns/foo/sa/bar"},
		},
		{
			name:              "One trust domain alias, two principals",
			trustDomainBundle: NewTrustDomainBundle("td1", []string{"cluster.local"}),
			principals:        []string{"cluster.local/ns/foo/sa/bar", "cluster.local/ns/yyy/sa/zzz"},
			expect:            []string{"td1/ns/foo/sa/bar", "cluster.local/ns/foo/sa/bar", "td1/ns/yyy/sa/zzz", "cluster.local/ns/yyy/sa/zzz"},
		},
		{
			name:              "One trust domain alias, principals with * as-is",
			trustDomainBundle: NewTrustDomainBundle("td1", []string{"cluster.local"}),
			principals:        []string{"*/ns/foo/sa/bar", "*sa/zzz", "*"},
			expect:            []string{"*/ns/foo/sa/bar", "*sa/zzz", "*"},
		},
		{
			name:              "Two trust domain aliases, two principals",
			trustDomainBundle: NewTrustDomainBundle("td2", []string{"td1", "cluster.local"}),
			principals:        []string{"cluster.local/ns/foo/sa/bar", "td1/ns/yyy/sa/zzz"},
			expect: []string{"td2/ns/foo/sa/bar", "td1/ns/foo/sa/bar", "cluster.local/ns/foo/sa/bar",
				"td2/ns/yyy/sa/zzz", "td1/ns/yyy/sa/zzz", "cluster.local/ns/yyy/sa/zzz"},
		},
		{
			name:              "Two trust domain aliases with * prefix in trust domain",
			trustDomainBundle: NewTrustDomainBundle("td2", []string{"foo-td1", "cluster.local"}),
			principals:        []string{"*-td1/ns/foo/sa/bar"},
			expect:            []string{"td2/ns/foo/sa/bar", "*-td1/ns/foo/sa/bar", "cluster.local/ns/foo/sa/bar"},
		},
		{
			name:              "Principals not match any trust domains",
			trustDomainBundle: NewTrustDomainBundle("td1", []string{"td2"}),
			principals:        []string{"some-td/ns/foo/sa/bar"},
			expect:            []string{"some-td/ns/foo/sa/bar"},
		},
		{
			name:              "Principals match one alias",
			trustDomainBundle: NewTrustDomainBundle("td1", []string{"td2", "some-td"}),
			principals:        []string{"some-td/ns/foo/sa/bar"},
			expect:            []string{"td1/ns/foo/sa/bar", "td2/ns/foo/sa/bar", "some-td/ns/foo/sa/bar"},
		},
		{
			name:              "One principal match one alias",
			trustDomainBundle: NewTrustDomainBundle("new-td", []string{"td2", "td3"}),
			principals:        []string{"td1/ns/some-ns/sa/some-sa", "td2/ns/foo/sa/bar"},
			expect: []string{"td1/ns/some-ns/sa/some-sa", "new-td/ns/foo/sa/bar",
				"td2/ns/foo/sa/bar", "td3/ns/foo/sa/bar"},
		},
		{
			name:              "Trust domain is empty string",
			trustDomainBundle: NewTrustDomainBundle("new-td", []string{"td2", "td3"}),
			principals:        []string{"/ns/some-ns/sa/some-sa"},
			expect:            []string{"/ns/some-ns/sa/some-sa"},
		},
		{
			name:              "No duplicated principals for prefix",
			trustDomainBundle: NewTrustDomainBundle("new-td", []string{"old-td"}),
			principals:        []string{"*-td/ns/some-ns/sa/some-sa"},
			// Rather than output *-td/ns/some-ns/sa/some-sa once for each trust domain.
			expect: []string{"*-td/ns/some-ns/sa/some-sa"},
		},
	}

	for _, tc := range testCases {
		got := tc.trustDomainBundle.ReplaceTrustDomainAliases(tc.principals)
		if !reflect.DeepEqual(got, tc.expect) {
			t.Errorf("%s failed. Expect: %s. Got: %s", tc.name, tc.expect, got)
		}
	}
}

func TestReplaceTrustDomainInPrincipal(t *testing.T) {
	cases := []struct {
		trustDomainIn string
		principal     string
		out           string
	}{
		{principal: "spiffe://cluster.local/ns/foo/sa/bar", out: ""},
		{principal: "sa/test-sa/ns/default", out: ""},
		{trustDomainIn: "td", principal: "cluster.local/ns/foo/sa/bar", out: "td/ns/foo/sa/bar"},
		{trustDomainIn: "abc", principal: "xyz/ns/foo/sa/bar", out: "abc/ns/foo/sa/bar"},
	}

	for _, c := range cases {
		got := replaceTrustDomainInPrincipal(c.trustDomainIn, c.principal)
		if got != c.out {
			t.Errorf("expect %s, but got %s", c.out, got)
		}
	}
}

func TestGetTrustDomainFromSpiffeIdentity(t *testing.T) {
	cases := []struct {
		principal string
		out       string
	}{
		{principal: "spiffe://cluster.local/ns/foo/sa/bar", out: ""},
		{principal: "sa/test-sa/ns/default", out: ""},
		{principal: "cluster.local/ns/foo/sa/bar", out: "cluster.local"},
		{principal: "xyz/ns/foo/sa/bar", out: "xyz"},
	}

	for _, c := range cases {
		got, _ := getTrustDomainFromSpiffeIdentity(c.principal)
		if got != c.out {
			t.Errorf("expect %s, but got %s", c.out, got)
		}
	}
}

func TestIsTrustDomainBeingEnforced(t *testing.T) {
	cases := []struct {
		principal string
		want      bool
	}{
		{principal: "cluster.local/ns/foo/sa/bar", want: true},
		{principal: "*/ns/foo/sa/bar", want: false},
		{principal: "*-td/ns/foo/sa/bar", want: true},
		{principal: "*/sa/bar", want: false},
		{principal: "*", want: false},
		{principal: "/ns/foo/sa/bar", want: true},
	}

	for _, c := range cases {
		got := isTrustDomainBeingEnforced(c.principal)
		if got != c.want {
			t.Errorf("expect %v, but got %v", c.want, got)
		}
	}
}
<|endoftext|>


<commit_before>package controllers

import (
    "database/sql"
    "encoding/json"
    "fmt"
    "github.com/orc/db"
    "github.com/orc/sessions"
    "github.com/orc/utils"
    "html/template"
    // "log"
    "math"
    "net/http"
    "strconv"
    "strings"
)

func (c *BaseController) GridHandler() *GridHandler {
    return new(GridHandler)
}

type GridHandler struct {
    Controller
}

func (this *GridHandler) GetSubTable() {
    if !sessions.CheackSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        return
    }

    request, err := utils.ParseJS(this.Request, this.Response)
    if err != nil {
        utils.SendJSReply(err.Error(), this.Response)
        return
    }

    model := GetModel(request["table"].(string))
    index, _ := strconv.Atoi(request["index"].(string))
    subModel := GetModel(model.GetSubTable(index))
    subModel.LoadWherePart(map[string]interface{}{model.GetSubField(): request["id"]})
    result := db.Select(subModel, subModel.GetColumns() )
    refFields, refData := GetModelRefDate(subModel)

    response, err := json.Marshal(map[string]interface{}{
        "data":      result,
        "name":      subModel.GetTableName(),
        "caption":   subModel.GetCaption(),
        "colnames":  subModel.GetColNames(),
        "columns":   subModel.GetColumns(),
        "reffields": refFields,
        "refdata":   refData})
    if utils.HandleErr("[GridHandler::GetSubTable] Marshal: ", err, this.Response) {
        return
    }

    fmt.Fprintf(this.Response, "%s", string(response))
}

func (this *GridHandler) Load(tableName string) {
    if !sessions.CheackSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        return
    }

    limit, err := strconv.Atoi(this.Request.PostFormValue("rows"))
    if utils.HandleErr("[GridHandler::Load]  limit Atoi: ", err, this.Response) {
        return
    }

    page, err := strconv.Atoi(this.Request.PostFormValue("page"))
    if utils.HandleErr("[GridHandler::Load] page Atoi: ", err, this.Response) {
        return
    }

    sidx := this.Request.FormValue("sidx")
    start := limit*page - limit

    model := GetModel(tableName)
    model.SetOrder(sidx)
    model.SetLimit(limit)
    model.SetOffset(start)

    rows := db.Select(model, model.GetColumns())
    count := db.SelectCount(tableName)

    var totalPages int
    if count > 0 {
        totalPages = int(math.Ceil(float64(count) / float64(limit)))
    } else {
        totalPages = 0
    }

    result := make(map[string]interface{}, 4)
    result["rows"] = rows
    result["page"] = page
    result["total"] = totalPages
    result["records"] = count

    utils.SendJSReply(result, this.Response)
}

func (this *GridHandler) Select(tableName string) {
    if !sessions.CheackSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        return
    }

    tmp, err := template.ParseFiles(
        "mvc/views/table.html",
        "mvc/views/header.html",
        "mvc/views/footer.html")
    if utils.HandleErr("[GridHandler::Select] ParseFiles: ", err, this.Response) {
        return
    }

    model := GetModel(tableName)
    refFields, refData := GetModelRefDate(model)

    err = tmp.ExecuteTemplate(this.Response, "table", Model{
        RefData:   refData,
        RefFields: refFields,
        TableName: model.GetTableName(),
        ColNames:  model.GetColNames(),
        Columns:   model.GetColumns(),
        Caption:   model.GetCaption(),
        Sub:       model.GetSub()})
    utils.HandleErr("[GridHandler::Select] ExecuteTemplate: ", err, this.Response)
}

func (this *GridHandler) Edit(tableName string) {
    if !sessions.CheackSession(this.Response, this.Request) {
        http.Error(this.Response, "", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        return
    }

    model := GetModel(tableName)
    if model == nil {
        utils.HandleErr("[Grid-Handler::Edit] GetModel: invalid model", nil, this.Response)
        return
    }

    params := make(map[string]interface{}, len(model.GetColumns()))
    for i := 0; i < len(model.GetColumns()); i++ {
        params[model.GetColumnByIdx(i)] = this.Request.PostFormValue(model.GetColumnByIdx(i))
    }

    oper := this.Request.PostFormValue("oper")
    switch oper {
    case "edit":
        id, err := strconv.Atoi(this.Request.PostFormValue("id"))
        if utils.HandleErr("[Grid-Handler::Edit] strconv.Atoi: ", err, this.Response) {
            return
        }
        model.LoadModelData(params)
        model.LoadWherePart(map[string]interface{}{"id": id})
        err = db.QueryUpdate_(model).Scan()
        utils.HandleErr("", err, this.Response)
        break
    case "add":
        model.LoadModelData(params)
        var id int
        err := db.QueryInsert_(model, "RETURNING id").Scan(&id)
        utils.HandleErr("", err, this.Response)
        break
    case "del":
        db.QueryDeleteByIds(tableName, this.Request.PostFormValue("id"))
        break
    }
}

func (this *GridHandler) ResetPassword() {
    if !sessions.CheackSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        return
    }

    this.Response.Header().Set("Access-Control-Allow-Origin", "*")
    this.Response.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
    this.Response.Header().Set("Content-type", "application/json")

    request, err := utils.ParseJS(this.Request, this.Response)
    if err != nil {
        utils.SendJSReply(err.Error(), this.Response)
        return
    }

    pass := request["pass"].(string)

    id, err :=  strconv.Atoi(request["id"].(string))
    if utils.HandleErr("[Grid-Handler::ResetPassword] strconv.Atoi: ", err, this.Response) {
        return
    }

    user := GetModel("users")
    user.LoadWherePart(map[string]interface{}{"id": id})

    var salt string
    db.SelectRow(user, []string{"salt"}).Scan(&salt)

    user.LoadModelData(map[string]interface{}{"pass": utils.GetMD5Hash(pass + salt)})
    db.QueryUpdate_(user)

    utils.SendJSReply(map[string]interface{}{"result": "ok"}, this.Response)
}

func (this *GridHandler) isAdmin() bool {
    var role string

    user_id := sessions.GetValue("id", this.Request)
    if user_id == nil {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return false
    }

    user := GetModel("users")
    user.LoadWherePart(map[string]interface{}{"id": user_id})
    err := db.SelectRow(user, []string{"role"}).Scan(&role)
    if err != nil || role == "user" {
        http.Redirect(this.Response, this.Request, "/", http.StatusForbidden)
        return false
    }

    return role == "admin"
}

func (this *GridHandler) GetEventTypesByEventId() {
    if !sessions.CheackSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        return
    }

    request, err := utils.ParseJS(this.Request, this.Response)
    if err != nil {
        utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
    } else {
        event_id, err := strconv.Atoi(request["event_id"].(string))
        if utils.HandleErr("[GridHandler::GetEventTypesByEventId] id Atoi: ", err, this.Response) {
            return
        }

        query := db.InnerJoin(
            []string{"t.id", "t.name"},
            "events_types",
            "e_t",
            []string{"event_id", "type_id"},
            []string{"events", "event_types"},
            []string{"e", "t"},
            []string{"id", "id"},
            "where e.id=$1")
        result := db.Query(query, []interface{}{event_id})

        utils.SendJSReply(map[string]interface{}{"result": "ok", "data": result}, this.Response)
    }
}

func (this *GridHandler) ImportForms() {
    if !sessions.CheackSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        return
    }

    request, err := utils.ParseJS(this.Request, this.Response)
    if err != nil {
        utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
        return
    }

    event_id, err := strconv.Atoi(request["event_id"].(string))
    if utils.HandleErr("[GridHandler::GetEventTypesByEventId]  id Atoi: ", err, this.Response) {
        return
    }

    for _, v := range request["event_types_ids"].([]interface{}) {
        println("event_types_ids: ", v)
        type_id, err := strconv.Atoi(v.(string))
        if err != nil {
            utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
            return
        }
        query := `SELECT events.id from events
        INNER JOIN events_types on events_types.event_id = events.id
        INNER JOIN event_types on event_types.id = events_types.type_id
        WHERE event_types.id=$1 AND events.id <> $2
        ORDER BY id DESC LIMIT 1`

        eventResult := db.Query(query, []interface{}{type_id, event_id})

        query = `SELECT forms.id from forms
        INNER JOIN events_forms on events_forms.form_id = forms.id
        INNER JOIN events on events.id = events_forms.event_id
        WHERE events.id=$1`

        formsResult := db.Query(query, []interface{}{int(eventResult[0].(map[string]interface{})["id"].(int64))})

        for i := 0; i < len(formsResult); i++ {
            form_id := int(formsResult[i].(map[string]interface{})["id"].(int64))
            eventsForms := GetModel("events_forms")
            eventsForms.LoadWherePart(map[string]interface{}{"event_id":  event_id, "form_id": form_id})
            var p int
            err := db.SelectRow(eventsForms, []string{"id"}).Scan(&p)
            if err != sql.ErrNoRows {
                continue
            }
            eventsForms.LoadModelData(map[string]interface{}{"event_id":  event_id, "form_id": form_id})
            db.QueryInsert_(eventsForms, "")
        }
    }
}

func (this *GridHandler) GetPersonsByEventId() {
    if !sessions.CheackSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        return
    }

    request, err := utils.ParseJS(this.Request, this.Response)
    if err != nil {
        utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
    } else {
        event_id, err := strconv.Atoi(request["event_id"].(string))
        if utils.HandleErr("[GridHandler::GetEventTypesByEventId] id Atoi: ", err, this.Response) {
            return
        }

        params := request["params_ids"].([]interface{})

        if len(params) == 0 {
            utils.SendJSReply(map[string]interface{}{"result": "Выберите параметры."}, this.Response)
            return;
        }

        query := `select reg_param_vals.reg_id as id, array_to_string(array_agg(params.name || ': ' ||  param_values.value), ' ') as name
            from reg_param_vals
            INNER JOIN registrations on registrations.id = reg_param_vals.reg_id
            INNER JOIN events on events.id = reg_param_vals.event_id
            INNER JOIN param_values on param_values.id = reg_param_vals.param_val_id
            INNER JOIN params on params.id = param_values.param_id
            where params.id in (` + strings.Join(db.MakeParams(len(params)), ", ")
        query += ") and events.id = $" + strconv.Itoa(len(params)+1) + " group by reg_param_vals.reg_id;"

        result := db.Query(query, append(request["params_ids"].([]interface{}), event_id))

        utils.SendJSReply(map[string]interface{}{"result": "ok", "data": result}, this.Response)
    }
}

func (this *GridHandler) GetParamsByEventId() {
    if !sessions.CheackSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        return
    }

    request, err := utils.ParseJS(this.Request, this.Response)
    if err != nil {
        utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
    } else {
        event_id, err := strconv.Atoi(request["event_id"].(string))
        if utils.HandleErr("[GridHandler::GetEventTypesByEventId] id Atoi: ", err, this.Response) {
            return
        }

        query := `select DISTINCT params.id, params.name
            from reg_param_vals
            INNER JOIN events on events.id = reg_param_vals.event_id
            INNER JOIN param_values on param_values.id = reg_param_vals.param_val_id
            INNER JOIN params on params.id = param_values.param_id
            INNER JOIN registrations on registrations.id = reg_param_vals.reg_id
            where events.id = $1 ORDER BY params.id;`

        result := db.Query(query, []interface{}{event_id})

        utils.SendJSReply(map[string]interface{}{"result": "ok", "data": result}, this.Response)
    }
}
<commit_msg>add caption for list of persons<commit_after>package controllers

import (
    "database/sql"
    "encoding/json"
    "fmt"
    "github.com/orc/db"
    "github.com/orc/sessions"
    "github.com/orc/utils"
    "html/template"
    // "log"
    "math"
    "net/http"
    "strconv"
    "strings"
)

func (c *BaseController) GridHandler() *GridHandler {
    return new(GridHandler)
}

type GridHandler struct {
    Controller
}

func (this *GridHandler) GetSubTable() {
    if !sessions.CheackSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        return
    }

    request, err := utils.ParseJS(this.Request, this.Response)
    if err != nil {
        utils.SendJSReply(err.Error(), this.Response)
        return
    }

    model := GetModel(request["table"].(string))
    index, _ := strconv.Atoi(request["index"].(string))
    subModel := GetModel(model.GetSubTable(index))
    subModel.LoadWherePart(map[string]interface{}{model.GetSubField(): request["id"]})
    result := db.Select(subModel, subModel.GetColumns() )
    refFields, refData := GetModelRefDate(subModel)

    response, err := json.Marshal(map[string]interface{}{
        "data":      result,
        "name":      subModel.GetTableName(),
        "caption":   subModel.GetCaption(),
        "colnames":  subModel.GetColNames(),
        "columns":   subModel.GetColumns(),
        "reffields": refFields,
        "refdata":   refData})
    if utils.HandleErr("[GridHandler::GetSubTable] Marshal: ", err, this.Response) {
        return
    }

    fmt.Fprintf(this.Response, "%s", string(response))
}

func (this *GridHandler) Load(tableName string) {
    if !sessions.CheackSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        return
    }

    limit, err := strconv.Atoi(this.Request.PostFormValue("rows"))
    if utils.HandleErr("[GridHandler::Load]  limit Atoi: ", err, this.Response) {
        return
    }

    page, err := strconv.Atoi(this.Request.PostFormValue("page"))
    if utils.HandleErr("[GridHandler::Load] page Atoi: ", err, this.Response) {
        return
    }

    sidx := this.Request.FormValue("sidx")
    start := limit*page - limit

    model := GetModel(tableName)
    model.SetOrder(sidx)
    model.SetLimit(limit)
    model.SetOffset(start)

    rows := db.Select(model, model.GetColumns())
    count := db.SelectCount(tableName)

    var totalPages int
    if count > 0 {
        totalPages = int(math.Ceil(float64(count) / float64(limit)))
    } else {
        totalPages = 0
    }

    result := make(map[string]interface{}, 4)
    result["rows"] = rows
    result["page"] = page
    result["total"] = totalPages
    result["records"] = count

    utils.SendJSReply(result, this.Response)
}

func (this *GridHandler) Select(tableName string) {
    if !sessions.CheackSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        return
    }

    tmp, err := template.ParseFiles(
        "mvc/views/table.html",
        "mvc/views/header.html",
        "mvc/views/footer.html")
    if utils.HandleErr("[GridHandler::Select] ParseFiles: ", err, this.Response) {
        return
    }

    model := GetModel(tableName)
    refFields, refData := GetModelRefDate(model)

    err = tmp.ExecuteTemplate(this.Response, "table", Model{
        RefData:   refData,
        RefFields: refFields,
        TableName: model.GetTableName(),
        ColNames:  model.GetColNames(),
        Columns:   model.GetColumns(),
        Caption:   model.GetCaption(),
        Sub:       model.GetSub()})
    utils.HandleErr("[GridHandler::Select] ExecuteTemplate: ", err, this.Response)
}

func (this *GridHandler) Edit(tableName string) {
    if !sessions.CheackSession(this.Response, this.Request) {
        http.Error(this.Response, "", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        return
    }

    model := GetModel(tableName)
    if model == nil {
        utils.HandleErr("[Grid-Handler::Edit] GetModel: invalid model", nil, this.Response)
        return
    }

    params := make(map[string]interface{}, len(model.GetColumns()))
    for i := 0; i < len(model.GetColumns()); i++ {
        params[model.GetColumnByIdx(i)] = this.Request.PostFormValue(model.GetColumnByIdx(i))
    }

    oper := this.Request.PostFormValue("oper")
    switch oper {
    case "edit":
        id, err := strconv.Atoi(this.Request.PostFormValue("id"))
        if utils.HandleErr("[Grid-Handler::Edit] strconv.Atoi: ", err, this.Response) {
            return
        }
        model.LoadModelData(params)
        model.LoadWherePart(map[string]interface{}{"id": id})
        err = db.QueryUpdate_(model).Scan()
        utils.HandleErr("", err, this.Response)
        break
    case "add":
        model.LoadModelData(params)
        var id int
        err := db.QueryInsert_(model, "RETURNING id").Scan(&id)
        utils.HandleErr("", err, this.Response)
        break
    case "del":
        db.QueryDeleteByIds(tableName, this.Request.PostFormValue("id"))
        break
    }
}

func (this *GridHandler) ResetPassword() {
    if !sessions.CheackSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        return
    }

    this.Response.Header().Set("Access-Control-Allow-Origin", "*")
    this.Response.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
    this.Response.Header().Set("Content-type", "application/json")

    request, err := utils.ParseJS(this.Request, this.Response)
    if err != nil {
        utils.SendJSReply(err.Error(), this.Response)
        return
    }

    pass := request["pass"].(string)

    id, err :=  strconv.Atoi(request["id"].(string))
    if utils.HandleErr("[Grid-Handler::ResetPassword] strconv.Atoi: ", err, this.Response) {
        return
    }

    user := GetModel("users")
    user.LoadWherePart(map[string]interface{}{"id": id})

    var salt string
    db.SelectRow(user, []string{"salt"}).Scan(&salt)

    user.LoadModelData(map[string]interface{}{"pass": utils.GetMD5Hash(pass + salt)})
    db.QueryUpdate_(user)

    utils.SendJSReply(map[string]interface{}{"result": "ok"}, this.Response)
}

func (this *GridHandler) isAdmin() bool {
    var role string

    user_id := sessions.GetValue("id", this.Request)
    if user_id == nil {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return false
    }

    user := GetModel("users")
    user.LoadWherePart(map[string]interface{}{"id": user_id})
    err := db.SelectRow(user, []string{"role"}).Scan(&role)
    if err != nil || role == "user" {
        http.Redirect(this.Response, this.Request, "/", http.StatusForbidden)
        return false
    }

    return role == "admin"
}

func (this *GridHandler) GetEventTypesByEventId() {
    if !sessions.CheackSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        return
    }

    request, err := utils.ParseJS(this.Request, this.Response)
    if err != nil {
        utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
    } else {
        event_id, err := strconv.Atoi(request["event_id"].(string))
        if utils.HandleErr("[GridHandler::GetEventTypesByEventId] id Atoi: ", err, this.Response) {
            return
        }

        query := db.InnerJoin(
            []string{"t.id", "t.name"},
            "events_types",
            "e_t",
            []string{"event_id", "type_id"},
            []string{"events", "event_types"},
            []string{"e", "t"},
            []string{"id", "id"},
            "where e.id=$1")
        result := db.Query(query, []interface{}{event_id})

        utils.SendJSReply(map[string]interface{}{"result": "ok", "data": result}, this.Response)
    }
}

func (this *GridHandler) ImportForms() {
    if !sessions.CheackSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        return
    }

    request, err := utils.ParseJS(this.Request, this.Response)
    if err != nil {
        utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
        return
    }

    event_id, err := strconv.Atoi(request["event_id"].(string))
    if utils.HandleErr("[GridHandler::GetEventTypesByEventId]  id Atoi: ", err, this.Response) {
        return
    }

    for _, v := range request["event_types_ids"].([]interface{}) {
        println("event_types_ids: ", v)
        type_id, err := strconv.Atoi(v.(string))
        if err != nil {
            utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
            return
        }
        query := `SELECT events.id from events
        INNER JOIN events_types on events_types.event_id = events.id
        INNER JOIN event_types on event_types.id = events_types.type_id
        WHERE event_types.id=$1 AND events.id <> $2
        ORDER BY id DESC LIMIT 1`

        eventResult := db.Query(query, []interface{}{type_id, event_id})

        query = `SELECT forms.id from forms
        INNER JOIN events_forms on events_forms.form_id = forms.id
        INNER JOIN events on events.id = events_forms.event_id
        WHERE events.id=$1`

        formsResult := db.Query(query, []interface{}{int(eventResult[0].(map[string]interface{})["id"].(int64))})

        for i := 0; i < len(formsResult); i++ {
            form_id := int(formsResult[i].(map[string]interface{})["id"].(int64))
            eventsForms := GetModel("events_forms")
            eventsForms.LoadWherePart(map[string]interface{}{"event_id":  event_id, "form_id": form_id})
            var p int
            err := db.SelectRow(eventsForms, []string{"id"}).Scan(&p)
            if err != sql.ErrNoRows {
                continue
            }
            eventsForms.LoadModelData(map[string]interface{}{"event_id":  event_id, "form_id": form_id})
            db.QueryInsert_(eventsForms, "")
        }
    }
}

func (this *GridHandler) GetPersonsByEventId() {
    if !sessions.CheackSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        return
    }

    request, err := utils.ParseJS(this.Request, this.Response)
    if err != nil {
        utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
    } else {
        event_id, err := strconv.Atoi(request["event_id"].(string))
        if utils.HandleErr("[GridHandler::GetEventTypesByEventId] id Atoi: ", err, this.Response) {
            return
        }

        params := request["params_ids"].([]interface{})

        if len(params) == 0 {
            utils.SendJSReply(map[string]interface{}{"result": "Выберите параметры."}, this.Response)
            return;
        }

        query1 := `select reg_param_vals.reg_id as id, array_to_string(array_agg(params.name), ' ') as name from reg_param_vals
            INNER JOIN registrations on registrations.id = reg_param_vals.reg_id
            INNER JOIN events on events.id = reg_param_vals.event_id
            INNER JOIN param_values on param_values.id = reg_param_vals.param_val_id
            INNER JOIN params on params.id = param_values.param_id
            where params.id in (` + strings.Join(db.MakeParams(len(params)), ", ")
        query1 += ") and events.id = $" + strconv.Itoa(len(params)+1) + " group by reg_param_vals.reg_id union all "

        query2 := `select reg_param_vals.reg_id as id, array_to_string(array_agg(param_values.value), ' ') as name
            from reg_param_vals
            INNER JOIN registrations on registrations.id = reg_param_vals.reg_id
            INNER JOIN events on events.id = reg_param_vals.event_id
            INNER JOIN param_values on param_values.id = reg_param_vals.param_val_id
            INNER JOIN params on params.id = param_values.param_id
            where params.id in (` + strings.Join(db.MakeParams(len(params)), ", ")
        query2 += ") and events.id = $" + strconv.Itoa(len(params)+1) + " group by reg_param_vals.reg_id;"

        result := db.Query(query1+query2, append(request["params_ids"].([]interface{}), event_id))

        utils.SendJSReply(map[string]interface{}{"result": "ok", "data": result}, this.Response)
    }
}

func (this *GridHandler) GetParamsByEventId() {
    if !sessions.CheackSession(this.Response, this.Request) {
        http.Redirect(this.Response, this.Request, "/", http.StatusUnauthorized)
        return
    }

    if !this.isAdmin() {
        return
    }

    request, err := utils.ParseJS(this.Request, this.Response)
    if err != nil {
        utils.SendJSReply(map[string]interface{}{"result": err.Error()}, this.Response)
    } else {
        event_id, err := strconv.Atoi(request["event_id"].(string))
        if utils.HandleErr("[GridHandler::GetEventTypesByEventId] id Atoi: ", err, this.Response) {
            return
        }

        query := `select DISTINCT params.id, params.name
            from reg_param_vals
            INNER JOIN events on events.id = reg_param_vals.event_id
            INNER JOIN param_values on param_values.id = reg_param_vals.param_val_id
            INNER JOIN params on params.id = param_values.param_id
            INNER JOIN registrations on registrations.id = reg_param_vals.reg_id
            where events.id = $1 ORDER BY params.id;`

        result := db.Query(query, []interface{}{event_id})

        utils.SendJSReply(map[string]interface{}{"result": "ok", "data": result}, this.Response)
    }
}
<|endoftext|>


<commit_before>// Copyright Istio Authors
//
// 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 csrctrl

import (
	"context"
	"os"
	"strings"
	"time"

	capi "k8s.io/api/certificates/v1"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/client-go/rest"
	ctrl "sigs.k8s.io/controller-runtime"

	// +kubebuilder:scaffold:imports
	"istio.io/istio/pkg/test/csrctrl/signer"
	"istio.io/pkg/log"
)

const (
	// Define the root path for signer to store CA and private key files.
	signerRoot = "/tmp/pki/signer/"

	// The duration of the signed certificates
	certificateDuration = 1 * time.Hour
)

var (
	scheme         = runtime.NewScheme()
	loggingOptions = log.DefaultOptions()
	_              = capi.AddToScheme(scheme)
	_              = corev1.AddToScheme(scheme)
)

type SignerRootCert struct {
	Signer   string
	Rootcert string
}

func RunCSRController(signerNames string, appendRootCert bool, config *rest.Config, c <-chan struct{},
	certChan chan *SignerRootCert,
) {
	// Config Istio log
	if err := log.Configure(loggingOptions); err != nil {
		log.Infof("Unable to configure Istio log error: %v", err)
		os.Exit(-1)
	}
	mgr, err := ctrl.NewManager(config, ctrl.Options{
		Scheme: scheme,
		// disabel the metric server to avoid the port conflicting
		MetricsBindAddress: "0",
	})
	if err != nil {
		log.Infof("Unable to start manager error: %v", err)
		os.Exit(-1)
	}

	arrSingers := strings.Split(signerNames, ",")
	signersMap := make(map[string]*signer.Signer, len(arrSingers))
	for _, signerName := range arrSingers {
		signer, sErr := signer.NewSigner(signerRoot, signerName, certificateDuration)
		if sErr != nil {
			log.Infof("Unable to start signer for [%s], error: %v", signerName, sErr)
			os.Exit(-1)
		}
		signersMap[signerName] = signer
		rootCert, rErr := os.ReadFile(signer.GetRootCerts())
		if rErr != nil {
			log.Infof("Unable to read root cert for signer [%s], error: %v", signerName, sErr)
			os.Exit(-1)
		}
		rootCertsForSigner := &SignerRootCert{
			Signer:   signerName,
			Rootcert: string(rootCert),
		}
		certChan <- rootCertsForSigner
	}

	if err := (&CertificateSigningRequestSigningReconciler{
		Client:         mgr.GetClient(),
		SignerRoot:     signerRoot,
		CtrlCertTTL:    certificateDuration,
		Scheme:         mgr.GetScheme(),
		SignerNames:    arrSingers,
		Signers:        signersMap,
		appendRootCert: appendRootCert,
	}).SetupWithManager(mgr); err != nil {
		log.Infof("Unable to create Controller fro controller CSRSigningReconciler, error: %v", err)
		os.Exit(-1)
	}
	ctx, cancel := context.WithCancel(context.Background())
	go func() {
		<-c
		cancel()
	}()
	// +kubebuilder:scaffold:builder
	log.Info("starting manager")
	if err := mgr.Start(ctx); err != nil {
		log.Infof("Problem running manager, error: %v", err)
		os.Exit(-1)
	}
}
<commit_msg>Fixing typos in start_csrctrl.go (#39059)<commit_after>// Copyright Istio Authors
//
// 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 csrctrl

import (
	"context"
	"os"
	"strings"
	"time"

	capi "k8s.io/api/certificates/v1"
	corev1 "k8s.io/api/core/v1"
	"k8s.io/apimachinery/pkg/runtime"
	"k8s.io/client-go/rest"
	ctrl "sigs.k8s.io/controller-runtime"

	// +kubebuilder:scaffold:imports
	"istio.io/istio/pkg/test/csrctrl/signer"
	"istio.io/pkg/log"
)

const (
	// Define the root path for signer to store CA and private key files.
	signerRoot = "/tmp/pki/signer/"

	// The duration of the signed certificates
	certificateDuration = 1 * time.Hour
)

var (
	scheme         = runtime.NewScheme()
	loggingOptions = log.DefaultOptions()
	_              = capi.AddToScheme(scheme)
	_              = corev1.AddToScheme(scheme)
)

type SignerRootCert struct {
	Signer   string
	Rootcert string
}

func RunCSRController(signerNames string, appendRootCert bool, config *rest.Config, c <-chan struct{},
	certChan chan *SignerRootCert,
) {
	// Config Istio log
	if err := log.Configure(loggingOptions); err != nil {
		log.Infof("Unable to configure Istio log error: %v", err)
		os.Exit(-1)
	}
	mgr, err := ctrl.NewManager(config, ctrl.Options{
		Scheme: scheme,
		// disable the metric server to avoid the port conflicting
		MetricsBindAddress: "0",
	})
	if err != nil {
		log.Infof("Unable to start manager error: %v", err)
		os.Exit(-1)
	}

	arrSingers := strings.Split(signerNames, ",")
	signersMap := make(map[string]*signer.Signer, len(arrSingers))
	for _, signerName := range arrSingers {
		signer, sErr := signer.NewSigner(signerRoot, signerName, certificateDuration)
		if sErr != nil {
			log.Infof("Unable to start signer for [%s], error: %v", signerName, sErr)
			os.Exit(-1)
		}
		signersMap[signerName] = signer
		rootCert, rErr := os.ReadFile(signer.GetRootCerts())
		if rErr != nil {
			log.Infof("Unable to read root cert for signer [%s], error: %v", signerName, sErr)
			os.Exit(-1)
		}
		rootCertsForSigner := &SignerRootCert{
			Signer:   signerName,
			Rootcert: string(rootCert),
		}
		certChan <- rootCertsForSigner
	}

	if err := (&CertificateSigningRequestSigningReconciler{
		Client:         mgr.GetClient(),
		SignerRoot:     signerRoot,
		CtrlCertTTL:    certificateDuration,
		Scheme:         mgr.GetScheme(),
		SignerNames:    arrSingers,
		Signers:        signersMap,
		appendRootCert: appendRootCert,
	}).SetupWithManager(mgr); err != nil {
		log.Infof("Unable to create Controller for controller CSRSigningReconciler, error: %v", err)
		os.Exit(-1)
	}
	ctx, cancel := context.WithCancel(context.Background())
	go func() {
		<-c
		cancel()
	}()
	// +kubebuilder:scaffold:builder
	log.Info("starting manager")
	if err := mgr.Start(ctx); err != nil {
		log.Infof("Problem running manager, error: %v", err)
		os.Exit(-1)
	}
}
<|endoftext|>


<commit_before>// Copyright 2017 Frédéric Guillot. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package controller

import (
	"encoding/base64"
	"log"
	"time"

	"github.com/miniflux/miniflux2/server/core"
	"github.com/miniflux/miniflux2/server/static"
)

// Stylesheet renders the CSS.
func (c *Controller) Stylesheet(ctx *core.Context, request *core.Request, response *core.Response) {
	stylesheet := request.StringParam("name", "white")
	body := static.Stylesheets["common"]
	etag := static.StylesheetsChecksums["common"]

	if theme, found := static.Stylesheets[stylesheet]; found {
		body += theme
		etag += static.StylesheetsChecksums[stylesheet]
	}

	response.Cache("text/css", etag, []byte(body), 48*time.Hour)
}

// Javascript renders application client side code.
func (c *Controller) Javascript(ctx *core.Context, request *core.Request, response *core.Response) {
	response.Cache("text/javascript", static.JavascriptChecksums["app"], []byte(static.Javascript["app"]), 48*time.Hour)
}

// Favicon renders the application favicon.
func (c *Controller) Favicon(ctx *core.Context, request *core.Request, response *core.Response) {
	blob, err := base64.StdEncoding.DecodeString(static.Binaries["favicon.ico"])
	if err != nil {
		log.Println(err)
		response.HTML().NotFound()
		return
	}

	response.Cache("image/x-icon", static.BinariesChecksums["favicon.ico"], blob, 48*time.Hour)
}
<commit_msg>Add charset to CSS and JS mime type<commit_after>// Copyright 2017 Frédéric Guillot. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.

package controller

import (
	"encoding/base64"
	"log"
	"time"

	"github.com/miniflux/miniflux2/server/core"
	"github.com/miniflux/miniflux2/server/static"
)

// Stylesheet renders the CSS.
func (c *Controller) Stylesheet(ctx *core.Context, request *core.Request, response *core.Response) {
	stylesheet := request.StringParam("name", "white")
	body := static.Stylesheets["common"]
	etag := static.StylesheetsChecksums["common"]

	if theme, found := static.Stylesheets[stylesheet]; found {
		body += theme
		etag += static.StylesheetsChecksums[stylesheet]
	}

	response.Cache("text/css; charset=utf-8", etag, []byte(body), 48*time.Hour)
}

// Javascript renders application client side code.
func (c *Controller) Javascript(ctx *core.Context, request *core.Request, response *core.Response) {
	response.Cache("text/javascript; charset=utf-8", static.JavascriptChecksums["app"], []byte(static.Javascript["app"]), 48*time.Hour)
}

// Favicon renders the application favicon.
func (c *Controller) Favicon(ctx *core.Context, request *core.Request, response *core.Response) {
	blob, err := base64.StdEncoding.DecodeString(static.Binaries["favicon.ico"])
	if err != nil {
		log.Println(err)
		response.HTML().NotFound()
		return
	}

	response.Cache("image/x-icon", static.BinariesChecksums["favicon.ico"], blob, 48*time.Hour)
}
<|endoftext|>


<commit_before>package httpfunction

import "github.com/bitly/go-simplejson"

import (
	"net/http"
	"dao"
	"encoding/json"
	"errors"
	"strings"
	"strconv"
	"log"
	"os"
	"io"
)

type Datatablesdata struct {
	Data interface{}  `json:"data"`
	Files uploadfile_tmp `json:"files,omitempty"`
	Upload uploadid `json:"upload,omitempty"`
}

type uploadid struct {
	Id string `json:"id"`
}

type uploadfile_tmp struct {
	Files *simplejson.Json `json:"files"`
}

const UPLOAD_DIR = "/home/zh/GoPro/firstRedis/html/uploads"
const PreWebPath = "/uploads/"
const URLTableName = "tableName"
//var mutexlock sync.Mutex

func GetDataTableId(r *http.Request)(id []string, err error ){

	action := r.FormValue("action")
	id = make([]string, 0)
	if action == "create" {
		id = append(id, "0")
	}else {
		id = make([]string, 0)
		err = errors.New("failed to parse id")
		for k,v := range r.Form{
			if strings.Contains(k,"[id]"){
				id = append(id, v[0])
				err = nil
			}
		}
		if err != nil {
			log.Println("failed to get datatables id")
		}
	}
	return
}

func Getpostfile(w http.ResponseWriter, r *http.Request) (uploadid string, err error){
	var filetmp dao.Uploadfile
	file,handler, err := r.FormFile("upload")
	if err != nil {
		log.Println("failed to get formfile")
		return
	}
	defer file.Close()

	filetmp.Filename = handler.Filename
	t, err := os.Create(UPLOAD_DIR + "/" + filetmp.Filename)
	defer t.Close()
	if err != nil {
		log.Println("fail to create file")
		return
	}
	_, err = io.Copy(t, file)
	if err != nil {
		log.Println("failed to copy file")
		return
	}

	filetmp.Systempath = UPLOAD_DIR + "/" + filetmp.Filename
	filetmp.Webpath = PreWebPath + filetmp.Filename

	fileinfo, err := os.Stat(filetmp.Systempath)
	if err != nil {
		log.Println("failed to get the file station")
		return
	}
	filetmp.Filesize = strconv.Itoa(int(fileinfo.Size()))
	filetmp.Id = strconv.Itoa(dao.GetNextId())

	//database
	filetmp.Insert()

	uploadid = filetmp.Id

	return
}

func Createdatatablesline(w http.ResponseWriter,r *http.Request, id []string, tableName string) (res []dao.EditDataTables, err error) {

	//mutexlock.Lock()
	//defer mutexlock.Unlock()
	res = make([]dao.EditDataTables, len(id))
	for i := range id {
		res[i], err = dao.GetDataStruct(tableName)
		if err != nil {
			log.Println(err.Error(), " failed to GetDataStruct in func Createdatatablesline")
			return
		}
		res[i].LoadDataFromPostForm(r, id[i])
		err = dao.Insert(tableName, res[i])
		if err != nil {
			log.Println("failed to create datatables row")
			return
		}
	}

	return
}

func Editdatatablesline(w http.ResponseWriter,r *http.Request, id []string, tableName string) (res []dao.EditDataTables,err error) {

	//mutexlock.Lock()
	//defer mutexlock.Unlock()
	res = make([]dao.EditDataTables, len(id))
	for i := range id {
		res[i], err = dao.GetDataStruct(tableName)
		if err != nil {
			log.Println(err.Error(), " failed to GetDataStruct in func Createdatatablesline")
			return
		}
		res[i].LoadDataFromPostForm(r, id[i])

		var filetmp dao.Uploadfile
		filetmp.Id, err = dao.GetFileId(tableName, res[i].GetId())
		NowFileId := r.FormValue("data[" + id[i] + "][fileid]")
		if err != nil {
			log.Println("failed to get fileId in func Editdatatablesline")
			return
		}
		if filetmp.Id != "" && filetmp.Id != NowFileId{
			//if need delete local file you should have this
			//err = filetmp.LoadUploadfile()
			//if err != nil {
			//	log.Println("failed to load uploadfile in func deldatatablesline")
			//	return
			// }
			err = filetmp.Remove()
			if err != nil {
				log.Println("failed to remove uploadfile in func deldatatablesline")
				return
			}
		}

		err = dao.Update(tableName, res[i].GetId(), res[i])
		if err != nil {
			log.Println("failed to update datatables line")
			return
		}
	}
	return
}

func Deldatatablesline(w http.ResponseWriter,r *http.Request, id []string, tableName string) (err error) {

	//mutexlock.Lock()
	//defer mutexlock.Unlock()
	res := make([]dao.EditDataTables,len(id))
	for i := range id {
		res[i], err = dao.GetDataStruct(tableName)
		if err != nil {
			log.Println(err.Error(), " failed to GetDataStruct in func Createdatatablesline")
			return
		}
		res[i].LoadDataFromPostForm(r, id[i])

		var filetmp dao.Uploadfile
		filetmp.Id, err = dao.GetFileId(tableName, res[i].GetId())
		if err != nil {
			log.Println("failed to get fileId in func Deldatatablesline")
			return
		}
		if filetmp.Id != ""{
			//if need delete local file you should have this
			//err = filetmp.LoadUploadfile()
			//if err != nil {
			//	log.Println("failed to load uploadfile in func deldatatablesline")
			//	return
			//}
			err = filetmp.Remove()
			if err != nil {
				log.Println("failed to remove uploadfile in func deldatatablesline")
				return
			}
		}

		err = dao.Remove(tableName, res[i].GetId())
		if err != nil {
			log.Println("failed to delete datatables line")
			return
		}

	}

	return
}

func ViewHandle(w http.ResponseWriter, r *http.Request){

	var tmp Datatablesdata
	var err error
	flag := false
	tableName := r.URL.Query().Get(URLTableName)

	if r.Method == "POST"{
		if r.ContentLength != 0 {
			action := r.FormValue("action")
			if action == "upload" {
				tmp.Upload.Id, err = Getpostfile(w, r)
				if err != nil {
					log.Println(err.Error(), " failed to action upload in func ViewHandle")
					return
				}
				flag = true
			} else {
				id, _ := GetDataTableId(r)
				if action == "create"  || action == "edit"{
					var res []dao.EditDataTables
					if action == "create" {
						res, _ = Createdatatablesline(w, r, id, tableName)
					}else {
						res, _ = Editdatatablesline(w, r, id, tableName)
					}
					dataslice := make([]interface{}, 0)
					for i := range res {
						data, err := dao.GetDataStruct(tableName)
						if err != nil {
							log.Println("failed to get datastruct %v", err.Error())
							return
						}
						err = dao.GetOneById(tableName, res[i].GetId(), data)
						if err != nil {
							log.Println("failed to get one data by id %v", err.Error())
							return
						}
						dataslice = append(dataslice, data)
					}
					tmp.Data = dataslice
					flag = true

				}else if action == "remove"{
					Deldatatablesline(w, r, id, tableName)
				}
			}
		}
	} else if r.Method == "GET" {

		tmp.Data, err = dao.GetDataStructSilce(tableName)
		if err != nil {
			log.Println("falied to get datastruct silce, err: ", err.Error())
			return
		}

		err = dao.GetAll(tableName, tmp.Data)
		if err != nil {
			log.Println("failed to get all data, err: ",err.Error())
			return
		}
		flag = true
	}

	//if flag is true, add all file information to tmp
	if flag {
		tmp.Files.Files = simplejson.New()
		res, err := dao.GetAllUploadfile()
		if err != nil {
			log.Println(err.Error(), " failed to GetAllUploadfile in func ViewHandle")
			return
		}
		for i := range res{
			tmp.Files.Files.Set(res[i].Id, res[i])
		}
	}

	//encode to json
	t, err := json.Marshal(tmp)
	if err != nil {
		log.Println(err.Error(), " failed to marshal to json in func ViewHandle")
		return
	}
	w.Write(t)
}

<commit_msg>little change<commit_after>package httpfunction

import "github.com/bitly/go-simplejson"

import (
	"net/http"
	"dao"
	"encoding/json"
	"errors"
	"strings"
	"strconv"
	"log"
	"os"
	"io"
	"reflect"
	"fmt"
)

type Datatablesdata struct {
	Data interface{}  `json:"data"`
	Files uploadfile_tmp `json:"files,omitempty"`
	Upload uploadid `json:"upload,omitempty"`
}

type uploadid struct {
	Id string `json:"id"`
}

type uploadfile_tmp struct {
	Files *simplejson.Json `json:"files"`
}

const UPLOAD_DIR = "/home/zh/GoPro/firstRedis/html/uploads"
const PreWebPath = "/uploads/"
const URLTableName = "tableName"
//var mutexlock sync.Mutex

func GetDataTableId(r *http.Request)(id []string, err error ){

	action := r.FormValue("action")
	id = make([]string, 0)
	if action == "create" {
		id = append(id, "0")
	}else {
		id = make([]string, 0)
		err = errors.New("failed to parse id")
		for k,v := range r.Form{
			if strings.Contains(k,"[id]"){
				id = append(id, v[0])
				err = nil
			}
		}
		if err != nil {
			log.Println("failed to get datatables id")
		}
	}
	return
}

func Getpostfile(w http.ResponseWriter, r *http.Request) (uploadid string, err error){
	var filetmp dao.Uploadfile
	file,handler, err := r.FormFile("upload")
	if err != nil {
		log.Println("failed to get formfile")
		return
	}
	defer file.Close()

	filetmp.Filename = handler.Filename
	t, err := os.Create(UPLOAD_DIR + "/" + filetmp.Filename)
	defer t.Close()
	if err != nil {
		log.Println("fail to create file")
		return
	}
	_, err = io.Copy(t, file)
	if err != nil {
		log.Println("failed to copy file")
		return
	}

	filetmp.Systempath = UPLOAD_DIR + "/" + filetmp.Filename
	filetmp.Webpath = PreWebPath + filetmp.Filename

	fileinfo, err := os.Stat(filetmp.Systempath)
	if err != nil {
		log.Println("failed to get the file station")
		return
	}
	filetmp.Filesize = strconv.Itoa(int(fileinfo.Size()))
	filetmp.Id = strconv.Itoa(dao.GetNextId())

	//database
	filetmp.Insert()

	uploadid = filetmp.Id

	return
}

func Createdatatablesline(w http.ResponseWriter,r *http.Request, id []string, tableName string) (res []dao.EditDataTables, err error) {

	//mutexlock.Lock()
	//defer mutexlock.Unlock()
	res = make([]dao.EditDataTables, len(id))
	for i := range id {
		res[i], err = dao.GetDataStruct(tableName)
		if err != nil {
			log.Println(err.Error(), " failed to GetDataStruct in func Createdatatablesline")
			return
		}
		res[i].LoadDataFromPostForm(r, id[i])
		err = dao.Insert(tableName, res[i])
		if err != nil {
			log.Println("failed to create datatables row")
			return
		}
	}

	return
}

func Editdatatablesline(w http.ResponseWriter,r *http.Request, id []string, tableName string) (res []dao.EditDataTables,err error) {

	//mutexlock.Lock()
	//defer mutexlock.Unlock()
	res = make([]dao.EditDataTables, len(id))
	for i := range id {
		res[i], err = dao.GetDataStruct(tableName)
		if err != nil {
			log.Println(err.Error(), " failed to GetDataStruct in func Createdatatablesline")
			return
		}
		res[i].LoadDataFromPostForm(r, id[i])

		var filetmp dao.Uploadfile
		filetmp.Id, err = dao.GetFileId(tableName, res[i].GetId())
		NowFileId := r.FormValue("data[" + id[i] + "][fileid]")
		if err != nil {
			log.Println("failed to get fileId in func Editdatatablesline")
			return
		}
		if filetmp.Id != "" && filetmp.Id != NowFileId{
			//if need delete local file you should have this
			//err = filetmp.LoadUploadfile()
			//if err != nil {
			//	log.Println("failed to load uploadfile in func deldatatablesline")
			//	return
			// }
			err = filetmp.Remove()
			if err != nil {
				log.Println("failed to remove uploadfile in func deldatatablesline")
				return
			}
		}

		err = dao.Update(tableName, res[i].GetId(), res[i])
		if err != nil {
			log.Println("failed to update datatables line")
			return
		}
	}
	return
}

func Deldatatablesline(w http.ResponseWriter,r *http.Request, id []string, tableName string) (err error) {

	//mutexlock.Lock()
	//defer mutexlock.Unlock()
	res := make([]dao.EditDataTables,len(id))
	for i := range id {
		res[i], err = dao.GetDataStruct(tableName)
		if err != nil {
			log.Println(err.Error(), " failed to GetDataStruct in func Createdatatablesline")
			return
		}
		res[i].LoadDataFromPostForm(r, id[i])

		var filetmp dao.Uploadfile
		filetmp.Id, err = dao.GetFileId(tableName, res[i].GetId())
		if err != nil {
			log.Println("failed to get fileId in func Deldatatablesline")
			return
		}
		if filetmp.Id != ""{
			//if need delete local file you should have this
			//err = filetmp.LoadUploadfile()
			//if err != nil {
			//	log.Println("failed to load uploadfile in func deldatatablesline")
			//	return
			//}
			err = filetmp.Remove()
			if err != nil {
				log.Println("failed to remove uploadfile in func deldatatablesline")
				return
			}
		}

		err = dao.Remove(tableName, res[i].GetId())
		if err != nil {
			log.Println("failed to delete datatables line")
			return
		}

	}

	return
}

func ViewHandle(w http.ResponseWriter, r *http.Request){

	var tmp Datatablesdata
	var err error
	flag := false
	tableName := r.URL.Query().Get(URLTableName)

	if r.Method == "POST"{
		if r.ContentLength != 0 {
			action := r.FormValue("action")
			if action == "upload" {
				tmp.Upload.Id, err = Getpostfile(w, r)
				if err != nil {
					log.Println(err.Error(), " failed to action upload in func ViewHandle")
					return
				}
				flag = true
			} else {
				id, _ := GetDataTableId(r)
				if action == "create"  || action == "edit"{
					var res []dao.EditDataTables
					if action == "create" {
						res, _ = Createdatatablesline(w, r, id, tableName)
					}else {
						res, _ = Editdatatablesline(w, r, id, tableName)
					}
					dataslice := make([]interface{}, 0)
					for i := range res {
						data, err := dao.GetDataStruct(tableName)
						if err != nil {
							log.Println("failed to get datastruct %v", err.Error())
							return
						}
						err = dao.GetOneById(tableName, res[i].GetId(), data)
						if err != nil {
							log.Println("failed to get one data by id %v", err.Error())
							return
						}
						dataslice = append(dataslice, data)
					}
					tmp.Data = dataslice
					flag = true

				}else if action == "remove"{
					Deldatatablesline(w, r, id, tableName)
				}
			}
		}
	} else if r.Method == "GET" {

		tmp.Data, err = dao.GetDataStructSilce(tableName)
		if err != nil {
			log.Println("falied to get datastruct silce, err: ", err.Error())
			return
		}

		err = dao.GetAll(tableName, tmp.Data)
		if err != nil {
			log.Println("failed to get all data, err: ",err.Error())
			return
		}
		if reflect.ValueOf(tmp.Data).Elem().Len() == 0 {
			fmt.Println("make the tmp.data is not empty")
			tmp.Data = make([]interface{}, 0)
		}
		flag = true
	}

	//if flag is true, add all file information to tmp
	if flag {
		tmp.Files.Files = simplejson.New()
		res, err := dao.GetAllUploadfile()
		if err != nil {
			log.Println(err.Error(), " failed to GetAllUploadfile in func ViewHandle")
			return
		}
		for i := range res{
			tmp.Files.Files.Set(res[i].Id, res[i])
		}
	}

	//encode to json
	t, err := json.Marshal(tmp)
	if err != nil {
		log.Println(err.Error(), " failed to marshal to json in func ViewHandle")
		return
	}
	w.Write(t)
}

<|endoftext|>