<commit_before>// Package twitch implements the OAuth2 protocol for authenticating users through Twitch.
// This package can be used as a reference implementation of an OAuth2 provider for Twitch.
package twitch

import (
	"encoding/json"
	"io"
	"net/http"
	"strconv"

	"fmt"
	"github.com/markbates/goth"
	"golang.org/x/oauth2"
)

const (
	authURL      string = "https://api.twitch.tv/kraken/oauth2/authorize"
	tokenURL     string = "https://api.twitch.tv/kraken/oauth2/token"
	userEndpoint string = "https://api.twitch.tv/kraken/user"
)

const (
	// ScopeUserRead provides read access to non-public user information, such
	// as their email address.
	ScopeUserRead string = "user_read"
	// ScopeUserBlocksEdit provides the ability to ignore or unignore on
	// behalf of a user.
	ScopeUserBlocksEdit string = "user_blocks_edit"
	// ScopeUserBlocksRead provides read access to a user's list of ignored
	// users.
	ScopeUserBlocksRead string = "user_blocks_read"
	// ScopeUserFollowsEdit provides access to manage a user's followed
	// channels.
	ScopeUserFollowsEdit string = "user_follows_edit"
	// ScopeChannelRead provides read access to non-public channel information,
	// including email address and stream key.
	ScopeChannelRead string = "channel_read"
	// ScopeChannelEditor provides write access to channel metadata (game,
	// status, etc).
	ScopeChannelEditor string = "channel_editor"
	// ScopeChannelCommercial provides access to trigger commercials on
	// channel.
	ScopeChannelCommercial string = "channel_commercial"
	// ScopeChannelStream provides the ability to reset a channel's stream key.
	ScopeChannelStream string = "channel_stream"
	// ScopeChannelSubscriptions provides read access to all subscribers to
	// your channel.
	ScopeChannelSubscriptions string = "channel_subscriptions"
	// ScopeUserSubscriptions provides read access to subscriptions of a user.
	ScopeUserSubscriptions string = "user_subscriptions"
	// ScopeChannelCheckSubscription provides read access to check if a user is
	// subscribed to your channel.
	ScopeChannelCheckSubscription string = "channel_check_subscription"
	// ScopeChatLogin provides the ability to log into chat and send messages.
	ScopeChatLogin string = "chat_login"
)

// New creates a new Twitch provider, and sets up important connection details.
// You should always call `twitch.New` to get a new Provider. Never try to create
// one manually.
func New(clientKey string, secret string, callbackURL string, scopes ...string) *Provider {
	p := &Provider{
		ClientKey:    clientKey,
		Secret:       secret,
		CallbackURL:  callbackURL,
		providerName: "twitch",
	}
	p.config = newConfig(p, scopes)
	return p
}

// Provider is the implementation of `goth.Provider` for accessing Twitch
type Provider struct {
	ClientKey    string
	Secret       string
	CallbackURL  string
	HTTPClient   *http.Client
	config       *oauth2.Config
	providerName string
}

// Name gets the name used to retrieve this provider.
func (p *Provider) Name() string {
	return p.providerName
}

// SetName is to update the name of the provider (needed in case of multiple providers of 1 type)
func (p *Provider) SetName(name string) {
	p.providerName = name
}

func (p *Provider) Client() *http.Client {
	return goth.HTTPClientWithFallBack(p.HTTPClient)
}

// Debug is no-op for the Twitch package.
func (p *Provider) Debug(debug bool) {}

// BeginAuth asks Twitch for an authentication end-point.
func (p *Provider) BeginAuth(state string) (goth.Session, error) {
	url := p.config.AuthCodeURL(state)
	s := &Session{
		AuthURL: url,
	}
	return s, nil
}

// FetchUser will go to Twitch and access basic info about the user.
func (p *Provider) FetchUser(session goth.Session) (goth.User, error) {

	s := session.(*Session)

	user := goth.User{
		AccessToken:  s.AccessToken,
		Provider:     p.Name(),
		RefreshToken: s.RefreshToken,
		ExpiresAt:    s.ExpiresAt,
	}

	if user.AccessToken == "" {
		// data is not yet retrieved since accessToken is still empty
		return user, fmt.Errorf("%s cannot get user information without accessToken", p.providerName)
	}

	req, err := http.NewRequest("GET", userEndpoint, nil)
	if err != nil {
		return user, err
	}
	req.Header.Set("Accept", "application/vnd.twitchtv.v3+json")
	req.Header.Set("Authorization", "OAuth "+s.AccessToken)
	resp, err := p.Client().Do(req)
	if err != nil {
		return user, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return user, fmt.Errorf("%s responded with a %d trying to fetch user information", p.providerName, resp.StatusCode)
	}

	err = userFromReader(resp.Body, &user)
	return user, err
}

func userFromReader(r io.Reader, user *goth.User) error {
	u := struct {
		Name        string `json:"name"`
		Email       string `json:"email"`
		Nickname    string `json:"display_name"`
		AvatarURL   string `json:"logo"`
		Description string `json:"bio"`
		ID          int    `json:"_id"`
	}{}

	err := json.NewDecoder(r).Decode(&u)
	if err != nil {
		return err
	}

	user.Name = u.Name
	user.Email = u.Email
	user.NickName = u.Nickname
	user.Location = "No location is provided by the Twitch API"
	user.AvatarURL = u.AvatarURL
	user.Description = u.Description
	user.UserID = strconv.Itoa(u.ID)

	return nil
}

func newConfig(p *Provider, scopes []string) *oauth2.Config {
	c := &oauth2.Config{
		ClientID:     p.ClientKey,
		ClientSecret: p.Secret,
		RedirectURL:  p.CallbackURL,
		Endpoint: oauth2.Endpoint{
			AuthURL:  authURL,
			TokenURL: tokenURL,
		},
		Scopes: []string{},
	}

	if len(scopes) > 0 {
		for _, scope := range scopes {
			c.Scopes = append(c.Scopes, scope)
		}
	} else {
		c.Scopes = []string{ScopeUserRead}
	}

	return c
}

//RefreshTokenAvailable refresh token is provided by auth provider or not
func (p *Provider) RefreshTokenAvailable() bool {
	return true
}

//RefreshToken get new access token based on the refresh token
func (p *Provider) RefreshToken(refreshToken string) (*oauth2.Token, error) {
	token := &oauth2.Token{RefreshToken: refreshToken}
	ts := p.config.TokenSource(goth.ContextForClient(p.Client()), token)
	newToken, err := ts.Token()
	if err != nil {
		return nil, err
	}
	return newToken, err
}
<commit_msg>Migrate from v3 Twitch API to v5<commit_after>// Package twitch implements the OAuth2 protocol for authenticating users through Twitch.
// This package can be used as a reference implementation of an OAuth2 provider for Twitch.
package twitch

import (
	"encoding/json"
	"io"
	"net/http"

	"fmt"

	"github.com/markbates/goth"
	"golang.org/x/oauth2"
)

const (
	authURL      string = "https://api.twitch.tv/kraken/oauth2/authorize"
	tokenURL     string = "https://api.twitch.tv/kraken/oauth2/token"
	userEndpoint string = "https://api.twitch.tv/kraken/user"
)

const (
	// ScopeChannelCheckSubscription provides access to read whether a user is
	// subscribed to your channel.
	ScopeChannelCheckSubscription string = "channel_check_subscription"
	// ScopeChannelCommercial provides access to trigger commercials on
	// channel.
	ScopeChannelCommercial string = "channel_commercial"
	// ScopeChannelEditor provides access to write channel metadata
	// (game, status, etc).
	ScopeChannelEditor string = "channel_editor"
	// ScopeChannelFeedEdit provides access to add posts and reactions to a
	// channel feed.
	ScopeChannelFeedEdit string = "channel_feed_edit"
	// ScopeChannelFeedRead provides access to view a channel feed.
	ScopeChannelFeedRead string = "channel_feed_read"
	// ScopeChannelRead provides access to read nonpublic channel information,
	// including email address and stream key.
	ScopeChannelRead string = "channel_read"
	// ScopeChannelStream provides access to reset a channel’s stream key.
	ScopeChannelStream string = "channel_stream"
	// ScopeChannelSubscriptions provides access to read all subscribers to
	// your channel.
	ScopeChannelSubscriptions string = "channel_subscriptions"
	// ScopeCollectionsEdit provides access to manage a user’s collections
	// (of videos).
	ScopeCollectionsEdit string = "collections_edit"
	// ScopeCommunitiesEdit provides access to manage a user’s communities.
	ScopeCommunitiesEdit string = "communities_edit"
	// ScopeCommunitiesModerate provides access to manage community moderators.
	ScopeCommunitiesModerate string = "communities_moderate"
	// ScopeOpenID provides access to use OpenID Connect authentication.
	ScopeOpenID string = "openid"
	// ScopeUserBlocksEdit provides access to turn on/off ignoring a user.
	// Ignoring users means you cannot see them type, receive messages from
	// them, etc.
	ScopeUserBlocksEdit string = "user_blocks_edit"
	// ScopeUserBlocksRead provides access to read a user’s list of ignored
	// users.
	ScopeUserBlocksRead string = "user_blocks_read"
	// ScopeUserFollowsEdit provides access to manage a user’s followed
	// channels.
	ScopeUserFollowsEdit string = "user_follows_edit"
	// ScopeUserRead provides access to read nonpublic user information, like
	// email address.
	ScopeUserRead string = "user_read"
	// ScopeUserSubscriptions provides access to read a user’s subscriptions.
	ScopeUserSubscriptions string = "user_subscriptions"
	// ScopeViewingActivityRead provides access to turn on Viewer Heartbeat
	// Service ability to record user data.
	ScopeViewingActivityRead string = "viewing_activity_read"
)

// New creates a new Twitch provider, and sets up important connection details.
// You should always call `twitch.New` to get a new Provider. Never try to create
// one manually.
func New(clientKey string, secret string, callbackURL string, scopes ...string) *Provider {
	p := &Provider{
		ClientKey:    clientKey,
		Secret:       secret,
		CallbackURL:  callbackURL,
		providerName: "twitch",
	}
	p.config = newConfig(p, scopes)
	return p
}

// Provider is the implementation of `goth.Provider` for accessing Twitch
type Provider struct {
	ClientKey    string
	Secret       string
	CallbackURL  string
	HTTPClient   *http.Client
	config       *oauth2.Config
	providerName string
}

// Name gets the name used to retrieve this provider.
func (p *Provider) Name() string {
	return p.providerName
}

// SetName is to update the name of the provider (needed in case of multiple providers of 1 type)
func (p *Provider) SetName(name string) {
	p.providerName = name
}

// Client ...
func (p *Provider) Client() *http.Client {
	return goth.HTTPClientWithFallBack(p.HTTPClient)
}

// Debug is no-op for the Twitch package.
func (p *Provider) Debug(debug bool) {}

// BeginAuth asks Twitch for an authentication end-point.
func (p *Provider) BeginAuth(state string) (goth.Session, error) {
	url := p.config.AuthCodeURL(state)
	s := &Session{
		AuthURL: url,
	}
	return s, nil
}

