Login system in c++

Hi everyone,

I want to add a login system for my c++ calculator: this is a system I've been programming for quite a few years now. At the moment it runs as a stand-alone webserver (written using linux system functions).

The ultimate goal is to let my students submit their homework and have it graded by the system (I am a math instructor). The system does not have to be super secure (although I certainly wouldn't mind security).

How would you do this? I am ready to make my students make a google account or perhaps I could do the account management myself. What is your advice? The less work I'd have to do, the happier I'd be. To be completely clear, checking out and compiling other people's code and reading documentation counts as work (just spent a whole afternoon reading about google authentification and I couldn't get even the google login sample programs to compile).

Cheers,
tition
Last edited on
I recommend Wt:

http://www.webtoolkit.eu/wt

It has a built in authentification and more.
Wow.... I just spent a half hour drafting a response to this, made it too large, and our lovely website told me "content too large" and promptly removed the box I was working in...

Unfortunately that means I'm a little less patient with this response...

The ultimate goal is to let my students submit their homework and have it graded by the system


I recommend creating a RESTful service that allows uploads from your students through whatever technology you want to use. C++ has CURL which will allow you to directly integrate.

You can create a simple API using PHP like this login page:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
<?php
header('Content-type: application/json');
$myerrors = array();$lasterror='';
function opendb($server, $username, $password, $database=""){
	global $myerrors;
	$dbh =  new mysqli($server,$username,$password,$database);
	if ($mysqli->connect_errno){
		array_push(	$myerrors,"Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error);
	}
	mysqli_set_charset($dbh,'utf8');
	return $dbh;
}
function executequery($idb, $query){
	$result = $idb->query($query);
	if($result==null){
		global $myerrors;
		global $lasterror;
		$rno = mysqli_errno($dbhandle);
		$rer = mysqli_error($dbhandle);
		array_push($myerrors, "iquery error $rno : $rer");
		$lasterror="iquery error $rno : $rer";
	}
	else if ($result&&gettype($result)!='boolean'){
		$data = mysqli_fetch_assoc($result);
		$retval = array();
		while($data != false){
			array_push($retval,$data);
			$data = mysqli_fetch_assoc($result);
		}
		mysqli_free_result($result);
		return $retval;
	}
	return $result;
}
function closedb($idb){
	mysqli_close($idb);
}

$required=array('username','password');

global $ret;
$missing = array();
$ret=array('SUCCESS'=>false);
$input=file_get_contents('php://input');
$jn=json_decode($input,true);	
if(count($jn)>0){
	$params=$jn;
}
else if(count($_POST)>0){
	$params=$_POST;
}
else if(count($_GET)>0){
	$params=$_GET;
}
$success=true;
if (isset($required)){
	foreach($required as $param){
		if(!isset($params[$param])){
			$success=false;
			array_push($missing,$param);
		}
	}
}
if ($success){
	$db = openmydb("127.0.0.1","USERNAME","PASSWORD","DATABASE");
	$username = mysqli_real_escape_string($db,$params['username']);
	$password = mysqli_real_escape_string($db,$params['password']);

	$qrey = "select id from Users WHERE username='".$username."' AND password='".$password.'" LIMIT 1';

	$res = executequery($db,$qrey);

	if ($res){
		$ret['SUCCESS']=true
		$ret['ID']=current($res);
			
	}
	else{
		//For Debugging Your Initial Problems
		if ($lasterror!=null){
			$ret['FAILURE']='Error';
			$ret['SQLERROR']=$lasterror;
		}
		$ret['SUCCESS']=false;
	}
}
else{
	$ret['MISSING']=$missing;
}
echo(json_encode($ret));
?>


And using CURL access that data in C++.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
struct httpret{
    std::string body;
    long status;
    std::string error;
    long errorcode;
    httpret();
    httpret(const httpret& hret);
    httpret& operator=(const httpret& hret);
    virtual ~httpret();
};
struct progfunc{
    std::function<void(long long,long long,void*)> func;
    void* pass;
};

extern CURLcode lastmsg;
size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata);
int progress_callback( void *Bar,curl_off_t dltotal,curl_off_t dlnow,curl_off_t ultotal,curl_off_t ulnow);

