I've got something that will help you press on.
The modifier
modifier onlyUser {
if (msg.sender != userAddr) throw;
_;
}
prevented all efforts to set a product, because userAddr was never set (==0x0). Added a constructor to look after it and now I can add a product.
After that, getUserProduct() started working. I added "public" to some state vars and some logs to help see what's going on. Watch for other small changes I may have slipped in while debugging.
Worked once. No Warranty. :-)
pragma solidity ^0.4.6;
library DataSet {
struct IndexValue { uint keyIndex; uint256 value;}
struct KeyFlag { uint key; bool deleted; }
struct KeyValue { uint key; uint value; }
struct Data {
mapping(uint => IndexValue) data;
KeyFlag[] keys;
//KeyValue[] kvpairs;
uint size;
}
function stringToBytes32(string memory source) returns (bytes32 result) {
assembly {
result := mload(add(source, 32))
}
}
function getCurrent(Data storage self) returns(uint index){
return self.size - 1;
}
}
contract Controlled {
address public userAddr;
struct User {
address a;
string name;
string email;
uint phone;
}
mapping (address => User) public Users;
event LogNewUser(address user, string name, string email, uint phone);
function Controlled() {
userAddr = msg.sender;
}
function registerUser(string _name, string _email, uint _phone) returns (bool success) {
Users[msg.sender].a = msg.sender;
Users[msg.sender].name = _name;
Users[msg.sender].email = _email;
Users[msg.sender].phone = _phone;
LogNewUser(msg.sender, _name, _email, _phone);
return true;
}
modifier onlyUser {
if (msg.sender != userAddr) throw;
_;
}
}
contract Main is Controlled {
using DataSet for *;
DataSet.Data d;
struct userProduct {
address user_address;
uint id;
string desc;
uint price;
}
userProduct[] public products;
event LogNewUserProduct(address user, uint index, string description, uint price);
function newUserProduct (
address u,
uint i,
string d,
uint p) onlyUser returns (bool added) {
userProduct memory newProduct;
newProduct.user_address = msg.sender;
newProduct.id = i;
newProduct.desc= d;
newProduct.price = p;
products.push(newProduct);
LogNewUserProduct(msg.sender, i, d, p);
return true;
}
function getUserInfo (uint g) constant returns (address ,bytes32, uint ) {
for (uint i = 0; i <= products.length; i++) {
if (products[i].id == g) {
return(products[i].user_address, DataSet.stringToBytes32(products[i].desc), products[i].price);
}
}
}
}
Here it is in Remix to show it working.

Side tip
It's hard to discern the data structure you're aiming for. If you can clarify that for me I might send back a simplified version of this for you.
There are example patterns over here that might help: Are there well-solved and simple storage patterns for Solidity?
Admittedly, it gets a little tricky applying the patterns to joins and there's no generalized example of that in the post.
Hope it helps.
Update
I'm a little confused by who's supposed to do what.
onlyAdmin must be able to create/update attributes/delete the product
from the struct array. onlyManager must be able to update
attributes/delete the product and onlyTester must be able to update
the product attributes
As a caution item, in general, I try to externalize access control concerns. "owner" can be a contract designed to reflect access control concerns.
This scaffold might give you some ideas about how to proceed.
pragma solidity ^0.4.6;
contract Store {
address public owner;
enum UserType {owner, admin, tester}
struct User {
bytes32 name;
bytes32 email;
bytes32 phone;
UserType userType;
uint userIndex;
}
mapping(address => User) public userStructs;
address[] public userList;
struct Product {
uint price;
bytes32 description;
uint productIndex;
}
mapping(bytes32 => Product) public productStructs;
bytes32[] public productList;
modifier onlyOwner {
if(msg.sender != owner) throw;
_;
}
modifier onlyAdmin {
if(!isUser(msg.sender)) throw;
if(userStructs[msg.sender].userType != UserType.admin) throw;
_;
}
modifier onlyTester {
if(!isUser(msg.sender)) throw;
if(userStructs[msg.sender].userType != UserType.tester) throw;
_;
}
// constructor
function Store() {
owner = msg.sender;
}
// simple counts
function getUserCount() public constant returns(uint userCount) { return userList.length; }
function getProductCount() public constant returns(uint productCount) { return productList.length; }
// Id checks
function isUser(address user)
public
constant
returns(bool isIndeed)
{
if(userList.length == 0) return false;
return userList[userStructs[user].userIndex] == user;
}
function isProduct(bytes32 productId)
public
constant
returns(bool isIndeed)
{
if(productList.length == 0) return false;
return productList[productStructs[productId].productIndex] == productId;
}
// inserts
function createAdmin(address userAddress, bytes32 userName, bytes32 userEmail)
onlyOwner
returns(bool success)
{
if(isUser(userAddress)) throw;
userStructs[userAddress].name = userName;
userStructs[userAddress].email = userEmail;
userStructs[userAddress].userType = UserType.admin;
userStructs[userAddress].userIndex = userList.push(userAddress) - 1;
return true;
}
function createTester(address userAddress, bytes32 userName, bytes32 userEmail)
onlyOwner
returns(bool success)
{
if(isUser(userAddress)) throw;
userStructs[userAddress].name = userName;
userStructs[userAddress].email = userEmail;
userStructs[userAddress].userType = UserType.tester;
userStructs[userAddress].userIndex = userList.push(userAddress) - 1;
return true;
}
function createProduct(bytes32 productId, uint productPrice, bytes32 productDescription)
onlyAdmin
returns(bool success)
{
if(isProduct(productId)) throw;
productStructs[productId].price = productPrice;
productStructs[productId].description = productDescription;
productStructs[productId].productIndex = productList.push(productId);
return true;
}
function updateProduct(bytes32 productId, uint productPrice, bytes32 productDescription)
onlyTester
returns(bool success)
{
if(!isProduct(productId)) throw;
if(isProduct(productId)) throw;
productStructs[productId].price = productPrice;
productStructs[productId].description = productDescription;
productStructs[productId].productIndex = productList.push(productId);
return true;
}
}