// FetchUser will go to Twitch and access basic info about the user.
func (p *Provider) FetchUser(session goth.Session) (goth.User, error) {

	s := session.(*Session)

	user := goth.User{
		AccessToken:  s.AccessToken,
		Provider:     p.Name(),
		RefreshToken: s.RefreshToken,
		ExpiresAt:    s.ExpiresAt,
	}

	if user.AccessToken == "" {
		// data is not yet retrieved since accessToken is still empty
		return user, fmt.Errorf("%s cannot get user information without accessToken", p.providerName)
	}

	req, err := http.NewRequest("GET", userEndpoint, nil)
	if err != nil {
		return user, err
	}
	req.Header.Set("Accept", "application/vnd.twitchtv.v5+json")
	req.Header.Set("Authorization", "OAuth "+s.AccessToken)
	resp, err := p.Client().Do(req)
	if err != nil {
		return user, err
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return user, fmt.Errorf("%s responded with a %d trying to fetch user information", p.providerName, resp.StatusCode)
	}

	err = userFromReader(resp.Body, &user)
	return user, err
}

func userFromReader(r io.Reader, user *goth.User) error {
	u := struct {
		Name        string `json:"name"`
		Email       string `json:"email"`
		Nickname    string `json:"display_name"`
		AvatarURL   string `json:"logo"`
		Description string `json:"bio"`
		ID          string `json:"_id"`
	}{}

	err := json.NewDecoder(r).Decode(&u)
	if err != nil {
		return err
	}

	user.Name = u.Name
	user.Email = u.Email
	user.NickName = u.Nickname
	user.Location = "No location is provided by the Twitch API"
	user.AvatarURL = u.AvatarURL
	user.Description = u.Description
	user.UserID = u.ID

	return nil
}

func newConfig(p *Provider, scopes []string) *oauth2.Config {
	c := &oauth2.Config{
		ClientID:     p.ClientKey,
		ClientSecret: p.Secret,
		RedirectURL:  p.CallbackURL,
		Endpoint: oauth2.Endpoint{
			AuthURL:  authURL,
			TokenURL: tokenURL,
		},
		Scopes: []string{},
	}

	if len(scopes) > 0 {
		for _, scope := range scopes {
			c.Scopes = append(c.Scopes, scope)
		}
	} else {
		c.Scopes = []string{ScopeUserRead}
	}

	return c
}

//RefreshTokenAvailable refresh token is provided by auth provider or not
func (p *Provider) RefreshTokenAvailable() bool {
	return true
}

//RefreshToken get new access token based on the refresh token
func (p *Provider) RefreshToken(refreshToken string) (*oauth2.Token, error) {
	token := &oauth2.Token{RefreshToken: refreshToken}
	ts := p.config.TokenSource(goth.ContextForClient(p.Client()), token)
	newToken, err := ts.Token()
	if err != nil {
		return nil, err
	}
	return newToken, err
}
<|endoftext|>


<commit_before>// Copyright 2016 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package swarm

import (
	"github.com/fsouza/go-dockerclient"
	"github.com/pkg/errors"
	"github.com/tsuru/tsuru/action"
	"github.com/tsuru/tsuru/app/image"
	"github.com/tsuru/tsuru/log"
	"github.com/tsuru/tsuru/provision"
	"github.com/tsuru/tsuru/set"
)

type pipelineArgs struct {
	client         *docker.Client
	app            provision.App
	newImage       string
	newImgData     *image.ImageMetadata
	currentImage   string
	currentImgData *image.ImageMetadata
}

func rollbackAddedProcesses(args *pipelineArgs, processes []string) {
	for _, processName := range processes {
		var err error
		if _, in := args.currentImgData.Processes[processName]; in {
			err = deploy(args.client, args.app, processName, args.currentImage)
		} else {
			err = removeService(args.client, args.app, processName)
		}
		if err != nil {
			log.Errorf("error rolling back updated service for %s[%s]: %+v", args.app.GetName(), processName, err)
		}
	}
}

var updateServices = &action.Action{
	Name: "update-services",
	Forward: func(ctx action.FWContext) (action.Result, error) {
		args := ctx.Params[0].(*pipelineArgs)
		var deployedProcesses []string
		var err error
		for processName := range args.newImgData.Processes {
			err = deploy(args.client, args.app, processName, args.newImage)
			if err != nil {
				break
			}
			deployedProcesses = append(deployedProcesses, processName)
		}
		if err != nil {
			rollbackAddedProcesses(args, deployedProcesses)
			return nil, err
		}
		return deployedProcesses, nil
	},
	Backward: func(ctx action.BWContext) {
		args := ctx.Params[0].(*pipelineArgs)
		deployedProcesses := ctx.FWResult.([]string)
		rollbackAddedProcesses(args, deployedProcesses)
	},
}

var updateImageInDB = &action.Action{
	Name: "update-image-in-db",
	Forward: func(ctx action.FWContext) (action.Result, error) {
		args := ctx.Params[0].(*pipelineArgs)
		err := image.AppendAppImageName(args.app.GetName(), args.newImage)
		if err != nil {
			return nil, errors.Wrap(err, "")
		}
		return ctx.Previous, nil
	},
}

var removeOldServices = &action.Action{
	Name: "remove-old-services",
	Forward: func(ctx action.FWContext) (action.Result, error) {
		args := ctx.Params[0].(*pipelineArgs)
		old := set.FromMap(args.currentImgData.Processes)
		new := set.FromMap(args.newImgData.Processes)
		for processName := range old.Difference(new) {
			err := removeService(args.client, args.app, processName)
			if err != nil {
				log.Errorf("ignored error removing unwanted service for %s[%s]: %+v", args.app.GetName(), processName, err)
			}
		}
		return nil, nil
	},
}
<commit_msg>provision/swarm: sort processes for deterministic update services action<commit_after>// Copyright 2016 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package swarm

import (
	"sort"

	"github.com/fsouza/go-dockerclient"
	"github.com/pkg/errors"
	"github.com/tsuru/tsuru/action"
	"github.com/tsuru/tsuru/app/image"
	"github.com/tsuru/tsuru/log"
	"github.com/tsuru/tsuru/provision"
	"github.com/tsuru/tsuru/set"
)

type pipelineArgs struct {
	client         *docker.Client
	app            provision.App
	newImage       string
	newImgData     *image.ImageMetadata
	currentImage   string
	currentImgData *image.ImageMetadata
}

func rollbackAddedProcesses(args *pipelineArgs, processes []string) {
	for _, processName := range processes {
		var err error
		if _, in := args.currentImgData.Processes[processName]; in {
			err = deploy(args.client, args.app, processName, args.currentImage)
		} else {
			err = removeService(args.client, args.app, processName)
		}
		if err != nil {
			log.Errorf("error rolling back updated service for %s[%s]: %+v", args.app.GetName(), processName, err)
		}
	}
}

var updateServices = &action.Action{
	Name: "update-services",
	Forward: func(ctx action.FWContext) (action.Result, error) {
		args := ctx.Params[0].(*pipelineArgs)
		var (
			toDeployProcesses []string
			deployedProcesses []string
			err               error
		)
		for processName := range args.newImgData.Processes {
			toDeployProcesses = append(toDeployProcesses, processName)
		}
		sort.Strings(toDeployProcesses)
		for _, processName := range toDeployProcesses {
			err = deploy(args.client, args.app, processName, args.newImage)
			if err != nil {
				break
			}
			deployedProcesses = append(deployedProcesses, processName)
		}
		if err != nil {
			rollbackAddedProcesses(args, deployedProcesses)
			return nil, err
		}
		return deployedProcesses, nil
	},
	Backward: func(ctx action.BWContext) {
		args := ctx.Params[0].(*pipelineArgs)
		deployedProcesses := ctx.FWResult.([]string)
		rollbackAddedProcesses(args, deployedProcesses)
	},
}

var updateImageInDB = &action.Action{
	Name: "update-image-in-db",
	Forward: func(ctx action.FWContext) (action.Result, error) {
		args := ctx.Params[0].(*pipelineArgs)
		err := image.AppendAppImageName(args.app.GetName(), args.newImage)
		if err != nil {
			return nil, errors.Wrap(err, "")
		}
		return ctx.Previous, nil
	},
}

var removeOldServices = &action.Action{
	Name: "remove-old-services",
	Forward: func(ctx action.FWContext) (action.Result, error) {
		args := ctx.Params[0].(*pipelineArgs)
		old := set.FromMap(args.currentImgData.Processes)
		new := set.FromMap(args.newImgData.Processes)
		for processName := range old.Difference(new) {
			err := removeService(args.client, args.app, processName)
			if err != nil {
				log.Errorf("ignored error removing unwanted service for %s[%s]: %+v", args.app.GetName(), processName, err)
			}
		}
		return nil, nil
	},
}
<|endoftext|>


<commit_before>package client

import (
	"github.com/dghubble/sling"
	"github.com/pkg/errors"
)

//AuthAPIClient is the client for the nerdalize authentication server.
type AuthAPIClient struct {
	URL string
}

//NewAuthAPI creates a new AuthAPIClient.
func NewAuthAPI(url string) *AuthAPIClient {
	return &AuthAPIClient{
		URL: url,
	}
}

//GetToken gets a JWT for a given user.
func (auth *AuthAPIClient) GetToken(user, pass string) (string, error) {
	type body struct {
		Token string `json:"token"`
	}
	b := &body{}
	s := sling.New().Get(auth.URL)
	req, err := s.Request()
	if err != nil {
		return "", errors.Wrapf(err, "failed to create request (%v)", auth.URL)
	}
	req.SetBasicAuth(user, pass)
	_, err = s.Do(req, b, nil)
	if err != nil {
		return "", errors.Wrapf(err, "failed to do request (%v)", auth.URL)
	}
	return b.Token, nil
}
<commit_msg>Include token endpoint<commit_after>package client

import (
	"github.com/dghubble/sling"
	"github.com/pkg/errors"
)

const (
	//TokenEndpoint is the endpoint from where to fetch the JWT.
	TokenEndpoint = "token/?service=nce.nerdalize.com"
)

//AuthAPIClient is the client for the nerdalize authentication server.
type AuthAPIClient struct {
	URL string
}

//NewAuthAPI creates a new AuthAPIClient.
func NewAuthAPI(url string) *AuthAPIClient {
	return &AuthAPIClient{
		URL: url,
	}
}

//GetToken gets a JWT for a given user.
func (auth *AuthAPIClient) GetToken(user, pass string) (string, error) {
	type body struct {
		Token string `json:"token"`
	}
	b := &body{}
	s := sling.New().Get(auth.URL + "/" + TokenEndpoint)
	req, err := s.Request()
	if err != nil {
		return "", errors.Wrapf(err, "failed to create request (%v)", auth.URL)
	}
	req.SetBasicAuth(user, pass)
	_, err = s.Do(req, b, nil)
	if err != nil {
		return "", errors.Wrapf(err, "failed to do request (%v)", auth.URL)
	}
	return b.Token, nil
}
<|endoftext|>


<commit_before>package controllers

import (
    "github.com/orc/db"
    "github.com/orc/mvc/models"
    "github.com/orc/sessions"
    "github.com/orc/utils"
    "log"
    "strconv"
)

func (this *Handler) GetHistoryRequest() {
    user_id := sessions.GetValue("id", this.Request)

    if !sessions.CheackSession(this.Response, this.Request) || user_id == nil {
        utils.SendJSReply(map[string]interface{}{"result": "notAuthorized"}, this.Response)
        return
    }

    result := make(map[string]interface{}, 2)
    result["result"] = "ok"

    data, 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(data["event_id"].(string))
    if utils.HandleErr("[Handler::GetHistoryRequest] event_id Atoi: ", err, this.Response) {
        return
    }

    query := `SELECT param_id, params.name, param_types.name as type, param_values.value, forms.id as form_id FROM events
            INNER JOIN events_forms ON events_forms.event_id = events.id
            INNER JOIN forms ON events_forms.form_id = forms.id

            INNER JOIN registrations ON events.id = registrations.event_id
            INNER JOIN reg_param_vals ON reg_param_vals.reg_id = registrations.id

            INNER JOIN faces ON faces.id = registrations.face_id
            INNER JOIN users ON users.id = faces.user_id

            INNER JOIN params ON params.form_id = forms.id
            INNER JOIN param_types ON param_types.id = params.param_type_id
            INNER JOIN param_values ON param_values.param_id = params.id AND reg_param_vals.param_val_id = param_values.id
            WHERE users.id = $1 AND events.id = $2;`

    result["data"] = db.Query(query, []interface{}{user_id, event_id})
    utils.SendJSReply(result, this.Response)
}

