Revision 01a30cd0

b/jboss/conf/gss.properties
6 6
version=1.0.0-beta
7 7
noUsernameMessage=<B>No username found in the Shibboleth attributes!</B><P>Your Identity Provider sent the following attributes:
8 8
fileRepositoryPath=/tmp/gss-root
9
#quota in bytes(10GB)
9
# Default quota in bytes (10GB)
10 10
quota=10737418240
11
#milliseconds a request's timestamp may differ from the current system time (10')
11
# Coupon-awarded quota in bytes (100GB)
12
couponQuota=107374182400
13
# Milliseconds a request's timestamp may differ from the current system time (10')
12 14
timeSkew=600000
13
#number of days the authentication token is valid
15
# Number of days the authentication token is valid
14 16
tokenTTL=1
15 17
solrSelectUrl=http://localhost:8983/solr/select
16 18
solrUpdateUrl=http://localhost:8983/solr/update
17 19
solrUpdateRichUrl=http://localhost:8983/solr/update/rich
18
#must be in sync with solrconfig.xml's multipartUploadLimitInKB parameter
20
# Must be in sync with solrconfig.xml's multipartUploadLimitInKB parameter
19 21
solrDocumentUploadLimitInKB=30720
20
#Tomcat apparently converts data received through the AJP connector to ISO-8859-1
22
# Tomcat apparently converts data received through the AJP connector to ISO-8859-1
21 23
requestAttributeEncoding=ISO-8859-1
22
#an announcement message that will be displayed when the user logs in the system
24
# An announcement message that will be displayed when the user logs in the system
23 25
announcement=
24 26
# The test user, for development environments only! The presence of this property
25 27
# makes the Login servlet consider the specified user as having successfully
b/src/gr/ebs/gss/client/exceptions/InvitationUsedException.java
1
/*
2
 * Copyright 2010 Electronic Business Systems Ltd.
3
 *
4
 * This file is part of GSS.
5
 *
6
 * GSS is free software: you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License as published by
8
 * the Free Software Foundation, either version 3 of the License, or
9
 * (at your option) any later version.
10
 *
11
 * GSS is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with GSS.  If not, see <http://www.gnu.org/licenses/>.
18
 */
19
package gr.ebs.gss.client.exceptions;
20

  
21
import java.io.Serializable;
22

  
23
import javax.ejb.ApplicationException;
24

  
25
/**
26
 * An exception thrown when trying to reuse an already used invitation.
27
 *
28
 * @author past
29
 */
30
@ApplicationException(rollback=true)
31
public class InvitationUsedException extends Exception implements Serializable {
32

  
33
	/**
34
	 * The serial version UID.
35
	 */
36
	private static final long serialVersionUID = 1L;
37

  
38
	/**
39
	 * The stored message that provides details about the problem.
40
	 */
41
	private String message;
42

  
43
	/**
44
	 * Default constructor
45
	 */
46
	public InvitationUsedException() {
47
		super();
48
	}
49

  
50
	/**
51
	 * Constructor from error message.
52
	 *
53
	 * @param newMessage The error message
54
	 */
55
	public InvitationUsedException(final String newMessage) {
56
		super(newMessage);
57
		message = newMessage;
58
	}
59

  
60
	/**
61
	 * Constructor from Throwable.
62
	 *
63
	 * @param cause The throwable that caused the exception
64
	 */
65
	public InvitationUsedException(final Throwable cause) {
66
		super(cause);
67
	}
68

  
69
	/**
70
	 * Constructor from error message and Throwable.
71
	 *
72
	 * @param newMessage The error message
73
	 * @param cause The throwable that caused the exception
74
	 */
75
	public InvitationUsedException(final String newMessage, final Throwable cause) {
76
		super(newMessage, cause);
77
		message = newMessage;
78
	}
79

  
80
	@Override
81
	public String getMessage() {
82
		return message;
83
	}
84

  
85
}
b/src/gr/ebs/gss/server/CouponVerifier.java
18 18
 */
