Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

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

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

import logging 

 

from datetime import datetime 

from pyramid.httpexceptions import HTTPFound 

from pyramid.httpexceptions import HTTPNotFound 

from pyramid.renderers import render_to_response 

from pyramid.security import remember 

from pyramid.security import forget 

from pyramid.url import route_url 

from pyramid.view import view_config 

 

from bookie.bcelery import tasks 

from bookie.lib.applog import AuthLog 

from bookie.models.auth import UserMgr 

from bookie.models.auth import ActivationMgr 

 

LOG = logging.getLogger(__name__) 

 

 

@view_config(route_name="login", renderer="/auth/login.mako") 

def login(request): 

    """Login the user to the system 

 

    If not POSTed then show the form 

    If error, display the form with the error message 

    If successful, forward the user to their /recent 

 

    Note: the came_from stuff we're not using atm. We'll clean out if we keep 

    things this way 

 

    """ 

    login_url = route_url('login', request) 

    referrer = request.url 

    if referrer == login_url: 

        referrer = '/'  # never use the login form itself as came_from 

 

    came_from = request.params.get('came_from', referrer) 

 

    message = '' 

    login = '' 

    password = '' 

 

    if 'form.submitted' in request.params: 

        login = request.params['login'] 

        password = request.params['password'] 

 

        LOG.debug(login) 

        auth = UserMgr.get(username=login) 

        LOG.debug(auth) 

        LOG.debug(UserMgr.get_list()) 

 

        if auth and auth.validate_password(password) and auth.activated: 

            # We use the Primary Key as our identifier once someone has 

            # authenticated rather than the username.  You can change what is 

            # returned as the userid by altering what is passed to remember. 

            headers = remember(request, auth.id, max_age=60 * 60 * 24 * 30) 

            auth.last_login = datetime.utcnow() 

 

            # log the successful login 

            AuthLog.login(login, True) 

 

            # we're always going to return a user to their own /recent after a 

            # login 

            return HTTPFound( 

                location=request.route_url( 

                    'user_bmark_recent', 

                    username=auth.username), 

                headers=headers) 

 

        # log the right level of problem 

        if auth and not auth.validate_password(password): 

            message = "Your login attempt has failed." 

            AuthLog.login(login, False, password=password) 

 

        elif auth and not auth.activated: 

            message = "User account deactivated. Please check your email." 

            AuthLog.login(login, False, password=password) 

            AuthLog.disabled(login) 

 

        elif auth is None: 

            message = "Failed login" 

            AuthLog.login(login, False, password=password) 

 

    return { 

        'message': message, 

        'came_from': came_from, 

        'login': login, 

        'password': password, 

    } 

 

 

@view_config(route_name="logout", renderer="/auth/login.mako") 

def logout(request): 

    headers = forget(request) 

    return HTTPFound(location=route_url('home', request), 

                     headers=headers) 

 

 

@view_config(route_name="signup", renderer="/auth/signup.mako") 

def signup(request): 

    """Signup merely shows the signup for to users. 

 

    We always take their signup even if we don't send out the email/invite at 

    this time so that we can stage invites across a specific number in waves. 

 

    """ 

    return {} 

 

 

@view_config(route_name="signup_process", renderer="/auth/signup.mako") 

def signup_process(request): 

    """Process the signup request 

 

    If there are any errors drop to the same template with the error 

    information. 

 

    """ 

    params = request.params 

    email = params.get('email', None) 

 

    if not email: 

        # if still no email, I give up! 

        return { 

            'errors': { 

                'email': 'Please supply an email address to sign up.' 

            } 

        } 

 

    # first see if the user is already in the system 

    exists = UserMgr.get(email=email) 

    if exists: 

        return { 

            'errors': { 

                'email': 'The user has already signed up.' 

            } 

        } 

 

    new_user = UserMgr.signup_user(email, 'signup') 

    if new_user: 

        # then this user is able to invite someone 

        # log it 

        AuthLog.reactivate(new_user.username) 

 

        # and then send an email notification 

        # @todo the email side of things 

        settings = request.registry.settings 

 

        # Add a queue job to send the user a notification email. 

        tasks.email_signup_user.delay( 

            new_user.email, 

            "Enable your Bookie account", 

            settings, 

            request.route_url( 

                'reset', 

                username=new_user.username, 

                reset_key=new_user.activation.code 

            ) 

        ) 

 

        # And let the user know they're signed up. 

        return { 

            'message': 'Thank you for signing up from: ' + new_user.email 

        } 

    else: 

        return { 

            'errors': { 

                'email': 'There was an unknown error signing up.' 

            } 

        } 

 

 

@view_config(route_name="reset", renderer="/auth/reset.mako") 

def reset(request): 

    """Once deactivated, allow for changing the password via activation key""" 

    rdict = request.matchdict 

    params = request.params 

 

    # This is an initial request to show the activation form. 

    username = rdict.get('username', None) 

    activation_key = rdict.get('reset_key', None) 

    user = ActivationMgr.get_user(username, activation_key) 

 

    if user is None: 

        # just 404 if we don't have an activation code for this user 

        raise HTTPNotFound() 

 

    if 'code' in params: 

        # This is a posted form with the activation, attempt to unlock the 

        # user's account. 

        username = params.get('username', None) 

        activation = params.get('code', None) 

        password = params.get('new_password', None) 

        new_username = params.get('new_username', None) 

        error = None 

 

        if not UserMgr.acceptable_password(password): 

            # Set an error message to the template. 

            error = "Come on, pick a real password please." 

        else: 

            res = ActivationMgr.activate_user(username, activation, password) 

            if res: 

                # success so respond nicely 

                AuthLog.reactivate(username, success=True, code=activation) 

 

                # if there's a new username and it's not the same as our current 

                # username, update it 

                if new_username and new_username != username: 

                    try: 

                        user = UserMgr.get(username=username) 

                        user.username = new_username 

                    except IntegrityError, exc: 

                        error = 'There was an issue setting your new username' 

            else: 

                AuthLog.reactivate(username, success=False, code=activation) 

                error = 'There was an issue attempting to activate this account.' 

 

        if error: 

            return { 

                'message': error, 

                'user': user 

            } 

        else: 

            # Log the user in and move along. 

            headers = remember(request, user.id, max_age=60 * 60 * 24 * 30) 

            user.last_login = datetime.utcnow() 

 

            # log the successful login 

            AuthLog.login(user.username, True) 

 

            # we're always going to return a user to their own /recent after a 

            # login 

            return HTTPFound( 

                location=request.route_url( 

                    'user_bmark_recent', 

                    username=user.username), 

                headers=headers) 

 

    else: 

        LOG.error("CHECKING") 

        LOG.error(username) 

 

        if user is None: 

            # just 404 if we don't have an activation code for this user 

            raise HTTPNotFound() 

 

        LOG.error(user.username) 

        LOG.error(user.email) 

        return { 

            'user': user, 

        } 

 

 

def forbidden_view(request): 

    login_url = route_url('login', request) 

    referrer = request.url 

    if referrer == login_url: 

        referrer = '/'  # never use the login form itself as came_from 

    came_from = request.params.get('came_from', referrer) 

    return render_to_response( 

        '/auth/login.mako', 

        dict( 

            message='', 

            url=request.application_url + '/login', 

            came_from=came_from, 

            login='', 

            password='', 

        ), 

        request=request)