func (this *Handler) GetListHistoryEvents() {
    user_id := sessions.GetValue("id", this.Request)

    if !sessions.CheackSession(this.Response, this.Request) || user_id == nil {
        utils.SendJSReply(map[string]interface{}{"result": "notAuthorized"}, this.Response)
        return
    }

    result := make(map[string]interface{}, 2)
    result["result"] = "ok"

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

    ids := make(map[string]interface{}, 1)
    ids["form_id"] = make([]interface{}, 0)
    if len(data["form_ids"].(map[string]interface{})["form_id"].([]interface{})) == 0 {
        result["result"] = "no"
    } else {
        for _, v := range data["form_ids"].(map[string]interface{})["form_id"].([]interface{}) {
            ids["form_id"] = append(ids["form_id"].([]interface{}), int(v.(float64)))
        }

        eventsForms := GetModel("events_forms")
        eventsForms.LoadWherePart(ids)
        eventsForms.SetCondition(models.OR)
        events := db.Select(eventsForms, []string{"event_id"})

        if len(events) != 0 {
            query := `SELECT DISTINCT events.id, events.name FROM events
                INNER JOIN events_forms ON events_forms.event_id = events.id
                INNER JOIN forms ON events_forms.form_id = forms.id
                INNER JOIN registrations ON registrations.event_id = events.id
                INNER JOIN faces ON faces.id = registrations.face_id
                INNER JOIN users ON users.id = faces.user_id
                WHERE users.id=$1 AND events.id IN (`

            var i int
            var params []interface{}
            params = append(params, user_id)

            for i = 2; i < len(events); i++ {
                query += "$" + strconv.Itoa(i) + ", "
                params = append(params, int(events[i-2].(map[string]interface{})["event_id"].(int)))
                log.Println("EVENT_ID: ", strconv.Itoa(int(events[i-2].(map[string]interface{})["event_id"].(int))))
            }

            query += "$" + strconv.Itoa(i) + ")"
            params = append(params, int(events[i-2].(map[string]interface{})["event_id"].(int)))
            result["data"] = db.Query(query, params)
        }
    }

    utils.SendJSReply(result, this.Response)
}