19 19
package gr.ebs.gss.server;
20 20

  
21
import gr.ebs.gss.client.exceptions.RpcException;
22
import gr.ebs.gss.server.domain.User;
21
import gr.ebs.gss.server.ejb.TransactionHelper;
23 22

  
24 23
import java.io.IOException;
24
import java.util.concurrent.Callable;
25 25

  
26 26
import javax.servlet.http.HttpServletRequest;
27 27
import javax.servlet.http.HttpServletResponse;
28 28

  
29
import org.apache.commons.logging.Log;
30
import org.apache.commons.logging.LogFactory;
31

  
32 29
/**
33 30
 * The servlet that handles user registration.
34 31
 *
......
70 67
	 */
71 68
	private static final long serialVersionUID = 1L;
72 69

  
73
	/**
74
	 * The logger.
75
	 */
76
	private static Log logger = LogFactory.getLog(CouponVerifier.class);
77

  
78 70
	@Override
79 71
	public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException {
80 72
		String firstname = request.getParameter(FIRSTNAME_PARAM);
81 73
		String lastname = request.getParameter(LASTNAME_PARAM);
82 74
		String email = request.getParameter(EMAIL_PARAM);
83
		String username = request.getParameter(USERNAME_PARAM);
84
		String code = request.getParameter(CODE_PARAM);
75
		final String username = request.getParameter(USERNAME_PARAM);
76
		final String code = request.getParameter(CODE_PARAM);
85 77
		String verify = request.getParameter(VERIFY_PARAM);
86 78
		response.setContentType("text/html");
87 79

  
......
113 105
			return;
114 106
		}
115 107

  
116
		User user = null;
117 108
		try {
118
			user = getService().findUser(username);
119
			if (user == null) {
120
				handleException(response, "Your user account was not found");
121
				return;
122
			}
123
			// TODO: update userclass
124
			/*
125
			final UserDTO userDto = new TransactionHelper<UserDTO>().tryExecute(new Callable<UserDTO>() {
126
				@Override
127
				public UserDTO call() throws Exception {
128
					return getService().createUser(username, firstname + " " + lastname, email, "", "").getDTO();
129
				}
130

  
131
			});
132 109
			new TransactionHelper<Void>().tryExecute(new Callable<Void>() {
133 110
				@Override
134 111
				public Void call() throws Exception {
135
					getService().updateUserPolicyAcceptance(userDto.getId(), true);
112
					getService().upgradeUserClass(username, code);
136 113
					return null;
137 114
				}
138 115

  
139
			});*/
140
			response.sendRedirect("couponSubmitted.jsp");
141
		} catch (RpcException e) {
142
			logger.error(e);
143
			handleException(response, "An error occurred while communicating with the service");
116
			});
117
			response.sendRedirect("couponSubmitted.jsp?newQuota=" + getService().getCouponUserClass().getQuotaAsString());
144 118
		} catch (Exception e) {
145
			logger.error(e);
146 119
			handleException(response, e.getMessage());
147 120
		}
148 121
	}
b/src/gr/ebs/gss/server/Login.java
193 193
				String tokenEncoded = new String(Base64.encodeBase64(user.getAuthToken()), "US-ASCII");
194 194
				user.setWebDAVPassword(tokenEncoded);
195 195
			}
196
			// Set the default user class if none was set.
197
			if (user.getUserClass() == null)
198
				user.setUserClass(getService().getUserClasses().get(0));
196 199
			getService().updateUser(user);