httpret postjson(CURL* curl, const std::string& url, const std::string& json, const std::string& username = "",const std::string& password = "", progfunc* passdat = NULL);
httpret getjson(CURL* curl, const std::string& url, const std::string& username = "",const std::string& password = "", progfunc* passdat = NULL);
httpret posthttp(CURL* curl, const std::string & url, const std::string& ipost, const std::string& username = "",const std::string& password = "", progfunc* passdat = NULL);
std::string geturl(CURL* curl, const std::string & url, const std::string& username = "",const std::string& password = "", progfunc* passdat = NULL);
httpret gethttp(CURL* curl, const std::string & url, const std::string& username = "",const std::string& password = "", progfunc* passdat = NULL);


httpret::httpret(){

}
httpret::httpret(const httpret& hret){
    (*this)=hret;
}
httpret& httpret::operator=(const httpret& hret){
    if(this==&hret)
        return *this;
    this->body=hret.body;
    this->error=hret.error;
    this->errorcode=hret.errorcode;
    this->status=hret.status;
    return *this;
}
httpret::~httpret(){

}
CURLcode lastmsg;
size_t write_callback(char *ptr, size_t size, size_t nmemb, void *userdata){
    ((std::string*)(userdata))->append(ptr,size*nmemb);
    return size*nmemb;
}
int progress_callback( void *Bar,curl_off_t dltotal,curl_off_t dlnow,curl_off_t ultotal,curl_off_t ulnow){
    if (Bar!=NULL){
        if (dlnow>0){
            int x = 5;
        }
        progfunc* pf = (progfunc*)Bar;
        pf->func(dlnow,dltotal,pf->pass);
    }
    return 0;
}
httpret postjson(CURL* curl, const std::string& url, const std::string& json, const std::string& username,const std::string& password, progfunc* passdat){
    httpret output;
    struct curl_slist *headers=NULL;
    headers = curl_slist_append(headers, "Accept: application/json");
    headers = curl_slist_append(headers, "Content-Type: application/json");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    output = posthttp(curl,url,json,username,password,passdat);
    curl_slist_free_all(headers);
    return output;
}
httpret getjson(CURL* curl, const std::string& url, const std::string& username,const std::string& password, progfunc* passdat){
    httpret output;
    struct curl_slist *headers=NULL; ///TODO do this one time dammit also postjson
    curl_slist_append(headers, "Accept: application/json");
    curl_slist_append(headers, "Content-Type: application/json");
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
    //curl_slist_append( headers, "charsets: utf-8");
    output = gethttp(curl,url,username,password,passdat);
    curl_slist_free_all(headers);
    return output;
}
httpret posthttp(CURL* curl, const std::string & url, const std::string& ipost, const std::string& username,const std::string& password, progfunc* passdat){
    curl_easy_setopt(curl, CURLOPT_POST, 1);
    curl_easy_setopt(curl, CURLOPT_POSTFIELDS,ipost.c_str());
    return gethttp(curl,url,username,password,passdat);
}
std::string geturl(CURL* curl, const std::string & url, const std::string& username,const std::string& password, progfunc* passdat){
    return gethttp(curl,url,username,password,passdat).body;
}
httpret gethttp(CURL* curl, const std::string & url, const std::string& username,const std::string& password, progfunc* passdat){
    httpret output;
    if (username.size()>0)
        curl_easy_setopt(curl,CURLOPT_USERNAME,username.c_str());
    if (password.size()>0)
        curl_easy_setopt(curl,CURLOPT_PASSWORD,password.c_str());
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,write_callback);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA,&output.body);
    curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false);

    if(passdat!=NULL){
        curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progress_callback);
        curl_easy_setopt(curl, CURLOPT_XFERINFODATA, passdat);
        curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0);
    }

    output.errorcode = curl_easy_perform(curl);
    curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &output.status);
    return output;
}


httpret hret = postjson("mywebsite.com/phppagewemade.php","username=blahblah&password=blahblah");

You can then adapt that API style to whatever you need.
Last edited on
Guys many thanks for your responses! I was out of the site for a number few days, just reading up on your responses ... Will double post with my comments when done reading ...
Topic archived. No new replies allowed.