func (this *Handler) SaveUserRequest(token string) {
    var param_val_ids []interface{}
    var result string
    var reg_id int

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

    event_id := int(data["event_id"].(float64))

    if event_id == 1 && sessions.CheackSession(this.Response, this.Request) {
        utils.SendJSReply(map[string]interface{}{"result": "authorized"}, this.Response)
        return
    }

    if sessions.CheackSession(this.Response, this.Request) {
        user_id := sessions.GetValue("id", this.Request)
        if user_id == nil {
            utils.SendJSReply(map[string]interface{}{"result": "notAuthorized"}, this.Response)
            return
        }

        var face_id int
        face := GetModel("faces")
        face.LoadModelData(map[string]interface{}{"user_id": user_id})
        db.QueryInsert_(face, "RETURNING id").Scan(&face_id)

        if token != "nil" {
            if !db.IsExists_("persons", []string{"token"}, []interface{}{token}) {
                utils.SendJSReply(map[string]interface{}{"result": "Неизвестный токен."}, this.Response)
                return
            } else {
                person := GetModel("persons")
                person.LoadModelData(map[string]interface{}{"face_id": face_id})
                person.LoadWherePart(map[string]interface{}{"token": token})
                db.QueryUpdate_(person).Scan()
            }
        }
        log.Println("token:", token)

        registration := GetModel("registrations")
        registration.LoadModelData(map[string]interface{}{"face_id": face_id, "event_id": event_id})
        db.QueryInsert_(registration, "RETURNING id").Scan(&reg_id)

        param_val_ids, _, _, _ = InsertUserParams(data["data"].([]interface{}))

    } else if event_id == 1 {
        var userLogin, userPass, email string
        param_val_ids, userLogin, userPass, email = InsertUserParams(data["data"].([]interface{}))

        result, reg_id = this.HandleRegister_(userLogin, userPass, email, "user")
        if result != "ok" && reg_id == -1 {
            utils.SendJSReply(map[string]interface{}{"result": result}, this.Response)
            return
        }

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

    for _, v := range param_val_ids {
        regParamValue := GetModel("reg_param_vals")
        regParamValue.LoadModelData(map[string]interface{}{
            "reg_id":        reg_id,
            "param_val_id":  v.(map[string]int)["param_val_id"]})
        db.QueryInsert_(regParamValue, "").Scan()
    }

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

func (this *Handler) GetRequest(tableName, id, token string) {
    if !sessions.CheackSession(this.Response, this.Request) && id != "1" {
        this.Render([]string{"mvc/views/loginpage.html", "mvc/views/login.html"}, "loginpage", nil)
        return
    }

        event_id, err := strconv.Atoi(id)
        if utils.HandleErr("[Handler::GetRequestGetRequest] event_id Atoi: ", err, this.Response) {
            return
        }

        query1 := `SELECT forms.id as form_id, forms.name as form_name, params.id as param_id,
                params.name as param_name, param_types.name as type, events.name as event_name,
                events.id as event_id
            FROM events_forms
            INNER JOIN events ON events.id = events_forms.event_id
            INNER JOIN forms ON forms.id = events_forms.form_id
            INNER JOIN params ON forms.id = params.form_id
            INNER JOIN param_types ON param_types.id = params.param_type_id
            WHERE events.id = $1 ORDER BY forms.id, params.id;`

        res1 := db.Query(query1, []interface{}{event_id})

    this.Render([]string{"mvc/views/item.html"}, "item", map[string]interface{}{"data": res1, "token": token})
}

func InsertUserParams(data []interface{}) ([]interface{}, string, string, string) {
    param_val_ids := make([]interface{}, 0)
    userLogin := ""
    userPass := ""
    email := ""

    for _, element := range data {
        param_id, err := strconv.Atoi(element.(map[string]interface{})["id"].(string))
        if err != nil {
            continue
        }

        value := element.(map[string]interface{})["value"].(string)

        if param_id == 1 {
            userLogin = value
            continue
        } else if param_id == 2 || param_id == 3 {
            userPass = value
            continue
        } else if param_id == 4 {
            email = value
        }

        var param_val_id int
        paramValues := GetModel("param_values")
        paramValues.LoadModelData(map[string]interface{}{"param_id": param_id, "value": value})
        db.QueryInsert_(paramValues, "RETURNING id").Scan(&param_val_id)
        param_val_ids = append(param_val_ids, map[string]int{"param_val_id": param_val_id})
    }

    return param_val_ids, userLogin, userPass, email
}
<commit_msg>save login<commit_after>package controllers

import (
    "github.com/orc/db"
    "github.com/orc/mvc/models"
    "github.com/orc/sessions"
    "github.com/orc/utils"
    "log"
    "strconv"
)

func (this *Handler) GetHistoryRequest() {
    user_id := sessions.GetValue("id", this.Request)

    if !sessions.CheackSession(this.Response, this.Request) || user_id == nil {
        utils.SendJSReply(map[string]interface{}{"result": "notAuthorized"}, this.Response)
        return
    }

    result := make(map[string]interface{}, 2)
    result["result"] = "ok"

    data, 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(data["event_id"].(string))
    if utils.HandleErr("[Handler::GetHistoryRequest] event_id Atoi: ", err, this.Response) {
        return
    }

    query := `SELECT param_id, params.name, param_types.name as type, param_values.value, forms.id as form_id FROM events
            INNER JOIN events_forms ON events_forms.event_id = events.id
            INNER JOIN forms ON events_forms.form_id = forms.id

            INNER JOIN registrations ON events.id = registrations.event_id
            INNER JOIN reg_param_vals ON reg_param_vals.reg_id = registrations.id

            INNER JOIN faces ON faces.id = registrations.face_id
            INNER JOIN users ON users.id = faces.user_id

            INNER JOIN params ON params.form_id = forms.id
            INNER JOIN param_types ON param_types.id = params.param_type_id
            INNER JOIN param_values ON param_values.param_id = params.id AND reg_param_vals.param_val_id = param_values.id
            WHERE users.id = $1 AND events.id = $2;`

    result["data"] = db.Query(query, []interface{}{user_id, event_id})
    utils.SendJSReply(result, this.Response)
}

func (this *Handler) GetListHistoryEvents() {
    user_id := sessions.GetValue("id", this.Request)

    if !sessions.CheackSession(this.Response, this.Request) || user_id == nil {
        utils.SendJSReply(map[string]interface{}{"result": "notAuthorized"}, this.Response)
        return
    }

    result := make(map[string]interface{}, 2)
    result["result"] = "ok"

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

    ids := make(map[string]interface{}, 1)
    ids["form_id"] = make([]interface{}, 0)
    if len(data["form_ids"].(map[string]interface{})["form_id"].([]interface{})) == 0 {
        result["result"] = "no"
    } else {
        for _, v := range data["form_ids"].(map[string]interface{})["form_id"].([]interface{}) {
            ids["form_id"] = append(ids["form_id"].([]interface{}), int(v.(float64)))
        }

        eventsForms := GetModel("events_forms")
        eventsForms.LoadWherePart(ids)
        eventsForms.SetCondition(models.OR)
        events := db.Select(eventsForms, []string{"event_id"})

        if len(events) != 0 {
            query := `SELECT DISTINCT events.id, events.name FROM events
                INNER JOIN events_forms ON events_forms.event_id = events.id
                INNER JOIN forms ON events_forms.form_id = forms.id
                INNER JOIN registrations ON registrations.event_id = events.id
                INNER JOIN faces ON faces.id = registrations.face_id
                INNER JOIN users ON users.id = faces.user_id
                WHERE users.id=$1 AND events.id IN (`

            var i int
            var params []interface{}
            params = append(params, user_id)

            for i = 2; i < len(events); i++ {
                query += "$" + strconv.Itoa(i) + ", "
                params = append(params, int(events[i-2].(map[string]interface{})["event_id"].(int)))
                log.Println("EVENT_ID: ", strconv.Itoa(int(events[i-2].(map[string]interface{})["event_id"].(int))))
            }

            query += "$" + strconv.Itoa(i) + ")"
            params = append(params, int(events[i-2].(map[string]interface{})["event_id"].(int)))
            result["data"] = db.Query(query, params)
        }
    }

    utils.SendJSReply(result, this.Response)
}

func (this *Handler) SaveUserRequest(token string) {
    var param_val_ids []interface{}
    var result string
    var reg_id int

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

    event_id := int(data["event_id"].(float64))

    if event_id == 1 && sessions.CheackSession(this.Response, this.Request) {
        utils.SendJSReply(map[string]interface{}{"result": "authorized"}, this.Response)
        return
    }

    if sessions.CheackSession(this.Response, this.Request) {
        user_id := sessions.GetValue("id", this.Request)
        if user_id == nil {
            utils.SendJSReply(map[string]interface{}{"result": "notAuthorized"}, this.Response)
            return
        }

        var face_id int
        face := GetModel("faces")
        face.LoadModelData(map[string]interface{}{"user_id": user_id})
        db.QueryInsert_(face, "RETURNING id").Scan(&face_id)

        if token != "nil" {
            if !db.IsExists_("persons", []string{"token"}, []interface{}{token}) {
                utils.SendJSReply(map[string]interface{}{"result": "Неизвестный токен."}, this.Response)
                return
            } else {
                person := GetModel("persons")
                person.LoadModelData(map[string]interface{}{"face_id": face_id})
                person.LoadWherePart(map[string]interface{}{"token": token})
                db.QueryUpdate_(person).Scan()
            }
        }
        log.Println("token:", token)

        registration := GetModel("registrations")
        registration.LoadModelData(map[string]interface{}{"face_id": face_id, "event_id": event_id})
        db.QueryInsert_(registration, "RETURNING id").Scan(&reg_id)

        param_val_ids, _, _, _ = InsertUserParams(data["data"].([]interface{}))

    } else if event_id == 1 {
        var userLogin, userPass, email string
        param_val_ids, userLogin, userPass, email = InsertUserParams(data["data"].([]interface{}))

        result, reg_id = this.HandleRegister_(userLogin, userPass, email, "user")
        if result != "ok" && reg_id == -1 {
            utils.SendJSReply(map[string]interface{}{"result": result}, this.Response)
            return
        }

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

    for _, v := range param_val_ids {
        regParamValue := GetModel("reg_param_vals")
        regParamValue.LoadModelData(map[string]interface{}{
            "reg_id":        reg_id,
            "param_val_id":  v.(map[string]int)["param_val_id"]})
        db.QueryInsert_(regParamValue, "").Scan()
    }

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

func (this *Handler) GetRequest(tableName, id, token string) {
    if !sessions.CheackSession(this.Response, this.Request) && id != "1" {
        this.Render([]string{"mvc/views/loginpage.html", "mvc/views/login.html"}, "loginpage", nil)
        return
    }

        event_id, err := strconv.Atoi(id)
        if utils.HandleErr("[Handler::GetRequestGetRequest] event_id Atoi: ", err, this.Response) {
            return
        }

        query1 := `SELECT forms.id as form_id, forms.name as form_name, params.id as param_id,
                params.name as param_name, param_types.name as type, events.name as event_name,
                events.id as event_id
            FROM events_forms
            INNER JOIN events ON events.id = events_forms.event_id
            INNER JOIN forms ON forms.id = events_forms.form_id
            INNER JOIN params ON forms.id = params.form_id
            INNER JOIN param_types ON param_types.id = params.param_type_id
            WHERE events.id = $1 ORDER BY forms.id, params.id;`

        res1 := db.Query(query1, []interface{}{event_id})

    this.Render([]string{"mvc/views/item.html"}, "item", map[string]interface{}{"data": res1, "token": token})
}

func InsertUserParams(data []interface{}) ([]interface{}, string, string, string) {
    param_val_ids := make([]interface{}, 0)
    userLogin := ""
    userPass := ""
    email := ""

    for _, element := range data {
        param_id, err := strconv.Atoi(element.(map[string]interface{})["id"].(string))
        if err != nil {
            continue
        }

        value := element.(map[string]interface{})["value"].(string)

        if param_id == 1 {
            userLogin = value
        } else if param_id == 2 || param_id == 3 {
            userPass = value
            continue
        } else if param_id == 4 {
            email = value
        }

        var param_val_id int
        paramValues := GetModel("param_values")
        paramValues.LoadModelData(map[string]interface{}{"param_id": param_id, "value": value})
        db.QueryInsert_(paramValues, "RETURNING id").Scan(&param_val_id)
        param_val_ids = append(param_val_ids, map[string]int{"param_val_id": param_val_id})
    }

    return param_val_ids, userLogin, userPass, email
}
<|endoftext|>


<commit_before>// Copyright Microsoft Corp.
// All rights reserved.

package network

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"
	"net/http/httptest"
	"os"
	"testing"

	remoteApi "github.com/docker/libnetwork/drivers/remote/api"
)

var plugin NetPlugin
var mux *http.ServeMux

// Wraps the test run with plugin setup and teardown.
func TestMain(m *testing.M) {
	var err error

	// Create the plugin.
	plugin, err = NewPlugin("test", "")
	if err != nil {
		fmt.Printf("Failed to create network plugin %v\n", err)
		return
	}

	err = plugin.Start(nil)
	if err != nil {
		fmt.Printf("Failed to start network plugin %v\n", err)
		return
	}

	// Get the internal http mux as test hook.
	mux = plugin.(*netPlugin).Listener.GetMux()

	// Run tests.
	exitCode := m.Run()

	// Cleanup.
	plugin.Stop()

	os.Exit(exitCode)
}

// Decodes plugin's responses to test requests.
func decodeResponse(w *httptest.ResponseRecorder, response interface{}) error {
	if w.Code != http.StatusOK {
		return fmt.Errorf("Request failed with HTTP error %s", w.Code)
	}

	if w.Body == nil {
		return fmt.Errorf("Response body is empty")
	}

	return json.NewDecoder(w.Body).Decode(&response)
}

//
// Libnetwork remote API compliance tests
// https://github.com/docker/libnetwork/blob/master/docs/remote.md
//

// Tests Plugin.Activate functionality.
func TestActivate(t *testing.T) {
	fmt.Println("Test: Activate")

	var resp struct {
		Implements []string
	}

	req, err := http.NewRequest(http.MethodGet, "/Plugin.Activate", nil)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil || resp.Implements[0] != "NetworkDriver" {
		t.Errorf("Activate response is invalid %+v", resp)
	}
}

// Tests NetworkDriver.GetCapabilities functionality.
func TestGetCapabilities(t *testing.T) {
	fmt.Println("Test: GetCapabilities")

	var resp remoteApi.GetCapabilityResponse

	req, err := http.NewRequest(http.MethodGet, getCapabilitiesPath, nil)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil || resp.Err != "" || resp.Scope != "local" {
		t.Errorf("GetCapabilities response is invalid %+v", resp)
	}
}

// Tests NetworkDriver.CreateNetwork functionality.
func TestCreateNetwork(t *testing.T) {
	fmt.Println("Test: CreateNetwork")

	var body bytes.Buffer
	var resp remoteApi.CreateNetworkResponse

	info := &remoteApi.CreateNetworkRequest{
		NetworkID: "N1",
	}

	json.NewEncoder(&body).Encode(info)

	req, err := http.NewRequest(http.MethodGet, createNetworkPath, &body)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil || resp.Err != "" {
		t.Errorf("CreateNetwork response is invalid %+v", resp)
	}
}

// Tests NetworkDriver.DeleteNetwork functionality.
func TestDeleteNetwork(t *testing.T) {
	fmt.Println("Test: DeleteNetwork")

	var body bytes.Buffer
	var resp remoteApi.DeleteNetworkResponse

	info := &remoteApi.DeleteNetworkRequest{
		NetworkID: "N1",
	}

	json.NewEncoder(&body).Encode(info)

	req, err := http.NewRequest(http.MethodGet, deleteNetworkPath, &body)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil || resp.Err != "" {
		t.Errorf("DeleteNetwork response is invalid %+v", resp)
	}
}

// Tests NetworkDriver.EndpointOperInfo functionality.
func TestEndpointOperInfo(t *testing.T) {
	fmt.Println("Test: EndpointOperInfo")

	var body bytes.Buffer
	var resp remoteApi.EndpointInfoResponse

	info := &remoteApi.EndpointInfoRequest{
		NetworkID:  "N1",
		EndpointID: "E1",
	}

	json.NewEncoder(&body).Encode(info)

	req, err := http.NewRequest(http.MethodGet, endpointOperInfoPath, &body)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil {
		t.Errorf("EndpointOperInfo response is invalid %+v", resp)
	}
}
<commit_msg>Updated net plugin tests to use dummy interface<commit_after>// Copyright Microsoft Corp.
// All rights reserved.

package network

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net"
	"net/http"
	"net/http/httptest"
	"os"
	"testing"

	"github.com/Azure/Aqua/common"
	"github.com/Azure/Aqua/netlink"
	driverApi "github.com/docker/libnetwork/driverapi"
	remoteApi "github.com/docker/libnetwork/drivers/remote/api"
)

var plugin NetPlugin
var mux *http.ServeMux

var anyInterface = "test0"
var anySubnet = "192.168.1.0/24"

// Wraps the test run with plugin setup and teardown.
func TestMain(m *testing.M) {
	var config common.PluginConfig
	var err error

	// Create the plugin.
	plugin, err = NewPlugin(&config)
	if err != nil {
		fmt.Printf("Failed to create network plugin %v\n", err)
		os.Exit(1)
	}

	// Configure test mode.
	plugin.(*netPlugin).Name = "test"

	// Start the plugin.
	err = plugin.Start(&config)
	if err != nil {
		fmt.Printf("Failed to start network plugin %v\n", err)
		os.Exit(2)
	}

	// Create a dummy test network interface.
	err = netlink.AddLink(anyInterface, "dummy")
	if err != nil {
		fmt.Printf("Failed to create test network interface, err:%v.\n", err)
		os.Exit(3)
	}

	err = plugin.(*netPlugin).nm.AddExternalInterface(anyInterface, anySubnet)
	if err != nil {
		fmt.Printf("Failed to add test network interface, err:%v.\n", err)
		os.Exit(4)
	}

	// Get the internal http mux as test hook.
	mux = plugin.(*netPlugin).Listener.GetMux()

	// Run tests.
	exitCode := m.Run()

	// Cleanup.
	netlink.DeleteLink(anyInterface)
	plugin.Stop()

	os.Exit(exitCode)
}

// Decodes plugin's responses to test requests.
func decodeResponse(w *httptest.ResponseRecorder, response interface{}) error {
	if w.Code != http.StatusOK {
		return fmt.Errorf("Request failed with HTTP error %s", w.Code)
	}

	if w.Body == nil {
		return fmt.Errorf("Response body is empty")
	}

	return json.NewDecoder(w.Body).Decode(&response)
}

//
// Libnetwork remote API compliance tests
// https://github.com/docker/libnetwork/blob/master/docs/remote.md
//

// Tests Plugin.Activate functionality.
func TestActivate(t *testing.T) {
	fmt.Println("Test: Activate")

	var resp struct {
		Implements []string
	}

	req, err := http.NewRequest(http.MethodGet, "/Plugin.Activate", nil)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil || resp.Implements[0] != "NetworkDriver" {
		t.Errorf("Activate response is invalid %+v", resp)
	}
}

// Tests NetworkDriver.GetCapabilities functionality.
func TestGetCapabilities(t *testing.T) {
	fmt.Println("Test: GetCapabilities")

	var resp remoteApi.GetCapabilityResponse

	req, err := http.NewRequest(http.MethodGet, getCapabilitiesPath, nil)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil || resp.Err != "" || resp.Scope != "local" {
		t.Errorf("GetCapabilities response is invalid %+v", resp)
	}
}

// Tests NetworkDriver.CreateNetwork functionality.
func TestCreateNetwork(t *testing.T) {
	fmt.Println("Test: CreateNetwork")

	var body bytes.Buffer
	var resp remoteApi.CreateNetworkResponse

	_, pool, _ := net.ParseCIDR(anySubnet)

	info := &remoteApi.CreateNetworkRequest{
		NetworkID: "N1",
		IPv4Data: []driverApi.IPAMData{
			{
				Pool: pool,
			},
		},
	}

	json.NewEncoder(&body).Encode(info)

	req, err := http.NewRequest(http.MethodGet, createNetworkPath, &body)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil || resp.Err != "" {
		t.Errorf("CreateNetwork response is invalid %+v", resp)
	}
}

// Tests NetworkDriver.DeleteNetwork functionality.
func TestDeleteNetwork(t *testing.T) {
	fmt.Println("Test: DeleteNetwork")

	var body bytes.Buffer
	var resp remoteApi.DeleteNetworkResponse

	info := &remoteApi.DeleteNetworkRequest{
		NetworkID: "N1",
	}

	json.NewEncoder(&body).Encode(info)

	req, err := http.NewRequest(http.MethodGet, deleteNetworkPath, &body)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil || resp.Err != "" {
		t.Errorf("DeleteNetwork response is invalid %+v", resp)
	}
}

// Tests NetworkDriver.EndpointOperInfo functionality.
func TestEndpointOperInfo(t *testing.T) {
	fmt.Println("Test: EndpointOperInfo")

	var body bytes.Buffer
	var resp remoteApi.EndpointInfoResponse

	info := &remoteApi.EndpointInfoRequest{
		NetworkID:  "N1",
		EndpointID: "E1",
	}

	json.NewEncoder(&body).Encode(info)

	req, err := http.NewRequest(http.MethodGet, endpointOperInfoPath, &body)
	if err != nil {
		t.Fatal(err)
	}

	w := httptest.NewRecorder()
	mux.ServeHTTP(w, req)

	err = decodeResponse(w, &resp)

	if err != nil {
		t.Errorf("EndpointOperInfo response is invalid %+v", resp)
	}
}
<|endoftext|>


<commit_before>// The htmldrill package implements a drill/filesys.Handler for the HTML format.
// Drill nodes are delimited by "section" elements. Unordered nodes are
// implemented as section elements with the "data-name" attribute.
package htmldrill

import (
	"bytes"
	"io"
	"io/fs"

	"github.com/PuerkitoBio/goquery"
	"github.com/anaminus/drill"
	"github.com/anaminus/drill/filesys"
	"github.com/andybalholm/cascadia"
	"golang.org/x/net/html"
)

// Renderer renders a selection, writing the result to w.
type Renderer func(w io.Writer, s *goquery.Selection) error

// config holds options
type config struct {
	parseOptions []html.ParseOption
	renderer     Renderer
}

// Option configures the package's filesys handler.
type Option func(*config)

// WithParseOptions configures how a handler parses HTML.
func WithParseOptions(opts ...html.ParseOption) Option {
	return func(cfg *config) {
		cfg.parseOptions = append(cfg.parseOptions, opts...)
	}
}

// WithRenderer configures a handler to return nodes that use the given
// renderer.
func WithRenderer(renderer Renderer) Option {
	return func(cfg *config) {
		cfg.renderer = renderer
	}
}

// NewHandler returns a filesys.HandlerFunc that parses a file as an HTML
// document.
func NewHandler(opts ...Option) filesys.HandlerFunc {
	var cfg config
	for _, opt := range opts {
		opt(&cfg)
	}
	return func(fsys fs.FS, name string) drill.Node {
		b, err := fs.ReadFile(fsys, name)
		if err != nil {
			return nil
		}
		root, err := html.ParseWithOptions(bytes.NewBuffer(b), cfg.parseOptions...)
		if err != nil {
			return nil
		}
		doc := goquery.NewDocumentFromNode(root)
		StripComments(doc.Selection)
		FixTemplateDirectives(doc.Selection)
		return NewNode(doc, cfg.renderer)
	}
}

const (
	sectionName = "section"   // Section element name.
	sectionAttr = "data-name" // Section element attribute name.
)

var bodyMatcher = goquery.SingleMatcher(cascadia.MustCompile("body"))
var sectionMatcher = cascadia.MustCompile(sectionName)
var usectionMatcher = cascadia.MustCompile(sectionName + "[" + sectionAttr + "]")

// Node implements drill.Node.
type Node struct {
	document  *goquery.Document
	selection *goquery.Selection
	renderer  Renderer
}

// NewNode returns a Node that wraps the given goquery.Document and optional
// renderer.
func NewNode(doc *goquery.Document, renderer Renderer) *Node {
	return &Node{
		document:  doc,
		selection: doc.FindMatcher(bodyMatcher).First(),
		renderer:  renderer,
	}
}

// derive returns a Node that wraps selection instead of the selection from n.
func (n *Node) derive(selection *goquery.Selection) *Node {
	d := *n
	d.selection = selection
	return &d
}

// Document returns the root goquery.Document.
func (n *Node) Document() *goquery.Document {
	return n.document
}

// Selection returns the wrapped goquery.Selection.
func (n *Node) Selection() *goquery.Selection {
	return n.selection
}

func (n *Node) ochildren() *goquery.Selection {
	return n.selection.ChildrenMatcher(sectionMatcher)
}

func (n *Node) uchildren() *goquery.Selection {
	return n.selection.ChildrenMatcher(usectionMatcher)
}

// Fragment renders the wrapped node as a string using the node's renderer, or
// goquery.Render if the node has no renderer. Returns an empty string if an
// error occurs.
func (n *Node) Fragment() string {
	renderer := n.renderer
	if renderer == nil {
		renderer = goquery.Render
	}
	var buf bytes.Buffer
	if err := renderer(&buf, n.selection); err != nil {
		return ""
	}
	return buf.String()
}

// render renders n to w.
func render(n *Node, w *io.PipeWriter) {
	renderer := n.renderer
	if renderer == nil {
		renderer = goquery.Render
	}
	if err := renderer(w, n.selection); err != nil {
		w.CloseWithError(err)
	}
	w.Close()
}

// FragmentReader returns a ReadCloser that renders the wrapped node according
// the node's renderer, or goquery.Render if the node has no renderer. Errors
// are passed to the reader.
func (n *Node) FragmentReader() (r io.ReadCloser, err error) {
	r, w := io.Pipe()
	go render(n, w)
	return r, nil
}

// WithRenderer returns a copy of the node that uses the given renderer. r may
// be nil.
func (n *Node) WithRenderer(r Renderer) *Node {
	d := *n
	d.renderer = r
	return &d
}

// Len returns the number of child section elements.
func (n *Node) Len() int {
	return n.ochildren().Length()
}

func (n *Node) orderedChild(i int) *Node {
	children := n.ochildren()
	if i = drill.Index(i, children.Length()); i < 0 {
		return nil
	}
	return n.derive(children.Eq(i))
}

// OrderedChild returns a Node that wraps the ordered child section element at
// index i. Returns nil if the index is out of bounds.
func (n *Node) OrderedChild(i int) drill.Node {
	node := n.orderedChild(i)
	if node == nil {
		return nil
	}
	return node
}

// OrderedChildren returns a list of Nodes that wrap each ordered child Section.
func (n *Node) OrderedChildren() []drill.Node {
	var sections []drill.Node
	n.ochildren().Each(func(i int, s *goquery.Selection) {
		sections = append(sections, n.derive(s))
	})
	return sections
}

func (n *Node) unorderedChild(name string) *Node {
	var selection *goquery.Selection
	n.uchildren().EachWithBreak(func(i int, s *goquery.Selection) bool {
		if value, ok := s.Attr(sectionAttr); !ok || value != name {
			return true
		}
		selection = s
		return false
	})
	if selection == nil {
		return nil
	}
	return n.derive(selection)
}

// UnorderedChild returns a Node that wraps the unordered child section element
// whose data-name attribute is equal to name.
func (n *Node) UnorderedChild(name string) drill.Node {
	node := n.unorderedChild(name)
	if node == nil {
		return nil
	}
	return node
}

// UnorderedChildren returns a map of names to Nodes that wrap each unordered
// child section element.
func (n *Node) UnorderedChildren() map[string]drill.Node {
	children := n.uchildren()
	sections := make(map[string]drill.Node, children.Length())
	children.Each(func(i int, s *goquery.Selection) {
		if value, ok := s.Attr(sectionAttr); ok {
			sections[value] = n.derive(s)
		}
	})
	return sections
}

// Descend recursively descends into the unordered child section elements
// matching each given name. Returns nil if a child could not be found at any
// point.
func (n *Node) Descend(names ...string) drill.Node {
	for _, name := range names {
		node := n.unorderedChild(name)
		if node == nil {
			return nil
		}
		n = node
	}
	return n
}

// Query recursively descends into the child nodes that match the given queries.
// A query is either a string or an int. If an int, then the next node is
// acquired using the OrderedChild method of the current node. If a string, then
// the next node is acquired using the UnorderedChild method of the current
// node. Returns nil if a child could not be found at any point.
func (n *Node) Query(queries ...interface{}) drill.Node {
	for _, query := range queries {
		switch q := query.(type) {
		case string:
			node := n.unorderedChild(q)
			if node == nil {
				return nil
			}
			n = node
		case int:
			node := n.orderedChild(q)
			if node == nil {
				return nil
			}
			n = node
		default:
			return nil
		}
	}
	return n
}
<commit_msg>Export Node.Derive.<commit_after>// The htmldrill package implements a drill/filesys.Handler for the HTML format.
// Drill nodes are delimited by "section" elements. Unordered nodes are
// implemented as section elements with the "data-name" attribute.
package htmldrill

import (
	"bytes"
	"io"
	"io/fs"

	"github.com/PuerkitoBio/goquery"
	"github.com/anaminus/drill"
	"github.com/anaminus/drill/filesys"
	"github.com/andybalholm/cascadia"
	"golang.org/x/net/html"
)

// Renderer renders a selection, writing the result to w.
type Renderer func(w io.Writer, s *goquery.Selection) error

// config holds options
type config struct {
	parseOptions []html.ParseOption
	renderer     Renderer
}

// Option configures the package's filesys handler.
type Option func(*config)

// WithParseOptions configures how a handler parses HTML.
func WithParseOptions(opts ...html.ParseOption) Option {
	return func(cfg *config) {
		cfg.parseOptions = append(cfg.parseOptions, opts...)
	}
}

// WithRenderer configures a handler to return nodes that use the given
// renderer.
func WithRenderer(renderer Renderer) Option {
	return func(cfg *config) {
		cfg.renderer = renderer
	}
}

// NewHandler returns a filesys.HandlerFunc that parses a file as an HTML
// document.
func NewHandler(opts ...Option) filesys.HandlerFunc {
	var cfg config
	for _, opt := range opts {
		opt(&cfg)
	}
	return func(fsys fs.FS, name string) drill.Node {
		b, err := fs.ReadFile(fsys, name)
		if err != nil {
			return nil
		}
		root, err := html.ParseWithOptions(bytes.NewBuffer(b), cfg.parseOptions...)
		if err != nil {
			return nil
		}
		doc := goquery.NewDocumentFromNode(root)
		StripComments(doc.Selection)
		FixTemplateDirectives(doc.Selection)
		return NewNode(doc, cfg.renderer)
	}
}

const (
	sectionName = "section"   // Section element name.
	sectionAttr = "data-name" // Section element attribute name.
)

var bodyMatcher = goquery.SingleMatcher(cascadia.MustCompile("body"))
var sectionMatcher = cascadia.MustCompile(sectionName)
var usectionMatcher = cascadia.MustCompile(sectionName + "[" + sectionAttr + "]")

// Node implements drill.Node.
type Node struct {
	document  *goquery.Document
	selection *goquery.Selection
	renderer  Renderer
}

// NewNode returns a Node that wraps the given goquery.Document and optional
// renderer.
func NewNode(doc *goquery.Document, renderer Renderer) *Node {
	return &Node{
		document:  doc,
		selection: doc.FindMatcher(bodyMatcher).First(),
		renderer:  renderer,
	}
}

// Derive returns a Node that wraps selection instead of the selection from n.
func (n *Node) Derive(selection *goquery.Selection) *Node {
	d := *n
	d.selection = selection
	return &d
}

// Document returns the root goquery.Document.
func (n *Node) Document() *goquery.Document {
	return n.document
}

// Selection returns the wrapped goquery.Selection.
func (n *Node) Selection() *goquery.Selection {
	return n.selection
}

func (n *Node) ochildren() *goquery.Selection {
	return n.selection.ChildrenMatcher(sectionMatcher)
}

func (n *Node) uchildren() *goquery.Selection {
	return n.selection.ChildrenMatcher(usectionMatcher)
}

// Fragment renders the wrapped node as a string using the node's renderer, or
// goquery.Render if the node has no renderer. Returns an empty string if an
// error occurs.
func (n *Node) Fragment() string {
	renderer := n.renderer
	if renderer == nil {
		renderer = goquery.Render
	}
	var buf bytes.Buffer
	if err := renderer(&buf, n.selection); err != nil {
		return ""
	}
	return buf.String()
}

// render renders n to w.
func render(n *Node, w *io.PipeWriter) {
	renderer := n.renderer
	if renderer == nil {
		renderer = goquery.Render
	}
	if err := renderer(w, n.selection); err != nil {
		w.CloseWithError(err)
	}
	w.Close()
}

// FragmentReader returns a ReadCloser that renders the wrapped node according
// the node's renderer, or goquery.Render if the node has no renderer. Errors
// are passed to the reader.
func (n *Node) FragmentReader() (r io.ReadCloser, err error) {
	r, w := io.Pipe()
	go render(n, w)
	return r, nil
}

// WithRenderer returns a copy of the node that uses the given renderer. r may
// be nil.
func (n *Node) WithRenderer(r Renderer) *Node {
	d := *n
	d.renderer = r
	return &d
}

// Len returns the number of child section elements.
func (n *Node) Len() int {
	return n.ochildren().Length()
}

func (n *Node) orderedChild(i int) *Node {
	children := n.ochildren()
	if i = drill.Index(i, children.Length()); i < 0 {
		return nil
	}
	return n.Derive(children.Eq(i))
}

// OrderedChild returns a Node that wraps the ordered child section element at
// index i. Returns nil if the index is out of bounds.
func (n *Node) OrderedChild(i int) drill.Node {
	node := n.orderedChild(i)
	if node == nil {
		return nil
	}
	return node
}

// OrderedChildren returns a list of Nodes that wrap each ordered child Section.
func (n *Node) OrderedChildren() []drill.Node {
	var sections []drill.Node
	n.ochildren().Each(func(i int, s *goquery.Selection) {
		sections = append(sections, n.Derive(s))
	})
	return sections
}

func (n *Node) unorderedChild(name string) *Node {
	var selection *goquery.Selection
	n.uchildren().EachWithBreak(func(i int, s *goquery.Selection) bool {
		if value, ok := s.Attr(sectionAttr); !ok || value != name {
			return true
		}
		selection = s
		return false
	})
	if selection == nil {
		return nil
	}
	return n.Derive(selection)
}

// UnorderedChild returns a Node that wraps the unordered child section element
// whose data-name attribute is equal to name.
func (n *Node) UnorderedChild(name string) drill.Node {
	node := n.unorderedChild(name)
	if node == nil {
		return nil
	}
	return node
}

// UnorderedChildren returns a map of names to Nodes that wrap each unordered
// child section element.
func (n *Node) UnorderedChildren() map[string]drill.Node {
	children := n.uchildren()
	sections := make(map[string]drill.Node, children.Length())
	children.Each(func(i int, s *goquery.Selection) {
		if value, ok := s.Attr(sectionAttr); ok {
			sections[value] = n.Derive(s)
		}
	})
	return sections
}

// Descend recursively descends into the unordered child section elements
// matching each given name. Returns nil if a child could not be found at any
// point.
func (n *Node) Descend(names ...string) drill.Node {
	for _, name := range names {
		node := n.unorderedChild(name)
		if node == nil {
			return nil
		}
		n = node
	}
	return n
}

// Query recursively descends into the child nodes that match the given queries.
// A query is either a string or an int. If an int, then the next node is
// acquired using the OrderedChild method of the current node. If a string, then
// the next node is acquired using the UnorderedChild method of the current
// node. Returns nil if a child could not be found at any point.
func (n *Node) Query(queries ...interface{}) drill.Node {
	for _, query := range queries {
		switch q := query.(type) {
		case string:
			node := n.unorderedChild(q)
			if node == nil {
				return nil
			}
			n = node
		case int:
			node := n.orderedChild(q)
			if node == nil {
				return nil
			}
			n = node
		default:
			return nil
		}
	}
	return n
}
<|endoftext|>


<commit_before>// Copyright 2020 Google LLC
//
// 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
//
// 	https://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 safehttp_test

import (
	"context"
	"github.com/google/go-cmp/cmp"
	"github.com/google/go-safeweb/safehttp"
	"net/http"
	"net/http/httptest"
	"strings"
	"testing"
)

func TestIncomingRequestCookie(t *testing.T) {
	var tests = []struct {
		name      string
		req       *http.Request
		wantName  string
		wantValue string
	}{
		{
			name: "Basic",
			req: func() *http.Request {
				r := httptest.NewRequest(http.MethodGet, "/", nil)
				r.Header.Set("Cookie", "foo=bar")
				return r
			}(),
			wantName:  "foo",
			wantValue: "bar",
		},
		{
			name: "Multiple cookies with the same name",
			req: func() *http.Request {
				r := httptest.NewRequest(http.MethodGet, "/", nil)
				r.Header.Add("Cookie", "foo=bar; foo=xyz")
				r.Header.Add("Cookie", "foo=pizza")
				return r
			}(),
			wantName:  "foo",
			wantValue: "bar",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			ir := safehttp.NewIncomingRequest(tt.req)
			c, err := ir.Cookie(tt.wantName)
			if err != nil {
				t.Errorf(`ir.Cookie(tt.wantName) got: %v want: nil`, err)
			}

			if got := c.Name(); got != tt.wantName {
				t.Errorf("c.Name() got: %v want: %v", got, tt.wantName)
			}

			if got := c.Value(); got != tt.wantValue {
				t.Errorf(`c.Value() got: %v want: %v`, got, tt.wantValue)
			}
		})
	}
}

func TestIncomingRequestCookieNotFound(t *testing.T) {
	r := httptest.NewRequest(http.MethodGet, "/", nil)
	ir := safehttp.NewIncomingRequest(r)
	if _, err := ir.Cookie("foo"); err == nil {
		t.Error(`ir.Cookie("foo") got: nil want: error`)
	}
}

func TestIncomingRequestCookies(t *testing.T) {
	var tests = []struct {
		name       string
		req        *http.Request
		wantNames  []string
		wantValues []string
	}{
		{
			name: "One",
			req: func() *http.Request {
				r := httptest.NewRequest(http.MethodGet, "/", nil)
				r.Header.Set("Cookie", "foo=bar")
				return r
			}(),
			wantNames:  []string{"foo"},
			wantValues: []string{"bar"},
		},
		{
			name: "Multiple",
			req: func() *http.Request {
				r := httptest.NewRequest(http.MethodGet, "/", nil)
				r.Header.Add("Cookie", "foo=bar; a=b")
				r.Header.Add("Cookie", "pizza=hawaii")
				return r
			}(),
			wantNames:  []string{"foo", "a", "pizza"},
			wantValues: []string{"bar", "b", "hawaii"},
		},
		{
			name:       "None",
			req:        httptest.NewRequest(http.MethodGet, "/", nil),
			wantNames:  []string{},
			wantValues: []string{},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			ir := safehttp.NewIncomingRequest(tt.req)
			cl := ir.Cookies()

			if got, want := len(cl), len(tt.wantNames); got != want {
				t.Errorf("len(cl) got: %v want: %v", got, want)
			}

			for i, c := range cl {
				if got := c.Name(); got != tt.wantNames[i] {
					t.Errorf("c.Name() got: %v want: %v", got, tt.wantNames[i])
				}

				if got := c.Value(); got != tt.wantValues[i] {
					t.Errorf(`c.Value() got: %v want: %v`, got, tt.wantValues[i])
				}
			}
		})

	}
}