197 200
		} catch (RpcException e) {
198 201
			String error = "An error occurred while communicating with the service";
b/src/gr/ebs/gss/server/domain/Invitation.java
24 24
import javax.persistence.Entity;
25 25
import javax.persistence.GeneratedValue;
26 26
import javax.persistence.Id;
27
import javax.persistence.JoinColumn;
28
import javax.persistence.ManyToOne;
27 29
import javax.persistence.Version;
28 30

  
29 31
import org.hibernate.annotations.Cache;
......
78 80
	private String email;
79 81

  
80 82
	/**
83
	 * The user that used this invitation.
84
	 */
85
	@ManyToOne
86
	@JoinColumn
87
	private User user;
88

  
89
	/**
81 90
	 * Retrieve the firstname.
82 91
	 *
83 92
	 * @return the firstname
......
119 128
	 * @return the name
120 129
	 */
121 130
	public String getName() {
122
		return name;
131
		return name != null ? name : firstname + " " + lastname;
123 132
	}
124 133

  
125 134
	/**
......
177 186
		return id;
178 187
	}
179 188

  
189

  
190
	/**
191
	 * Retrieve the user.
192
	 *
193
	 * @return the user
194
	 */
195
	public User getUser() {
196
		return user;
197
	}
198

  
199

  
200
	/**
201
	 * Modify the user.
202
	 *
203
	 * @param aUser the user to set
204
	 */
205
	public void setUser(User aUser) {
206
		user = aUser;
207
	}
208

  
180 209
	@Override
181 210
	public boolean equals(Object o) {
182 211
		if (this == o) return true;
183 212
		if (!(o instanceof Invitation)) return false;
184
		Invitation user = (Invitation) o;
185
		return user.getCode().equals(code) && user.getName().equals(name);
213
		Invitation invite = (Invitation) o;
214
		return invite.getCode().equals(code) && invite.getName().equals(getName());
186 215
	}
187 216

  
188 217
	@Override
189 218
	public int hashCode() {
190
		return 37 * code.hashCode() + name.hashCode();
219
		return 37 * code.hashCode() + getName().hashCode();
191 220
	}
192 221
}
b/src/gr/ebs/gss/server/domain/UserClass.java
1 1
/*
2
 * Copyright 2007, 2008, 2009 Electronic Business Systems Ltd.
2
 * Copyright 2007, 2008, 2009, 2010 Electronic Business Systems Ltd.
3 3
 *
4 4
 * This file is part of GSS.
5 5
 *
......
21 21
import gr.ebs.gss.server.domain.dto.UserClassDTO;
22 22

  
23 23
import java.io.Serializable;
24
import java.text.DecimalFormat;
24 25
import java.util.List;
25 26

  
26 27
import javax.persistence.CascadeType;
27
import javax.persistence.Embedded;
28 28
import javax.persistence.Entity;
29 29
import javax.persistence.GeneratedValue;
30 30
import javax.persistence.Id;
......
58 58
	private int version;
59 59

  
60 60
	/**
61
	 * The audit information.
62
	 */
63
	@SuppressWarnings("unused")
64
	@Embedded
65
	private AuditInfo auditInfo;
66

  
67
	/**
68 61
	 * A name for this class.
69 62
	 */
70 63
	private String name;
......
80 73
	@OneToMany(cascade = CascadeType.ALL, mappedBy = "userClass")
81 74
	private List<User> users;
82 75

  
83
	/*
84
	 * (non-Javadoc)
85
	 *
86
	 * @see java.lang.Object#toString()
87
	 */
76
	public Long getId() {
77
		return id;
78
	}
79

  
80
	public String getName() {
81
		return name;
82
	}
83

  
84
	public void setName(String aName) {
85
		name = aName;
86
	}
87

  
88
	public long getQuota() {
89
		return quota;
90
	}
91

  
92
	public void setQuota(long aQuota) {
93
		quota = aQuota;
94
	}
95

  
88 96
	@Override
