mirror of
https://github.com/aclindsa/moneygo.git
synced 2024-10-30 07:40:05 -04:00
Add per-user default currency
This commit is contained in:
parent
25b04a4f0f
commit
4e73e8b508
@ -5,6 +5,7 @@ var ErrorActions = require('./ErrorActions');
|
|||||||
var models = require('../models.js');
|
var models = require('../models.js');
|
||||||
var Security = models.Security;
|
var Security = models.Security;
|
||||||
var Error = models.Error;
|
var Error = models.Error;
|
||||||
|
var SecurityType = models.SecurityType;
|
||||||
|
|
||||||
function searchSecurityTemplates(searchString, searchType) {
|
function searchSecurityTemplates(searchString, searchType) {
|
||||||
return {
|
return {
|
||||||
@ -23,6 +24,19 @@ function securityTemplatesSearched(searchString, searchType, securities) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fetchCurrencyTemplates() {
|
||||||
|
return {
|
||||||
|
type: SecurityTemplateConstants.FETCH_CURRENCIES
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function currencyTemplatesFetched(currencies) {
|
||||||
|
return {
|
||||||
|
type: SecurityTemplateConstants.CURRENCIES_FETCHED,
|
||||||
|
currencies: currencies
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function search(searchString, searchType, limit) {
|
function search(searchString, searchType, limit) {
|
||||||
return function (dispatch) {
|
return function (dispatch) {
|
||||||
dispatch(searchSecurityTemplates(searchString, searchType));
|
dispatch(searchSecurityTemplates(searchString, searchType));
|
||||||
@ -57,6 +71,38 @@ function search(searchString, searchType, limit) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {
|
function fetchCurrencies() {
|
||||||
search: search
|
return function (dispatch) {
|
||||||
|
dispatch(fetchCurrencyTemplates());
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: "GET",
|
||||||
|
dataType: "json",
|
||||||
|
url: "securitytemplate/?search=&type=currency",
|
||||||
|
success: function(data, status, jqXHR) {
|
||||||
|
var e = new Error();
|
||||||
|
e.fromJSON(data);
|
||||||
|
if (e.isError()) {
|
||||||
|
dispatch(ErrorActions.serverError(e));
|
||||||
|
} else if (data.securities == null) {
|
||||||
|
dispatch(currencyTemplatesFetched(new Array()));
|
||||||
|
} else {
|
||||||
|
dispatch(currencyTemplatesFetched(
|
||||||
|
data.securities.map(function(json) {
|
||||||
|
var s = new Security();
|
||||||
|
s.fromJSON(json);
|
||||||
|
return s;
|
||||||
|
})));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(jqXHR, status, error) {
|
||||||
|
dispatch(ErrorActions.ajaxError(error));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
search: search,
|
||||||
|
fetchCurrencies: fetchCurrencies
|
||||||
};
|
};
|
||||||
|
@ -12,6 +12,8 @@ var FormControl = ReactBootstrap.FormControl;
|
|||||||
var ControlLabel = ReactBootstrap.ControlLabel;
|
var ControlLabel = ReactBootstrap.ControlLabel;
|
||||||
var Col = ReactBootstrap.Col;
|
var Col = ReactBootstrap.Col;
|
||||||
|
|
||||||
|
var Combobox = require('react-widgets').Combobox;
|
||||||
|
|
||||||
var models = require('../models');
|
var models = require('../models');
|
||||||
var User = models.User;
|
var User = models.User;
|
||||||
|
|
||||||
@ -22,6 +24,7 @@ class AccountSettingsModal extends React.Component {
|
|||||||
name: props ? props.user.Name: "",
|
name: props ? props.user.Name: "",
|
||||||
username: props ? props.user.Username : "",
|
username: props ? props.user.Username : "",
|
||||||
email: props ? props.user.Email : "",
|
email: props ? props.user.Email : "",
|
||||||
|
defaultCurrency: props ? props.user.DefaultCurrency : "",
|
||||||
password: models.BogusPassword,
|
password: models.BogusPassword,
|
||||||
confirm_password: models.BogusPassword,
|
confirm_password: models.BogusPassword,
|
||||||
passwordChanged: false,
|
passwordChanged: false,
|
||||||
@ -33,6 +36,7 @@ class AccountSettingsModal extends React.Component {
|
|||||||
this.state = this._getInitialState();
|
this.state = this._getInitialState();
|
||||||
this.onCancel = this.handleCancel.bind(this);
|
this.onCancel = this.handleCancel.bind(this);
|
||||||
this.onChange = this.handleChange.bind(this);
|
this.onChange = this.handleChange.bind(this);
|
||||||
|
this.onSelectCurrency = this.handleSelectCurrency.bind(this);
|
||||||
this.onSubmit = this.handleSubmit.bind(this);
|
this.onSubmit = this.handleSubmit.bind(this);
|
||||||
}
|
}
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
@ -73,6 +77,13 @@ class AccountSettingsModal extends React.Component {
|
|||||||
confirm_password: ReactDOM.findDOMNode(this.refs.confirm_password).value
|
confirm_password: ReactDOM.findDOMNode(this.refs.confirm_password).value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
handleSelectCurrency(security) {
|
||||||
|
if (security.hasOwnProperty('SecurityId')) {
|
||||||
|
this.setState({
|
||||||
|
defaultCurrency: security.SecurityId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
handleSubmit(e) {
|
handleSubmit(e) {
|
||||||
var u = new User();
|
var u = new User();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
@ -81,6 +92,7 @@ class AccountSettingsModal extends React.Component {
|
|||||||
u.Name = this.state.name;
|
u.Name = this.state.name;
|
||||||
u.Username = this.state.username;
|
u.Username = this.state.username;
|
||||||
u.Email = this.state.email;
|
u.Email = this.state.email;
|
||||||
|
u.DefaultCurrency = this.state.defaultCurrency;
|
||||||
if (this.state.passwordChanged) {
|
if (this.state.passwordChanged) {
|
||||||
u.Password = this.state.password;
|
u.Password = this.state.password;
|
||||||
if (u.Password != this.state.confirm_password) {
|
if (u.Password != this.state.confirm_password) {
|
||||||
@ -130,6 +142,20 @@ class AccountSettingsModal extends React.Component {
|
|||||||
ref="email"/>
|
ref="email"/>
|
||||||
</Col>
|
</Col>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
<FormGroup>
|
||||||
|
<Col componentClass={ControlLabel} xs={2}>Default Currency</Col>
|
||||||
|
<Col xs={10}>
|
||||||
|
<Combobox
|
||||||
|
data={this.props.currencies}
|
||||||
|
valueField='SecurityId'
|
||||||
|
textField={item => item == undefined || typeof item === 'string' ? item : item.Name + " - " + item.Description}
|
||||||
|
defaultValue={this.state.defaultCurrency}
|
||||||
|
onChange={this.onSelectCurrency}
|
||||||
|
suggest
|
||||||
|
filter='contains'
|
||||||
|
ref="security" />
|
||||||
|
</Col>
|
||||||
|
</FormGroup>
|
||||||
<FormGroup validationState={this.passwordValidationState()}>
|
<FormGroup validationState={this.passwordValidationState()}>
|
||||||
<Col componentClass={ControlLabel} xs={2}>Password</Col>
|
<Col componentClass={ControlLabel} xs={2}>Password</Col>
|
||||||
<Col xs={10}>
|
<Col xs={10}>
|
||||||
|
@ -27,6 +27,7 @@ class MoneyGoApp extends React.Component {
|
|||||||
}
|
}
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
this.props.tryResumingSession();
|
this.props.tryResumingSession();
|
||||||
|
this.props.fetchCurrencies();
|
||||||
}
|
}
|
||||||
handleShowSettings() {
|
handleShowSettings() {
|
||||||
this.setState({showAccountSettingsModal: true});
|
this.setState({showAccountSettingsModal: true});
|
||||||
|
@ -11,6 +11,8 @@ var Col = ReactBootstrap.Col;
|
|||||||
var Button = ReactBootstrap.Button;
|
var Button = ReactBootstrap.Button;
|
||||||
var ButtonGroup = ReactBootstrap.ButtonGroup;
|
var ButtonGroup = ReactBootstrap.ButtonGroup;
|
||||||
|
|
||||||
|
var Combobox = require('react-widgets').Combobox;
|
||||||
|
|
||||||
var models = require('../models');
|
var models = require('../models');
|
||||||
var User = models.User;
|
var User = models.User;
|
||||||
|
|
||||||
@ -22,6 +24,7 @@ class NewUserModal extends React.Component {
|
|||||||
name: "",
|
name: "",
|
||||||
username: "",
|
username: "",
|
||||||
email: "",
|
email: "",
|
||||||
|
defaultCurrency: '840', // ISO4217 code for USD
|
||||||
password: "",
|
password: "",
|
||||||
confirm_password: "",
|
confirm_password: "",
|
||||||
passwordChanged: false,
|
passwordChanged: false,
|
||||||
@ -29,6 +32,7 @@ class NewUserModal extends React.Component {
|
|||||||
};
|
};
|
||||||
this.onCancel = this.handleCancel.bind(this);
|
this.onCancel = this.handleCancel.bind(this);
|
||||||
this.onChange = this.handleChange.bind(this);
|
this.onChange = this.handleChange.bind(this);
|
||||||
|
this.onSelectCurrency = this.handleSelectCurrency.bind(this);
|
||||||
this.onSubmit = this.handleSubmit.bind(this);
|
this.onSubmit = this.handleSubmit.bind(this);
|
||||||
}
|
}
|
||||||
passwordValidationState() {
|
passwordValidationState() {
|
||||||
@ -64,6 +68,13 @@ class NewUserModal extends React.Component {
|
|||||||
confirm_password: ReactDOM.findDOMNode(this.refs.confirm_password).value
|
confirm_password: ReactDOM.findDOMNode(this.refs.confirm_password).value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
handleSelectCurrency(security) {
|
||||||
|
if (security.hasOwnProperty('SecurityId')) {
|
||||||
|
this.setState({
|
||||||
|
defaultCurrency: security.AlternateId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
handleSubmit(e) {
|
handleSubmit(e) {
|
||||||
var u = new User();
|
var u = new User();
|
||||||
var error = "";
|
var error = "";
|
||||||
@ -72,6 +83,7 @@ class NewUserModal extends React.Component {
|
|||||||
u.Name = this.state.name;
|
u.Name = this.state.name;
|
||||||
u.Username = this.state.username;
|
u.Username = this.state.username;
|
||||||
u.Email = this.state.email;
|
u.Email = this.state.email;
|
||||||
|
u.DefaultCurrency = Number.parseInt(this.state.defaultCurrency);
|
||||||
u.Password = this.state.password;
|
u.Password = this.state.password;
|
||||||
if (u.Password != this.state.confirm_password) {
|
if (u.Password != this.state.confirm_password) {
|
||||||
this.setState({error: "Error: passwords do not match"});
|
this.setState({error: "Error: passwords do not match"});
|
||||||
@ -118,6 +130,20 @@ class NewUserModal extends React.Component {
|
|||||||
ref="email"/>
|
ref="email"/>
|
||||||
</Col>
|
</Col>
|
||||||
</FormGroup>
|
</FormGroup>
|
||||||
|
<FormGroup>
|
||||||
|
<Col componentClass={ControlLabel} xs={2}>Default Currency</Col>
|
||||||
|
<Col xs={10}>
|
||||||
|
<Combobox
|
||||||
|
data={this.props.currencies}
|
||||||
|
valueField='AlternateId'
|
||||||
|
textField={item => typeof item === 'string' ? item : item.Name + " - " + item.Description}
|
||||||
|
defaultValue={this.state.defaultCurrency}
|
||||||
|
onChange={this.onSelectCurrency}
|
||||||
|
suggest
|
||||||
|
filter='contains'
|
||||||
|
ref="security" />
|
||||||
|
</Col>
|
||||||
|
</FormGroup>
|
||||||
<FormGroup validationState={this.passwordValidationState()}>
|
<FormGroup validationState={this.passwordValidationState()}>
|
||||||
<Col componentClass={ControlLabel} xs={2}>Password</Col>
|
<Col componentClass={ControlLabel} xs={2}>Password</Col>
|
||||||
<Col xs={10}>
|
<Col xs={10}>
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
var keyMirror = require('keymirror');
|
var keyMirror = require('keymirror');
|
||||||
|
|
||||||
module.exports = keyMirror({
|
module.exports = keyMirror({
|
||||||
|
FETCH_CURRENCIES: null,
|
||||||
|
CURRENCIES_FETCHED: null,
|
||||||
SEARCH_SECURITY_TEMPLATES: null,
|
SEARCH_SECURITY_TEMPLATES: null,
|
||||||
SECURITY_TEMPLATES_SEARCHED: null
|
SECURITY_TEMPLATES_SEARCHED: null
|
||||||
});
|
});
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
var connect = require('react-redux').connect;
|
var connect = require('react-redux').connect;
|
||||||
|
|
||||||
var UserActions = require('../actions/UserActions');
|
var UserActions = require('../actions/UserActions');
|
||||||
|
|
||||||
var AccountSettingsModal = require('../components/AccountSettingsModal');
|
var AccountSettingsModal = require('../components/AccountSettingsModal');
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
return {
|
return {
|
||||||
user: state.user
|
user: state.user,
|
||||||
|
currencies: state.securities.currency_list
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
var connect = require('react-redux').connect;
|
var connect = require('react-redux').connect;
|
||||||
|
|
||||||
var UserActions = require('../actions/UserActions');
|
var UserActions = require('../actions/UserActions');
|
||||||
|
var SecurityTemplateActions = require('../actions/SecurityTemplateActions');
|
||||||
|
|
||||||
var MoneyGoApp = require('../components/MoneyGoApp');
|
var MoneyGoApp = require('../components/MoneyGoApp');
|
||||||
|
|
||||||
@ -13,6 +14,7 @@ function mapStateToProps(state) {
|
|||||||
function mapDispatchToProps(dispatch) {
|
function mapDispatchToProps(dispatch) {
|
||||||
return {
|
return {
|
||||||
tryResumingSession: function() {dispatch(UserActions.tryResumingSession())},
|
tryResumingSession: function() {dispatch(UserActions.tryResumingSession())},
|
||||||
|
fetchCurrencies: function() {dispatch(SecurityTemplateActions.fetchCurrencies())},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,9 @@ var UserActions = require('../actions/UserActions');
|
|||||||
var NewUserModal = require('../components/NewUserModal');
|
var NewUserModal = require('../components/NewUserModal');
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
return {}
|
return {
|
||||||
|
currencies: state.securityTemplates.currencies
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function mapDispatchToProps(dispatch) {
|
function mapDispatchToProps(dispatch) {
|
||||||
|
@ -13,6 +13,7 @@ function getJSONObj(json_input) {
|
|||||||
class User {
|
class User {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.UserId = -1;
|
this.UserId = -1;
|
||||||
|
this.DefaultCurrency = -1;
|
||||||
this.Name = "";
|
this.Name = "";
|
||||||
this.Username = "";
|
this.Username = "";
|
||||||
this.Password = "";
|
this.Password = "";
|
||||||
@ -21,6 +22,7 @@ class User {
|
|||||||
toJSON() {
|
toJSON() {
|
||||||
var json_obj = {};
|
var json_obj = {};
|
||||||
json_obj.UserId = this.UserId;
|
json_obj.UserId = this.UserId;
|
||||||
|
json_obj.DefaultCurrency = this.DefaultCurrency;
|
||||||
json_obj.Name = this.Name;
|
json_obj.Name = this.Name;
|
||||||
json_obj.Username = this.Username;
|
json_obj.Username = this.Username;
|
||||||
json_obj.Password = this.Password;
|
json_obj.Password = this.Password;
|
||||||
@ -32,6 +34,8 @@ class User {
|
|||||||
|
|
||||||
if (json_obj.hasOwnProperty("UserId"))
|
if (json_obj.hasOwnProperty("UserId"))
|
||||||
this.UserId = json_obj.UserId;
|
this.UserId = json_obj.UserId;
|
||||||
|
if (json_obj.hasOwnProperty("DefaultCurrency"))
|
||||||
|
this.DefaultCurrency = json_obj.DefaultCurrency;
|
||||||
if (json_obj.hasOwnProperty("Name"))
|
if (json_obj.hasOwnProperty("Name"))
|
||||||
this.Name = json_obj.Name;
|
this.Name = json_obj.Name;
|
||||||
if (json_obj.hasOwnProperty("Username"))
|
if (json_obj.hasOwnProperty("Username"))
|
||||||
|
@ -3,30 +3,37 @@ var assign = require('object-assign');
|
|||||||
var SecurityTemplateConstants = require('../constants/SecurityTemplateConstants');
|
var SecurityTemplateConstants = require('../constants/SecurityTemplateConstants');
|
||||||
var UserConstants = require('../constants/UserConstants');
|
var UserConstants = require('../constants/UserConstants');
|
||||||
|
|
||||||
var SecurityType = require('../models').SecurityType;
|
const initialState = {
|
||||||
|
search: "",
|
||||||
|
type: 0,
|
||||||
|
templates: [],
|
||||||
|
currencies: []
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = function(state = {search: "", type: 0, templates: [], searchNumber: 0}, action) {
|
module.exports = function(state = initialState, action) {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case SecurityTemplateConstants.SEARCH_SECURITY_TEMPLATES:
|
case SecurityTemplateConstants.SEARCH_SECURITY_TEMPLATES:
|
||||||
return {
|
return assign({}, state, {
|
||||||
search: action.searchString,
|
search: action.searchString,
|
||||||
type: action.searchType,
|
type: action.searchType,
|
||||||
templates: []
|
templates: []
|
||||||
};
|
});
|
||||||
case SecurityTemplateConstants.SECURITY_TEMPLATES_SEARCHED:
|
case SecurityTemplateConstants.SECURITY_TEMPLATES_SEARCHED:
|
||||||
if ((action.searchString != state.search) || (action.searchType != state.type))
|
if ((action.searchString != state.search) || (action.searchType != state.type))
|
||||||
return state;
|
return state;
|
||||||
return {
|
return assign({}, state, {
|
||||||
search: action.searchString,
|
search: action.searchString,
|
||||||
type: action.searchType,
|
type: action.searchType,
|
||||||
templates: action.securities
|
templates: action.securities
|
||||||
};
|
});
|
||||||
|
case SecurityTemplateConstants.CURRENCIES_FETCHED:
|
||||||
|
return assign({}, state, {
|
||||||
|
currencies: action.currencies
|
||||||
|
});
|
||||||
case UserConstants.USER_LOGGEDOUT:
|
case UserConstants.USER_LOGGEDOUT:
|
||||||
return {
|
return assign({}, initialState, {
|
||||||
search: "",
|
currencies: state.currencies
|
||||||
type: 0,
|
});
|
||||||
templates: []
|
|
||||||
};
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ type Security struct {
|
|||||||
// security is precise to
|
// security is precise to
|
||||||
Precision int
|
Precision int
|
||||||
Type int64
|
Type int64
|
||||||
// AlternateId is CUSIP for Type=Stock
|
// AlternateId is CUSIP for Type=Stock, ISO4217 for Type=Currency
|
||||||
AlternateId string
|
AlternateId string
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,6 +86,16 @@ func FindSecurityTemplate(name string, _type int64) *Security {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func FindCurrencyTemplate(iso4217 int64) *Security {
|
||||||
|
iso4217string := strconv.FormatInt(iso4217, 10)
|
||||||
|
for _, security := range SecurityTemplates {
|
||||||
|
if security.Type == Currency && security.AlternateId == iso4217string {
|
||||||
|
return &security
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func GetSecurity(securityid int64, userid int64) (*Security, error) {
|
func GetSecurity(securityid int64, userid int64) (*Security, error) {
|
||||||
var s Security
|
var s Security
|
||||||
|
|
||||||
@ -171,6 +181,15 @@ func DeleteSecurity(s *Security) error {
|
|||||||
return errors.New("One or more accounts still use this security")
|
return errors.New("One or more accounts still use this security")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
user, err := GetUserTx(transaction, s.UserId)
|
||||||
|
if err != nil {
|
||||||
|
transaction.Rollback()
|
||||||
|
return err
|
||||||
|
} else if user.DefaultCurrency == s.SecurityId {
|
||||||
|
transaction.Rollback()
|
||||||
|
return errors.New("Cannot delete security which is user's default currency")
|
||||||
|
}
|
||||||
|
|
||||||
count, err := transaction.Delete(s)
|
count, err := transaction.Delete(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
transaction.Rollback()
|
transaction.Rollback()
|
||||||
|
81
users.go
81
users.go
@ -3,7 +3,9 @@ package main
|
|||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"gopkg.in/gorp.v1"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -12,6 +14,7 @@ import (
|
|||||||
|
|
||||||
type User struct {
|
type User struct {
|
||||||
UserId int64
|
UserId int64
|
||||||
|
DefaultCurrency int64 // SecurityId of default currency, or ISO4217 code for it if creating new user
|
||||||
Name string
|
Name string
|
||||||
Username string
|
Username string
|
||||||
Password string `db:"-"`
|
Password string `db:"-"`
|
||||||
@ -54,6 +57,16 @@ func GetUser(userid int64) (*User, error) {
|
|||||||
return &u, nil
|
return &u, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetUserTx(transaction *gorp.Transaction, userid int64) (*User, error) {
|
||||||
|
var u User
|
||||||
|
|
||||||
|
err := transaction.SelectOne(&u, "SELECT * from users where UserId=?", userid)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &u, nil
|
||||||
|
}
|
||||||
|
|
||||||
func GetUserByUsername(username string) (*User, error) {
|
func GetUserByUsername(username string) (*User, error) {
|
||||||
var u User
|
var u User
|
||||||
|
|
||||||
@ -70,6 +83,12 @@ func InsertUser(u *User) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
security_template := FindCurrencyTemplate(u.DefaultCurrency)
|
||||||
|
if security_template == nil {
|
||||||
|
transaction.Rollback()
|
||||||
|
return errors.New("Invalid ISO4217 Default Currency")
|
||||||
|
}
|
||||||
|
|
||||||
existing, err := transaction.SelectInt("SELECT count(*) from users where Username=?", u.Username)
|
existing, err := transaction.SelectInt("SELECT count(*) from users where Username=?", u.Username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
transaction.Rollback()
|
transaction.Rollback()
|
||||||
@ -86,6 +105,28 @@ func InsertUser(u *User) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Copy the security template and give it our new UserId
|
||||||
|
var security Security
|
||||||
|
security = *security_template
|
||||||
|
security.UserId = u.UserId
|
||||||
|
|
||||||
|
err = InsertSecurityTx(transaction, &security)
|
||||||
|
if err != nil {
|
||||||
|
transaction.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update the user's DefaultCurrency to our new SecurityId
|
||||||
|
u.DefaultCurrency = security.SecurityId
|
||||||
|
count, err := transaction.Update(u)
|
||||||
|
if err != nil {
|
||||||
|
transaction.Rollback()
|
||||||
|
return err
|
||||||
|
} else if count != 1 {
|
||||||
|
transaction.Rollback()
|
||||||
|
return errors.New("Would have updated more than one user")
|
||||||
|
}
|
||||||
|
|
||||||
err = transaction.Commit()
|
err = transaction.Commit()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
transaction.Rollback()
|
transaction.Rollback()
|
||||||
@ -103,6 +144,42 @@ func GetUserFromSession(r *http.Request) (*User, error) {
|
|||||||
return GetUser(s.UserId)
|
return GetUser(s.UserId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func UpdateUser(u *User) error {
|
||||||
|
transaction, err := DB.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
security, err := GetSecurityTx(transaction, u.DefaultCurrency, u.UserId)
|
||||||
|
if err != nil {
|
||||||
|
transaction.Rollback()
|
||||||
|
return err
|
||||||
|
} else if security.UserId != u.UserId || security.SecurityId != u.DefaultCurrency {
|
||||||
|
transaction.Rollback()
|
||||||
|
return errors.New("UserId and DefaultCurrency don't match the fetched security")
|
||||||
|
} else if security.Type != Currency {
|
||||||
|
transaction.Rollback()
|
||||||
|
return errors.New("New DefaultCurrency security is not a currency")
|
||||||
|
}
|
||||||
|
|
||||||
|
count, err := transaction.Update(u)
|
||||||
|
if err != nil {
|
||||||
|
transaction.Rollback()
|
||||||
|
return err
|
||||||
|
} else if count != 1 {
|
||||||
|
transaction.Rollback()
|
||||||
|
return errors.New("Would have updated more than one user")
|
||||||
|
}
|
||||||
|
|
||||||
|
err = transaction.Commit()
|
||||||
|
if err != nil {
|
||||||
|
transaction.Rollback()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func UserHandler(w http.ResponseWriter, r *http.Request) {
|
func UserHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
if r.Method == "POST" {
|
if r.Method == "POST" {
|
||||||
user_json := r.PostFormValue("user")
|
user_json := r.PostFormValue("user")
|
||||||
@ -187,8 +264,8 @@ func UserHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
user.PasswordHash = old_pwhash
|
user.PasswordHash = old_pwhash
|
||||||
}
|
}
|
||||||
|
|
||||||
count, err := DB.Update(user)
|
err = UpdateUser(user)
|
||||||
if count != 1 || err != nil {
|
if err != nil {
|
||||||
WriteError(w, 999 /*Internal Error*/)
|
WriteError(w, 999 /*Internal Error*/)
|
||||||
log.Print(err)
|
log.Print(err)
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user