type pizza struct {
	val string
}

type notPizza struct {
}

type pizzaKey string

func TestRequestSetValidContextWithValue(t *testing.T) {
	tests := []struct {
		name    string
		key     pizzaKey
		wantVal *pizza
		wantOk  bool
	}{
		{
			name:    "Value set for key",
			key:     pizzaKey("1234"),
			wantOk:  true,
			wantVal: &pizza{val: "margeritta"},
		},
		{
			name:    "Value not set for key",
			key:     pizzaKey("5678"),
			wantOk:  false,
			wantVal: nil,
		},
	}
	for _, test := range tests {
		m := safehttp.NewMachinery(func(rw safehttp.ResponseWriter, ir *safehttp.IncomingRequest) safehttp.Result {
			ctx := context.WithValue(ir.Context(), pizzaKey("1234"), &pizza{val: "margeritta"})
			ir.SetContext(ctx)
			got, ok := ir.Context().Value(test.key).(*pizza)
			if ok != test.wantOk {
				t.Errorf("type match: got %v, want %v", ok, test.wantOk)
			}
			if diff := cmp.Diff(test.wantVal, got, cmp.AllowUnexported(pizza{})); diff != "" {
				t.Errorf("ir.Context().Value(k): mismatch (-want +got): \n%s", diff)
			}

			return safehttp.Result{}
		}, &testDispatcher{})

		rec := newResponseRecorder(&strings.Builder{})
		req := httptest.NewRequest("GET", "/", nil)
		m.HandleRequest(rec, req)

		if want := 200; rec.status != want {
			t.Errorf("response status: got %v, want %v", rec.status, want)
		}
	}
}