89 97
	public String toString() {
90 98
		return name;
......
96 104
	 * @return a new DTO with the same contents as this object
97 105
	 */
98 106
	public UserClassDTO getDTO() {
99
		final UserClassDTO u = new UserClassDTO();
107
		UserClassDTO u = new UserClassDTO();
100 108
		u.setId(id);
101 109
		u.setName(name);
102 110
		u.setQuota(quota);
......
104 112
			u.getUsers().add(user.getDTO());
105 113
		return u;
106 114
	}
115

  
116
	/**
117
	 * Return the quota size in a humanly readable form.
118
	 */
119
	public String getQuotaAsString() {
120
		if (quota < 1024)
121
			return String.valueOf(quota) + " B";
122
		else if (quota < 1024*1024)
123
			return getSize(quota, 1024D) + " KB";
124
		else if (quota < 1024*1024*1024)
125
			return getSize(quota,(1024D*1024D)) + " MB";
126
		return getSize(quota , (1024D*1024D*1024D)) + " GB";
127
	}
128

  
129
	private String getSize(Long size, Double divisor){
130
		DecimalFormat formatter = new DecimalFormat("######");
131
		return formatter.format((Double) (size.doubleValue()/divisor));
132
	}
107 133
}
b/src/gr/ebs/gss/server/ejb/ExternalAPI.java
21 21
import gr.ebs.gss.client.exceptions.DuplicateNameException;
22 22
import gr.ebs.gss.client.exceptions.GSSIOException;
23 23
import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
24
import gr.ebs.gss.client.exceptions.InvitationUsedException;
24 25
import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
25 26
import gr.ebs.gss.client.exceptions.QuotaExceededException;
26 27
import gr.ebs.gss.server.domain.FileUploadStatus;
27 28
import gr.ebs.gss.server.domain.Invitation;
28 29
import gr.ebs.gss.server.domain.Nonce;
29 30
import gr.ebs.gss.server.domain.User;
31
import gr.ebs.gss.server.domain.UserClass;
30 32
import gr.ebs.gss.server.domain.dto.FileBodyDTO;
31 33
import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
32 34
import gr.ebs.gss.server.domain.dto.FolderDTO;
......
1229 1231
	 */
1230 1232
	public void createLdapUser(String username, String firstname, String lastname, String email, String password);
1231 1233

  
1234
	/**
1235
	 * Retrieves the available user classes.
1236
	 */
1237
	public List<UserClass> getUserClasses();
1238

  
1239
	/**
1240
	 * Upgrades the user class to the default "coupon bearer" class and marks
1241
	 * the provided coupon as used.
1242
	 * @throws InvitationUsedException when trying to resuse an already used invitation
1243
	 * @throws ObjectNotFoundException if the user was not found
1244
	 */
1245
	public void upgradeUserClass(String username, String code)
1246
			throws ObjectNotFoundException, InvitationUsedException;
1247

  
1248
	/**
1249
	 * Retrieve the user class for coupon-bearing users.
1250
	 */
1251
	public UserClass getCouponUserClass();
1232 1252
}
b/src/gr/ebs/gss/server/ejb/ExternalAPIBean.java
22 22
import gr.ebs.gss.client.exceptions.DuplicateNameException;
23 23
import gr.ebs.gss.client.exceptions.GSSIOException;
24 24
import gr.ebs.gss.client.exceptions.InsufficientPermissionsException;
25
import gr.ebs.gss.client.exceptions.InvitationUsedException;
25 26
import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
26 27
import gr.ebs.gss.client.exceptions.QuotaExceededException;
27 28
import gr.ebs.gss.server.domain.AuditInfo;
......
35 36
import gr.ebs.gss.server.domain.Nonce;
36 37
import gr.ebs.gss.server.domain.Permission;
37 38
import gr.ebs.gss.server.domain.User;
39
import gr.ebs.gss.server.domain.UserClass;
38 40
import gr.ebs.gss.server.domain.dto.FileBodyDTO;
39 41
import gr.ebs.gss.server.domain.dto.FileHeaderDTO;
40 42
import gr.ebs.gss.server.domain.dto.FolderDTO;
......
799 801
		}
800 802
	}
