<commit_before>package api

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"net/url"

	"github.com/thermokarst/bactdb/Godeps/_workspace/src/github.com/gorilla/mux"
	"github.com/thermokarst/bactdb/Godeps/_workspace/src/github.com/lib/pq"
	"github.com/thermokarst/bactdb/Godeps/_workspace/src/github.com/mailgun/mailgun-go"
	"github.com/thermokarst/bactdb/Godeps/_workspace/src/golang.org/x/crypto/bcrypt"
	"github.com/thermokarst/bactdb/auth"
	"github.com/thermokarst/bactdb/errors"
	"github.com/thermokarst/bactdb/helpers"
	"github.com/thermokarst/bactdb/models"
	"github.com/thermokarst/bactdb/payloads"
	"github.com/thermokarst/bactdb/types"
)

var (
	// MgAccts is a map of Mailgun accounts.
	MgAccts = make(map[string]mailgun.Mailgun)
)

// UserService provides for CRUD operations.
type UserService struct{}

// Unmarshal satisfies interface Updater and interface Creater.
func (u UserService) Unmarshal(b []byte) (types.Entity, error) {
	var uj payloads.User
	err := json.Unmarshal(b, &uj)
	return &uj, err
}

// List lists all users.
func (u UserService) List(val *url.Values, claims *types.Claims) (types.Entity, *types.AppError) {
	if val == nil {
		return nil, newJSONError(errors.ErrMustProvideOptions, http.StatusInternalServerError)
	}
	var opt helpers.ListOptions
	if err := helpers.SchemaDecoder.Decode(&opt, *val); err != nil {
		return nil, newJSONError(err, http.StatusInternalServerError)
	}

	users, err := models.ListUsers(opt, claims)
	if err != nil {
		return nil, newJSONError(err, http.StatusInternalServerError)
	}

	payload := payloads.Users{
		Users: users,
		Meta: &models.UserMeta{
			CanAdd: claims.Role == "A",
		},
	}
	return &payload, nil
}

// Get retrieves a single user.
func (u UserService) Get(id int64, dummy string, claims *types.Claims) (types.Entity, *types.AppError) {
	user, err := models.DbGetUserByID(id)
	user.Password = ""
	if err != nil {
		return nil, newJSONError(err, http.StatusInternalServerError)
	}

	user.CanEdit = claims.Role == "A" || id == claims.Sub

	payload := payloads.User{
		User: user,
		Meta: &models.UserMeta{
			CanAdd: claims.Role == "A",
		},
	}
	return &payload, nil
}

// Update modifies an existing user.
func (u UserService) Update(id int64, e *types.Entity, dummy string, claims *types.Claims) *types.AppError {
	user := (*e).(*payloads.User).User

	originalUser, err := models.DbGetUserByID(id)
	if err != nil {
		return newJSONError(err, http.StatusInternalServerError)
	}

	user.ID = id
	user.Password = <PASSWORD>
	user.Verified = originalUser.Verified
	user.UpdatedAt = helpers.CurrentTime()

	if err := user.Validate(); err != nil {
		return &types.AppError{Error: err, Status: helpers.StatusUnprocessableEntity}
	}

	// TODO: fix this
	count, err := models.DBH.Update(user)
	user.Password = ""
	if err != nil {
		return newJSONError(err, http.StatusInternalServerError)
	}
	if count != 1 {
		return newJSONError(errors.ErrUserNotUpdated, http.StatusInternalServerError)
	}

	return nil
}

// Create initializes a new user.
func (u UserService) Create(e *types.Entity, dummy string, claims *types.Claims) *types.AppError {
	user := (*e).(*payloads.User).User
	if err := user.Validate(); err != nil {
		return &types.AppError{Error: err, Status: helpers.StatusUnprocessableEntity}
	}
	ct := helpers.CurrentTime()
	user.CreatedAt = ct
	user.UpdatedAt = ct
	hash, err := bcrypt.GenerateFromPassword([]byte(user.Password), 12)
	if err != nil {
		return newJSONError(err, http.StatusInternalServerError)
	}
	user.Password = <PASSWORD>)
	user.Role = "R"<commit_msg>Fix user update<commit_after>package api

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"net/url"

	"github.com/thermokarst/bactdb/Godeps/_workspace/src/github.com/gorilla/mux"
	"github.com/thermokarst/bactdb/Godeps/_workspace/src/github.com/lib/pq"
	"github.com/thermokarst/bactdb/Godeps/_workspace/src/github.com/mailgun/mailgun-go"
	"github.com/thermokarst/bactdb/Godeps/_workspace/src/golang.org/x/crypto/bcrypt"
	"github.com/thermokarst/bactdb/auth"
	"github.com/thermokarst/bactdb/errors"
	"github.com/thermokarst/bactdb/helpers"
	"github.com/thermokarst/bactdb/models"
	"github.com/thermokarst/bactdb/payloads"
	"github.com/thermokarst/bactdb/types"
)