func TestRequestSetNilContext(t *testing.T) {
	m := safehttp.NewMachinery(func(rw safehttp.ResponseWriter, ir *safehttp.IncomingRequest) safehttp.Result {
		ir.SetContext(nil)
		return safehttp.Result{}
	}, &testDispatcher{})

	defer func() {
		if r := recover(); r == nil {
			t.Errorf(`ir.SetContext(nil): expected panic`)
		}
	}()

	rec := newResponseRecorder(&strings.Builder{})
	req := httptest.NewRequest("GET", "/", nil)
	m.HandleRequest(rec, req)

	if want := 200; rec.status != want {
		t.Errorf("response status: got %v, want %v", rec.status, want)
	}
}
<commit_msg>Refactor tests to not use the safehttp.Machinery<commit_after>// Copyright 2020 Google LLC
//
// 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
//
// 	https://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 safehttp_test

import (
	"context"
	"github.com/google/go-cmp/cmp"
	"github.com/google/go-safeweb/safehttp"
	"net/http"
	"net/http/httptest"
	"testing"
)

func TestIncomingRequestCookie(t *testing.T) {
	var tests = []struct {
		name      string
		req       *http.Request
		wantName  string
		wantValue string
	}{
		{
			name: "Basic",
			req: func() *http.Request {
				r := httptest.NewRequest(http.MethodGet, "/", nil)
				r.Header.Set("Cookie", "foo=bar")
				return r
			}(),
			wantName:  "foo",
			wantValue: "bar",
		},
		{
			name: "Multiple cookies with the same name",
			req: func() *http.Request {
				r := httptest.NewRequest(http.MethodGet, "/", nil)
				r.Header.Add("Cookie", "foo=bar; foo=xyz")
				r.Header.Add("Cookie", "foo=pizza")
				return r
			}(),
			wantName:  "foo",
			wantValue: "bar",
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			ir := safehttp.NewIncomingRequest(tt.req)
			c, err := ir.Cookie(tt.wantName)
			if err != nil {
				t.Errorf(`ir.Cookie(tt.wantName) got: %v want: nil`, err)
			}

			if got := c.Name(); got != tt.wantName {
				t.Errorf("c.Name() got: %v want: %v", got, tt.wantName)
			}

			if got := c.Value(); got != tt.wantValue {
				t.Errorf(`c.Value() got: %v want: %v`, got, tt.wantValue)
			}
		})
	}
}