801 803

  
802
	/* (non-Javadoc)
803
	 * @see gr.ebs.gss.server.ejb.ExternalAPI#getFile(java.lang.Long, java.lang.Long)
804
	 */
804
	@Override
805 805
	public FileHeaderDTO getFile(Long userId, Long fileId) throws ObjectNotFoundException, InsufficientPermissionsException {
806 806
		if (userId == null)
807 807
			throw new ObjectNotFoundException("No user specified");
......
1429 1429
		user.setAuditInfo(auditInfo);
1430 1430
		user.generateAuthToken();
1431 1431
		user.generateWebDAVPassword();
1432
		// Set the default user class to the one with the lowest quota.
1433
		user.setUserClass(getUserClasses().get(0));
1432 1434
		dao.create(user);
1433 1435
		// Make sure we get an ID in the user object.
1434 1436
		dao.flush();
......
1438 1440
	}
1439 1441

  
1440 1442
	@Override
1443
	public List<UserClass> getUserClasses() {
1444
		List<UserClass> classes = dao.getUserClasses();
1445
		// Create a default user class for first-time use. Afterwards, the
1446
		// admin should modify or add to the userclass table.
1447
		if (classes.size() == 0) {
1448
			UserClass defaultClass = new UserClass();
1449
			defaultClass.setName("default");
1450
			Long defaultQuota = getConfiguration().getLong("quota", new Long(52428800L));
1451
			defaultClass.setQuota(defaultQuota);
1452
			dao.create(defaultClass);
1453
			classes.add(defaultClass);
1454
		}
1455
		return classes;
1456
	}
1457

  
1458
	@Override
1441 1459
	public User findUserByEmail(String email) {
1442 1460
		return dao.findUserByEmail(email);
1443 1461
	}
......
2134 2152
	}
2135 2153

  
2136 2154
	/**
2137
	 * Gets the quota left for specified userId
2138
	 * @param userId
2139
	 * @return
2155
	 * Gets the quota left for specified user ID.
2140 2156
	 */
