/*
* Copyright 2013 David Tinker
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.qdb.server.controller;
import io.qdb.server.repo.Repository;
import io.qdb.server.model.User;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
@Singleton
public class UserController extends CrudController {
private final Repository repo;
public static class UserDTO {
public String id;
public Integer version;
public String password;
public Boolean admin;
public String[] databases;
public UserDTO() { }
public UserDTO(User u) {
id = u.getId();
version = u.getVersion();
admin = u.isAdmin();
databases = u.getDatabases();
}
}
@Inject
public UserController(Repository repo, JsonService jsonService) {
super(jsonService);
this.repo = repo;
}
@Override
protected void list(Call call, int offset, int limit) throws IOException {
if (call.getUser().isAdmin()) {
List<User> users = repo.findUsers(offset, limit);
UserDTO[] ans = new UserDTO[users.size()];
for (int i = 0; i < ans.length; i++) ans[i] = new UserDTO(users.get(i));
call.setJson(ans);
} else {
call.setCode(403);
}
}
@Override
protected void count(Call call) throws IOException {
if (call.getUser().isAdmin()) {
call.setJson(new Count(repo.countUsers()));
} else {
call.setCode(403);
}
}
@Override
protected void show(Call call, String id) throws IOException {
User cu = call.getUser();
if ("me".equals(id)) id = cu.getId();
if (cu.isAdmin() || cu.getId().equals(id)) {
User user = repo.findUser(id);
if (user == null) {
call.setCode(404);
} else {
call.setJson(new UserDTO(user));
}
} else {
call.setCode(403);
}
}
@Override
protected void createOrUpdate(Call call, String id) throws IOException {
if (call.getUser().isAdmin()) {
UserDTO dto = getBodyObject(call, UserDTO.class);
User u;
boolean create;
synchronized (repo) {
u = repo.findUser(id);
if (create = u == null) {
if (call.isPut()) {
call.setCode(404);
return;
}
u = new User(id);
} else {
if (dto.version != null && !dto.version.equals(u.getVersion())) {
call.setCode(409, new UserDTO(u));
return;
}
u = u.deepCopy();
}
boolean changed = create;
if (dto.password != null && !u.doesPasswordMatch(dto.password)) {
u.setPassword(dto.password);
changed = true;
}
if (dto.admin != null && dto.admin != u.isAdmin()) {
u.setAdmin(dto.admin);
changed = true;
}
if (dto.databases != null && !Arrays.equals(dto.databases, u.getDatabases())) {
for (int i = 0; i < dto.databases.length; i++) {
String db = dto.databases[i];
if (repo.findDatabase(db) == null) {
call.setCode(400, "database [" + db + "] does not exist");
return;
}
}
u.setDatabases(dto.databases);
changed = true;
}
if (changed) repo.updateUser(u);
}
call.setCode(create ? 201 : 200, new UserDTO(u));
} else {
call.setCode(403);
}
}
@Override
protected void delete(Call call, String id) throws IOException {
synchronized (repo) {
User u = repo.findUser(id);
if (u == null) {
call.setCode(404);
return;
}
repo.deleteUser(id);
}
}
}