func TestIncomingRequestCookieNotFound(t *testing.T) {
	r := httptest.NewRequest(http.MethodGet, "/", nil)
	ir := safehttp.NewIncomingRequest(r)
	if _, err := ir.Cookie("foo"); err == nil {
		t.Error(`ir.Cookie("foo") got: nil want: error`)
	}
}

func TestIncomingRequestCookies(t *testing.T) {
	var tests = []struct {
		name       string
		req        *http.Request
		wantNames  []string
		wantValues []string
	}{
		{
			name: "One",
			req: func() *http.Request {
				r := httptest.NewRequest(http.MethodGet, "/", nil)
				r.Header.Set("Cookie", "foo=bar")
				return r
			}(),
			wantNames:  []string{"foo"},
			wantValues: []string{"bar"},
		},
		{
			name: "Multiple",
			req: func() *http.Request {
				r := httptest.NewRequest(http.MethodGet, "/", nil)
				r.Header.Add("Cookie", "foo=bar; a=b")
				r.Header.Add("Cookie", "pizza=hawaii")
				return r
			}(),
			wantNames:  []string{"foo", "a", "pizza"},
			wantValues: []string{"bar", "b", "hawaii"},
		},
		{
			name:       "None",
			req:        httptest.NewRequest(http.MethodGet, "/", nil),
			wantNames:  []string{},
			wantValues: []string{},
		},
	}

	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			ir := safehttp.NewIncomingRequest(tt.req)
			cl := ir.Cookies()

			if got, want := len(cl), len(tt.wantNames); got != want {
				t.Errorf("len(cl) got: %v want: %v", got, want)
			}

			for i, c := range cl {
				if got := c.Name(); got != tt.wantNames[i] {
					t.Errorf("c.Name() got: %v want: %v", got, tt.wantNames[i])
				}

				if got := c.Value(); got != tt.wantValues[i] {
					t.Errorf(`c.Value() got: %v want: %v`, got, tt.wantValues[i])
				}
			}
		})

	}
}

type pizza struct {
	val string
}

type pizzaKey string

func TestRequestSetValidContextWithValue(t *testing.T) {
	tests := []struct {
		name    string
		key     pizzaKey
		wantVal *pizza
		wantOk  bool
	}{
		{
			name:    "Value set for key",
			key:     pizzaKey("1234"),
			wantOk:  true,
			wantVal: &pizza{val: "margeritta"},
		},
		{
			name:    "Value not set for key",
			key:     pizzaKey("5678"),
			wantOk:  false,
			wantVal: nil,
		},
	}
	for _, test := range tests {
		req := httptest.NewRequest("GET", "/", nil)
		ir := safehttp.NewIncomingRequest(req)
		ctx := context.WithValue(ir.Context(), pizzaKey("1234"), &pizza{val: "margeritta"})
		ir.SetContext(ctx)

		got, ok := ir.Context().Value(test.key).(*pizza)
		if ok != test.wantOk {
			t.Errorf("type match: got %v, want %v", ok, test.wantOk)
		}
		if diff := cmp.Diff(test.wantVal, got, cmp.AllowUnexported(pizza{})); diff != "" {
			t.Errorf("ir.Context().Value(k): mismatch (-want +got): \n%s", diff)
		}
	}
}

func TestRequestSetNilContext(t *testing.T) {
	defer func() {
		if r := recover(); r == nil {
			t.Errorf(`ir.SetContext(nil): expected panic`)
		}
	}()

	req := httptest.NewRequest("GET", "/", nil)
	ir := safehttp.NewIncomingRequest(req)
	ir.SetContext(nil)
}
<|endoftext|>


<commit_before>// +build windows

package cni

import (
	"fmt"
	"net"

	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
	utilwait "k8s.io/apimachinery/pkg/util/wait"
)

// Start the Server's local HTTP server on a root-owned Unix domain socket.
// requestFunc will be called to handle pod setup/teardown operations on each
// request to the Server's HTTP server, and should return a PodResult
// when the operation has completed.
func (s *Server) Start(requestFunc cniRequestFunc) error {
	if requestFunc == nil {
		return fmt.Errorf("no pod request handler")
	}
	s.requestFunc = requestFunc

	l, err := net.Listen("tcp", serverTCPAddress)
	if err != nil {
		return fmt.Errorf("failed to listen on pod info socket: %v", err)
	}

	s.SetKeepAlivesEnabled(false)
	go utilwait.Forever(func() {
		if err := s.Serve(l); err != nil {
			utilruntime.HandleError(fmt.Errorf("CNI server Serve() failed: %v", err))
		}
	}, 0)
	return nil
}
<commit_msg>cosmetic changes<commit_after>// +build windows

package cni

import (
	"fmt"
	"net"

	"github.com/sirupsen/logrus"

	utilruntime "k8s.io/apimachinery/pkg/util/runtime"
	utilwait "k8s.io/apimachinery/pkg/util/wait"
)

// Start the Server's local HTTP server on a TCP port
// TODO: use HTTPS for better security
// TODO: even better to use named pipes instead
// requestFunc will be called to handle pod setup/teardown operations on each
// request to the Server's HTTP server, and should return a PodResult
// when the operation has completed.
func (s *Server) Start(requestFunc cniRequestFunc) error {
	if requestFunc == nil {
		return fmt.Errorf("no pod request handler")
	}
	s.requestFunc = requestFunc

	l, err := net.Listen("tcp", serverTCPAddress)
	if err != nil {
		return fmt.Errorf("failed to listen on pod info socket: %v", err)
	}

	s.SetKeepAlivesEnabled(false)
	// TODO: We should have the ovnkube as a service on Windows as well so it can benefit from automatic restarts and so on.
	// We have two options:
	//  - use service wrappers to be able to register ovnkube as a Windows service;
	//  - add support in ovn-kubernetes such that ovnkube will be able to run without additional wrappers as a Windows service (example for kubernetes: kubernetes/kubernetes#60144 )

	go utilwait.Forever(func() {
		if err := s.Serve(l); err != nil {
			utilruntime.HandleError(fmt.Errorf("CNI server Serve() failed: %v", err))
		}
	}, 0)
	logrus.Infof("CNI server started")
	return nil
}
<|endoftext|>


<commit_before>package systests

import (
	"testing"
	"time"

	"github.com/keybase/client/go/libkb"
	keybase1 "github.com/keybase/client/go/protocol/keybase1"
	"github.com/keybase/client/go/teams"
	"github.com/keybase/clockwork"
	"github.com/stretchr/testify/require"
	context "golang.org/x/net/context"
)

func TestTeamInviteSeitanInvitelinkHappy(t *testing.T) {
	testTeamInviteSeitanInvitelinkHappy(t, false /* implicitAdmin */)
	testTeamInviteSeitanInvitelinkHappy(t, true /* implicitAdmin */)
}

func testTeamInviteSeitanInvitelinkHappy(t *testing.T, implicitAdmin bool) {
	tt := newTeamTester(t)
	defer tt.cleanup()

	alice := tt.addUser("kvr")
	bob := tt.addUser("eci")

	teamIDParent, teamNameParent := alice.createTeam2()
	teamID := teamIDParent
	teamName := teamNameParent
	t.Logf("Created team %v %v", teamIDParent, teamNameParent)
	if implicitAdmin {
		subteamID, err := teams.CreateSubteam(context.TODO(), tt.users[0].tc.G, "sub1", teamNameParent, keybase1.TeamRole_NONE /* addSelfAs */)
		require.NoError(t, err)
		teamID = *subteamID
		subteamName, err := teamNameParent.Append("sub1")
		require.NoError(t, err)
		teamName = subteamName
		t.Logf("Created subteam %v %v", teamID, teamName)
	}

	maxUses, err := keybase1.NewTeamInviteFiniteUses(3)
	require.NoError(t, err)
	etime := keybase1.ToUnixTime(time.Now().Add(24 * time.Hour))
	link, err := alice.teamsClient.TeamCreateSeitanInvitelink(context.TODO(), keybase1.TeamCreateSeitanInvitelinkArg{
		Teamname: teamName.String(),
		Role:     keybase1.TeamRole_ADMIN,
		MaxUses:  maxUses,
		Etime:    &etime,
	})
	require.NoError(t, err)

	t.Logf("Created token %v", link)

	details := alice.teamGetDetails(teamName.String())
	require.Len(t, details.AnnotatedActiveInvites, 1)
	for _, aInvite := range details.AnnotatedActiveInvites {
		invite := aInvite.Invite
		require.Equal(t, keybase1.TeamRole_ADMIN, invite.Role)
		tic, err := invite.Type.C()
		require.NoError(t, err)
		require.Equal(t, keybase1.TeamInviteCategory_INVITELINK, tic)
	}

	bob.kickTeamRekeyd()
	err = bob.teamsClient.TeamAcceptInvite(context.TODO(), keybase1.TeamAcceptInviteArg{
		Token: string(link.Ikey),
	})
	require.NoError(t, err)

	t.Logf("User used token, waiting for rekeyd")

	alice.waitForTeamChangedGregor(teamID, keybase1.Seqno(3))

	t0, err := teams.GetTeamByNameForTest(context.TODO(), alice.tc.G, teamName.String(), false /* public */, true /* needAdmin */)
	require.NoError(t, err)

	role, err := t0.MemberRole(context.TODO(), teams.NewUserVersion(bob.uid, 1))
	require.NoError(t, err)
	require.Equal(t, role, keybase1.TeamRole_ADMIN)
}