2141
	private Long getQuotaLeft(Long userId){
2157
	private Long getQuotaLeft(Long userId) throws ObjectNotFoundException{
2142 2158
		Long fileSize = dao.getFileSize(userId);
2143 2159
		Long quota = getQuota(userId);
2144 2160
		return quota - fileSize;
2145 2161
	}
2146 2162

  
2147 2163
	/**
2148
	 * Gets the quota for specified userId
2149
	 * @param userId
2150
	 * @return
2164
	 * Gets the quota for specified user ID.
2151 2165
	 */
2152
	private Long getQuota(@SuppressWarnings("unused") Long userId){
2153
		Long quota = getConfiguration().getLong("quota", new Long(52428800L));
2154
		return quota;
2166
	private Long getQuota(Long userId) throws ObjectNotFoundException{
2167
		return getUser(userId).getUserClass().getQuota();
2155 2168
	}
2156 2169

  
2157 2170
	public void rebuildSolrIndex() {
......
2435 2448
	 * @param owner the owner of the file
2436 2449
	 * @throws FileNotFoundException
2437 2450
	 * @throws QuotaExceededException
2451
	 * @throws ObjectNotFoundException if the owner was not found
2438 2452
	 */
2439 2453
	private void createFileBody(String name, String mimeType, long fileSize, String filePath,
2440 2454
				FileHeader header, AuditInfo auditInfo)
2441
			throws FileNotFoundException, QuotaExceededException {
2455
			throws FileNotFoundException, QuotaExceededException, ObjectNotFoundException {
2442 2456

  
2443 2457
		long currentTotalSize = 0;
2444 2458
		if (!header.isVersioned() && header.getCurrentBody() != null && header.getBodies() != null)
......
2680 2694

  
2681 2695
	}
2682 2696

  
2697
	@Override
2698
	public void upgradeUserClass(String username, String code) throws ObjectNotFoundException, InvitationUsedException {
2699
		User user = findUser(username);
2700
		if (user == null)
2701
			throw new ObjectNotFoundException("The user was not found");
2702
		Invitation invite = findInvite(code);
2703
		if (invite.getUser() != null)
2704
			throw new InvitationUsedException("This code has already been used");
2705
		invite.setUser(user);
2706
		user.setUserClass(getCouponUserClass());
2707
	}
2708

  
2709
	@Override
2710
	public UserClass getCouponUserClass() {
2711
		return dao.findCouponUserClass();
2712
	}
2713

  
2683 2714
}
b/src/gr/ebs/gss/server/ejb/GSSDAO.java
27 27
import gr.ebs.gss.server.domain.Invitation;
28 28
import gr.ebs.gss.server.domain.Nonce;
29 29
import gr.ebs.gss.server.domain.User;
30
import gr.ebs.gss.server.domain.UserClass;
30 31

  
31 32
import java.util.Date;
32 33
import java.util.List;
......
402 403
	 * @return the Invitation or null if not found
403 404
	 */
404 405
	public Invitation findInvite(String code);
406

  
407
	/**
408
	 * Retrieves available user classes.
409
	 *
410
	 */
411
	public List<UserClass> getUserClasses();
412

  
413
	/**
414
	 * Retrieve the user class for coupon-bearing users.
415
	 */
416
	public UserClass findCouponUserClass();
405 417
}
b/src/gr/ebs/gss/server/ejb/GSSDAOBean.java
18 18
 */
19 19
package gr.ebs.gss.server.ejb;
20 20

  
21
import static gr.ebs.gss.server.configuration.GSSConfigurationFactory.getConfiguration;
21 22
import gr.ebs.gss.client.exceptions.ObjectNotFoundException;
22 23
import gr.ebs.gss.server.domain.AccountingInfo;
23 24
import gr.ebs.gss.server.domain.FileBody;
......
28 29
import gr.ebs.gss.server.domain.Invitation;
29 30
import gr.ebs.gss.server.domain.Nonce;
30 31
import gr.ebs.gss.server.domain.User;
32
import gr.ebs.gss.server.domain.UserClass;
31 33

  
32 34
import java.util.ArrayList;
33 35
import java.util.Calendar;
......
630 632
		return results.get(0);
631 633
	}
632 634

  
635
	@Override
636
	public List<UserClass> getUserClasses() {
637
		// Ordering by quota is important here.
638
		List<UserClass> ids = manager.createQuery("select uc from UserClass uc order by uc.quota").getResultList();
639
		return ids;
640
	}
641

  
642
	@Override
643
	public UserClass findCouponUserClass() {
644
		List<UserClass> results = manager.createQuery("select uc from UserClass uc where uc.name=:name").
645
				setParameter("name", getConfiguration().getString("couponQuota")).getResultList();
646
		if (results.isEmpty()) {
647
			// Create the coupon user class on first use.
648
			UserClass couponClass = new UserClass();
649
			couponClass.setName("coupon");
650
			Long couponQuota = getConfiguration().getLong("couponQuota", new Long(52428800L));
651
			couponClass.setQuota(couponQuota);
652
			create(couponClass);
653
			flush();
654
			results.add(couponClass);
655
		}
656
		return results.get(0);
657
	}
633 658
}
b/war/couponSubmitted.jsp
40 40
<div class="page_main">
41 41
<center>
42 42
<p>
43
Your account quota was successfully upgraded. You may now
43
Your account quota was successfully upgraded. You now have <%= request.getParameter("newQuota") %> of storage. You may now
44 44
<a href="<%= request.getContextPath()+ "/login?next=" + GSSConfigurationFactory.getConfiguration().getString("serviceURL") %>">
45 45
login</a> to <%= GSSConfigurationFactory.getConfiguration().getString("serviceName") %>
46 46
</center>

Also available in: Unified diff