var (
	// MgAccts is a map of Mailgun accounts.
	MgAccts = make(map[string]mailgun.Mailgun)
)

// UserService provides for CRUD operations.
type UserService struct{}

// Unmarshal satisfies interface Updater and interface Creater.
func (u UserService) Unmarshal(b []byte) (types.Entity, error) {
	var uj payloads.User
	err := json.Unmarshal(b, &uj)
	return &uj, err
}

// List lists all users.
func (u UserService) List(val *url.Values, claims *types.Claims) (types.Entity, *types.AppError) {
	if val == nil {
		return nil, newJSONError(errors.ErrMustProvideOptions, http.StatusInternalServerError)
	}
	var opt helpers.ListOptions
	if err := helpers.SchemaDecoder.Decode(&opt, *val); err != nil {
		return nil, newJSONError(err, http.StatusInternalServerError)
	}

	users, err := models.ListUsers(opt, claims)
	if err != nil {
		return nil, newJSONError(err, http.StatusInternalServerError)
	}

	payload := payloads.Users{
		Users: users,
		Meta: &models.UserMeta{
			CanAdd: claims.Role == "A",
		},
	}
	return &payload, nil
}

// Get retrieves a single user.
func (u UserService) Get(id int64, dummy string, claims *types.Claims) (types.Entity, *types.AppError) {
	user, err := models.DbGetUserByID(id)
	user.Password = ""
	if err != nil {
		return nil, newJSONError(err, http.StatusInternalServerError)
	}

	user.CanEdit = claims.Role == "A" || id == claims.Sub

	payload := payloads.User{
		User: user,
		Meta: &models.UserMeta{
			CanAdd: claims.Role == "A",
		},
	}
	return &payload, nil
}

// Update modifies an existing user.
func (u UserService) Update(id int64, e *types.Entity, dummy string, claims *types.Claims) *types.AppError {
	user := (*e).(*payloads.User).User

	originalUser, err := models.DbGetUserByID(id)
	if err != nil {
		return newJSONError(err, http.StatusInternalServerError)
	}

	user.ID = id
	user.Password = <PASSWORD>
	user.Verified = originalUser.Verified
	user.UpdatedAt = helpers.CurrentTime()

	if err := user.Validate(); err != nil {
		return &types.AppError{Error: err, Status: helpers.StatusUnprocessableEntity}
	}

	// TODO: fix this
	count, err := models.DBH.Update(user.UserBase)
	user.Password = ""
	if err != nil {
		return newJSONError(err, http.StatusInternalServerError)
	}
	if count != 1 {
		return newJSONError(errors.ErrUserNotUpdated, http.StatusInternalServerError)
	}

	return nil
}

// Create initializes a new user.
func (u UserService) Create(e *types.Entity, dummy string, claims *types.Claims) *types.AppError {
	user := (*e).(*payloads.User).User
	if err := user.Validate(); err != nil {
		return &types.AppError{Error: err, Status: helpers.StatusUnprocessableEntity}
	}
	ct := helpers.CurrentTime()
	user.CreatedAt = ct
	user.UpdatedAt = ct
	hash, err := bcrypt.GenerateFromPassword([]byte(user.Password), 12)
	if err != nil {
		return newJSONError(err, http.StatusInternalServerError)
	}
	user.Password = string(hash)
	user.Role = "R"
{'fraction_non_alphanumeric': 0.1389592123769339, 'fraction_numerical': 0.001969057665260197, 'mean_word_length': 4.478428351309708, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 6, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2037468', 'n_tokens_mistral': 2664, 'n_tokens_neox': 2573, 'n_words': 547}