func TestTeamInviteLinkAfterLeave(t *testing.T) {
	tt := newTeamTester(t)
	defer tt.cleanup()

	alice := tt.addUser("ali")
	bob := tt.addUser("bob")

	teamID, teamName := alice.createTeam2()
	maxUses, err := keybase1.NewTeamInviteFiniteUses(100)
	require.NoError(t, err)
	etime := keybase1.ToUnixTime(time.Now().AddDate(1, 0, 0))
	link, err := alice.teamsClient.TeamCreateSeitanInvitelink(context.TODO(), keybase1.TeamCreateSeitanInvitelinkArg{
		Teamname: teamName.String(),
		Role:     keybase1.TeamRole_WRITER,
		MaxUses:  maxUses,
		Etime:    &etime,
	})
	require.NoError(t, err)

	t.Logf("Created team invite link: %#v", link)

	bob.kickTeamRekeyd()
	err = bob.teamsClient.TeamAcceptInvite(context.TODO(), keybase1.TeamAcceptInviteArg{
		Token: string(link.Ikey),
	})
	require.NoError(t, err)

	alice.waitForTeamChangedGregor(teamID, keybase1.Seqno(3))

	// Bob leaves.
	bob.leave(teamName.String())

	// Make sure Bob gets different akey when accepting again.
	clock := clockwork.NewFakeClockAt(time.Now())
	clock.Advance(1 * time.Second)
	bob.tc.G.SetClock(clock)

	// Bob accepts the same invite again.
	err = bob.teamsClient.TeamAcceptInvite(context.TODO(), keybase1.TeamAcceptInviteArg{
		Token: string(link.Ikey),
	})
	require.NoError(t, err)

	alice.waitForTeamChangedGregor(teamID, keybase1.Seqno(5))

	t.Logf("removing bob; expecting to ban since he was added by invitelink most recently")
	alice.removeTeamMember(teamName.String(), bob.username)
	t.Logf("bob tries to rejoin")
	clock.Advance(1 * time.Second)
	err = bob.teamsClient.TeamAcceptInvite(context.TODO(), keybase1.TeamAcceptInviteArg{
		Token: string(link.Ikey),
	})
	require.Error(t, err, "server won't let bob back in")
	appErr, ok := err.(libkb.AppStatusError)
	require.True(t, ok, "got an app err")
	require.Equal(t, appErr.Code, libkb.SCTeamBanned)

	t.Logf("alice adds/removes manually to clear ban")
	alice.addTeamMember(teamName.String(), bob.username, keybase1.TeamRole_WRITER)
	alice.removeTeamMember(teamName.String(), bob.username)

	clock.Advance(1 * time.Second)
	err = bob.teamsClient.TeamAcceptInvite(context.TODO(), keybase1.TeamAcceptInviteArg{
		Token: string(link.Ikey),
	})
	require.NoError(t, err, "bob can rejoin")
	alice.waitForTeamChangedGregor(teamID, keybase1.Seqno(9))
	t0, err := teams.GetTeamByNameForTest(context.TODO(), alice.tc.G,
		teamName.String(), false /* public */, true /* needAdmin */)
	require.NoError(t, err)
	role, err := t0.MemberRole(context.TODO(), teams.NewUserVersion(bob.uid, 1))
	require.NoError(t, err)
	require.Equal(t, role, keybase1.TeamRole_WRITER)
}

func TestCreateSeitanInvitelinkWithDuration(t *testing.T) {
	// Test for the GUI RPC.

	tt := newTeamTester(t)
	defer tt.cleanup()

	alice := tt.addUser("ali")
	_, teamName := alice.createTeam2()

	now := alice.tc.G.Clock().Now()

	maxUses := keybase1.TeamMaxUsesInfinite
	expireAfter := "1000 Y"
	_, err := alice.teamsClient.TeamCreateSeitanInvitelinkWithDuration(
		context.TODO(),
		keybase1.TeamCreateSeitanInvitelinkWithDurationArg{
			Teamname:    teamName.String(),
			Role:        keybase1.TeamRole_WRITER,
			MaxUses:     maxUses,
			ExpireAfter: &expireAfter,
		})
	require.NoError(t, err)

	details := alice.teamGetDetails(teamName.String())
	require.Len(t, details.AnnotatedActiveInvites, 1)
	for _, aInvite := range details.AnnotatedActiveInvites {
		invite := aInvite.Invite
		require.Equal(t, keybase1.TeamRole_WRITER, invite.Role)
		require.NotNil(t, invite.MaxUses)
		require.Equal(t, keybase1.TeamMaxUsesInfinite, *invite.MaxUses)
		require.NotNil(t, invite.Etime)
		require.Equal(t, now.Year()+1000, invite.Etime.Time().Year())
		require.Equal(t, keybase1.TeamMaxUsesInfinite, *invite.MaxUses)
		tic, err := invite.Type.C()
		require.NoError(t, err)
		require.Equal(t, keybase1.TeamInviteCategory_INVITELINK, tic)
	}
}
<commit_msg>kill test as requested by max (#23733)<commit_after>package systests

import (
	"testing"
	"time"

	"github.com/keybase/client/go/libkb"
	keybase1 "github.com/keybase/client/go/protocol/keybase1"
	"github.com/keybase/client/go/teams"
	"github.com/keybase/clockwork"
	"github.com/stretchr/testify/require"
	context "golang.org/x/net/context"
)

func TestTeamInviteSeitanInvitelinkHappy(t *testing.T) {
	t.Skip()
	testTeamInviteSeitanInvitelinkHappy(t, false /* implicitAdmin */)
	testTeamInviteSeitanInvitelinkHappy(t, true /* implicitAdmin */)
}

func testTeamInviteSeitanInvitelinkHappy(t *testing.T, implicitAdmin bool) {
	tt := newTeamTester(t)
	defer tt.cleanup()

	alice := tt.addUser("kvr")
	bob := tt.addUser("eci")

	teamIDParent, teamNameParent := alice.createTeam2()
	teamID := teamIDParent
	teamName := teamNameParent
	t.Logf("Created team %v %v", teamIDParent, teamNameParent)
	if implicitAdmin {
		subteamID, err := teams.CreateSubteam(context.TODO(), tt.users[0].tc.G, "sub1", teamNameParent, keybase1.TeamRole_NONE /* addSelfAs */)
		require.NoError(t, err)
		teamID = *subteamID
		subteamName, err := teamNameParent.Append("sub1")
		require.NoError(t, err)
		teamName = subteamName
		t.Logf("Created subteam %v %v", teamID, teamName)
	}

	maxUses, err := keybase1.NewTeamInviteFiniteUses(3)
	require.NoError(t, err)
	etime := keybase1.ToUnixTime(time.Now().Add(24 * time.Hour))
	link, err := alice.teamsClient.TeamCreateSeitanInvitelink(context.TODO(), keybase1.TeamCreateSeitanInvitelinkArg{
		Teamname: teamName.String(),
		Role:     keybase1.TeamRole_ADMIN,
		MaxUses:  maxUses,
		Etime:    &etime,
	})
	require.NoError(t, err)

	t.Logf("Created token %v", link)

	details := alice.teamGetDetails(teamName.String())
	require.Len(t, details.AnnotatedActiveInvites, 1)
	for _, aInvite := range details.AnnotatedActiveInvites {
		invite := aInvite.Invite
		require.Equal(t, keybase1.TeamRole_ADMIN, invite.Role)
		tic, err := invite.Type.C()
		require.NoError(t, err)
		require.Equal(t, keybase1.TeamInviteCategory_INVITELINK, tic)
	}

	bob.kickTeamRekeyd()
	err = bob.teamsClient.TeamAcceptInvite(context.TODO(), keybase1.TeamAcceptInviteArg{
		Token: string(link.Ikey),
	})
	require.NoError(t, err)

	t.Logf("User used token, waiting for rekeyd")

	alice.waitForTeamChangedGregor(teamID, keybase1.Seqno(3))

	t0, err := teams.GetTeamByNameForTest(context.TODO(), alice.tc.G, teamName.String(), false /* public */, true /* needAdmin */)
	require.NoError(t, err)

	role, err := t0.MemberRole(context.TODO(), teams.NewUserVersion(bob.uid, 1))
	require.NoError(t, err)
	require.Equal(t, role, keybase1.TeamRole_ADMIN)
}

func TestTeamInviteLinkAfterLeave(t *testing.T) {
	tt := newTeamTester(t)
	defer tt.cleanup()

	alice := tt.addUser("ali")
	bob := tt.addUser("bob")

	teamID, teamName := alice.createTeam2()
	maxUses, err := keybase1.NewTeamInviteFiniteUses(100)
	require.NoError(t, err)
	etime := keybase1.ToUnixTime(time.Now().AddDate(1, 0, 0))
	link, err := alice.teamsClient.TeamCreateSeitanInvitelink(context.TODO(), keybase1.TeamCreateSeitanInvitelinkArg{
		Teamname: teamName.String(),
		Role:     keybase1.TeamRole_WRITER,
		MaxUses:  maxUses,
		Etime:    &etime,
	})
	require.NoError(t, err)

	t.Logf("Created team invite link: %#v", link)

	bob.kickTeamRekeyd()
	err = bob.teamsClient.TeamAcceptInvite(context.TODO(), keybase1.TeamAcceptInviteArg{
		Token: string(link.Ikey),
	})
	require.NoError(t, err)

	alice.waitForTeamChangedGregor(teamID, keybase1.Seqno(3))

	// Bob leaves.
	bob.leave(teamName.String())

	// Make sure Bob gets different akey when accepting again.
	clock := clockwork.NewFakeClockAt(time.Now())
	clock.Advance(1 * time.Second)
	bob.tc.G.SetClock(clock)

	// Bob accepts the same invite again.
	err = bob.teamsClient.TeamAcceptInvite(context.TODO(), keybase1.TeamAcceptInviteArg{
		Token: string(link.Ikey),
	})
	require.NoError(t, err)

	alice.waitForTeamChangedGregor(teamID, keybase1.Seqno(5))

	t.Logf("removing bob; expecting to ban since he was added by invitelink most recently")
	alice.removeTeamMember(teamName.String(), bob.username)
	t.Logf("bob tries to rejoin")
	clock.Advance(1 * time.Second)
	err = bob.teamsClient.TeamAcceptInvite(context.TODO(), keybase1.TeamAcceptInviteArg{
		Token: string(link.Ikey),
	})
	require.Error(t, err, "server won't let bob back in")
	appErr, ok := err.(libkb.AppStatusError)
	require.True(t, ok, "got an app err")
	require.Equal(t, appErr.Code, libkb.SCTeamBanned)

	t.Logf("alice adds/removes manually to clear ban")
	alice.addTeamMember(teamName.String(), bob.username, keybase1.TeamRole_WRITER)
	alice.removeTeamMember(teamName.String(), bob.username)

	clock.Advance(1 * time.Second)
	err = bob.teamsClient.TeamAcceptInvite(context.TODO(), keybase1.TeamAcceptInviteArg{
		Token: string(link.Ikey),
	})
	require.NoError(t, err, "bob can rejoin")
	alice.waitForTeamChangedGregor(teamID, keybase1.Seqno(9))
	t0, err := teams.GetTeamByNameForTest(context.TODO(), alice.tc.G,
		teamName.String(), false /* public */, true /* needAdmin */)
	require.NoError(t, err)
	role, err := t0.MemberRole(context.TODO(), teams.NewUserVersion(bob.uid, 1))
	require.NoError(t, err)
	require.Equal(t, role, keybase1.TeamRole_WRITER)
}

func TestCreateSeitanInvitelinkWithDuration(t *testing.T) {
	// Test for the GUI RPC.

	tt := newTeamTester(t)
	defer tt.cleanup()

	alice := tt.addUser("ali")
	_, teamName := alice.createTeam2()

	now := alice.tc.G.Clock().Now()

	maxUses := keybase1.TeamMaxUsesInfinite
	expireAfter := "1000 Y"
	_, err := alice.teamsClient.TeamCreateSeitanInvitelinkWithDuration(
		context.TODO(),
		keybase1.TeamCreateSeitanInvitelinkWithDurationArg{
			Teamname:    teamName.String(),
			Role:        keybase1.TeamRole_WRITER,
			MaxUses:     maxUses,
			ExpireAfter: &expireAfter,
		})
	require.NoError(t, err)

	details := alice.teamGetDetails(teamName.String())
	require.Len(t, details.AnnotatedActiveInvites, 1)
	for _, aInvite := range details.AnnotatedActiveInvites {
		invite := aInvite.Invite
		require.Equal(t, keybase1.TeamRole_WRITER, invite.Role)
		require.NotNil(t, invite.MaxUses)
		require.Equal(t, keybase1.TeamMaxUsesInfinite, *invite.MaxUses)
		require.NotNil(t, invite.Etime)
		require.Equal(t, now.Year()+1000, invite.Etime.Time().Year())
		require.Equal(t, keybase1.TeamMaxUsesInfinite, *invite.MaxUses)
		tic, err := invite.Type.C()
		require.NoError(t, err)
		require.Equal(t, keybase1.TeamInviteCategory_INVITELINK, tic)
	}
}
<|endoftext|>