File: login.cpp

package info (click to toggle)
bibledit-cloud 5.1.036-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 250,636 kB
  • sloc: xml: 915,934; ansic: 261,349; cpp: 92,628; javascript: 32,542; sh: 4,915; makefile: 586; php: 69
file content (141 lines) | stat: -rw-r--r-- 5,063 bytes parent folder | download | duplicates (2)
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/*
Copyright (©) 2003-2025 Teus Benschop.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/


#include <assets/view.h>
#include <assets/page.h>
#include <assets/header.h>
#include <public/login.h>
#include <locale/translate.h>
#include <webserver/request.h>
#include <filter/url.h>
#include <filter/roles.h>
#include <filter/string.h>
#include <database/logs.h>
#include <database/config/general.h>
#include <public/index.h>
#include <config/logic.h>
#include <config/logic.h>


const char * public_login_url ()
{
  return "public/login";
}


bool public_login_acl (Webserver_Request& webserver_request)
{
  if (config::logic::create_no_accounts()) return false;
  return roles::access_control (webserver_request, roles::guest);
}


std::string public_login (Webserver_Request& webserver_request)
{
  std::string page;
  Assets_Header header = Assets_Header (translate ("Public login"), webserver_request);
  page = header.run ();
  Assets_View view;

  
  // Form submission handler.
  if (!webserver_request.post_get("submit").empty ()) {

    bool form_is_valid = true;
    std::string name = webserver_request.post_get("name");
    const std::string email = webserver_request.post_get("email");
    
    // During login it determines whether the device is a touch enabled device.
    // Research shows that most desktop users move with their mouse over the screen before they click,
    // so we can detect those mouse movements through javascript,
    // and store that information with the user and device.
    const bool touch_enabled = filter::strings::convert_to_bool (webserver_request.post_get("touch"));
    
    if (name.length () < 2) {
      form_is_valid = false;
      view.set_variable ("name_invalid", translate ("The name should be at least two characters long"));
    }
    
    if (!filter_url_email_is_valid (email)) {
      form_is_valid = false;
      view.set_variable ("email_invalid", translate("The email address is not valid"));
    }
    
    std::string other_login = translate ("This account needs a password.") + " " + translate("Please login the other way, through Menu / Login.");
    
    // If the username exists with a level higher than guest, that would not be right.
    if (form_is_valid) {
      const int level = webserver_request.database_users ()->get_level (name);
      if (level > roles::guest) {
        form_is_valid = false;
        view.set_variable ("error", other_login);
      }
    }
    
    // If the email address exists with a level higher than guest, that would not be right.
    if (form_is_valid) {
      if (webserver_request.database_users ()->emailExists (email)) {
        const std::string username = webserver_request.database_users ()->getEmailToUser (email);
        const  int level = webserver_request.database_users ()->get_level (username);
        if (level > roles::guest) {
          form_is_valid = false;
          view.set_variable ("error", other_login);
        }
      }
    }

    // If the email address exists with a guest role,
    // update the username to be matching with this email address.
    if (form_is_valid) {
      if (webserver_request.database_users ()->emailExists (email)) {
        const std::string username = webserver_request.database_users ()->getEmailToUser (email);
        const int level = webserver_request.database_users ()->get_level (username);
        if (level == roles::guest) {
          name = username;
        }
      }
    }

    if (form_is_valid) {
      // For public login, the password is taken to be the same as the username.
      if (webserver_request.session_logic()->attempt_login (name, name, touch_enabled)) {
        // Log the login.
        Database_Logs::log ("User " + webserver_request.session_logic ()->get_username () + " logged in");
      } else {
        // Add a new user and login.
        webserver_request.database_users ()->add_user(name, name, roles::guest, email);
        webserver_request.session_logic()->attempt_login (name, name, touch_enabled);
        Database_Logs::log ("Public account created for user " + webserver_request.session_logic ()->get_username () + " with email " + email);
      }
    }
  }


  if (webserver_request.session_logic ()->get_logged_in ()) {
    redirect_browser (webserver_request, public_index_url ());
    return std::string();
  }

  
  page += view.render ("public", "login");
  page += assets_page::footer ();

  
  return page;
}