Commit 03084d64 authored by Jan Koester's avatar Jan Koester
Browse files

test

parent 3247be17
Loading
Loading
Loading
Loading
Loading
+21 −1
Changes for data/admin.html: 21 added lines, 1 removed line.
Original line number Diff line number Diff line
@@ -226,6 +226,10 @@ function createUserForm() {
    html += '<tr><td><label for="lastname">Lastname:</label></td><td><input type="text" name="lastname" id="cu_lastname"></td></tr>';
    html += '<tr><td><label for="mail">Mail:</label></td><td><input type="text" name="mail" id="cu_mail"></td></tr>';
    html += '<tr><td><label for="pwhash">Password:</label></td><td><input type="password" name="pwhash" id="cu_password"></td></tr>';
    html += '<tr><td><label for="role">Rolle:</label></td><td><select name="role" id="cu_role">';
    html += '<option value="mitarbeiter">Mitarbeiter</option>';
    html += '<option value="admin">Admin</option>';
    html += '</select></td></tr>';
    html += '<tr><td><label for="avatar">ProfilBild:</label></td><td><input type="file" name="avatar" id="cu_avatar"></td></tr>';
    html += '<tr><td></td><td><input type="button" value="Create" onclick="submitCreateUser()"></td></tr>';
    html += '</table></form>';
@@ -239,6 +243,7 @@ function submitCreateUser() {
    formData.append("lastname", document.getElementById("cu_lastname").value);
    formData.append("mail", document.getElementById("cu_mail").value);
    formData.append("pwhash", document.getElementById("cu_password").value);
    formData.append("role", document.getElementById("cu_role").value);
    var avatar = document.getElementById("cu_avatar").files[0];
    if (avatar) formData.append("avatar", avatar);

@@ -352,6 +357,10 @@ function createDomainForm() {
        html += '<tr><td><label>Domain Storage:</label></td><td>File</td></tr>';
        html += '<tr><td><label>Domain Options:</label></td><td><input type="text" id="cd_options" class="domaintext" value="" required></td></tr>';
    }
    html += '<tr><td colspan="2"><hr></td></tr>';
    html += '<tr><td><label>Admin/Chef Username:</label></td><td><input type="text" id="cd_adminuser" class="domaintext" value=""></td></tr>';
    html += '<tr><td><label>Admin/Chef Password:</label></td><td><input type="password" id="cd_adminpw" class="domaintext" value=""></td></tr>';
    html += '<tr><td><label>Admin/Chef Mail:</label></td><td><input type="text" id="cd_adminmail" class="domaintext" value=""></td></tr>';
    html += '<tr><td></td><td><input type="button" value="Save" onclick="submitCreateDomain()"></td></tr>';
    html += '</table></form>';
    setContent(html);
@@ -360,15 +369,26 @@ function createDomainForm() {
function submitCreateDomain() {
    var optEl = document.getElementById("cd_options");
    var nameEl = document.getElementById("cd_name");
    var adminUserEl = document.getElementById("cd_adminuser");
    var adminPwEl = document.getElementById("cd_adminpw");
    var adminMailEl = document.getElementById("cd_adminmail");
    if (!nameEl.value.trim() || (optEl && !optEl.value.trim())) {
        showError("Domain Name and Domain Options are required.");
        return;
    }
    if ((adminUserEl.value.trim() || adminPwEl.value.trim()) &&
        (!adminUserEl.value.trim() || !adminPwEl.value.trim())) {
        showError("Admin/Chef Username and Password must both be set.");
        return;
    }
    var obj = {
        domainid: document.getElementById("cd_id").value.trim(),
        domainname: nameEl.value,
        domainstorage: parseInt(document.getElementById("cd_storage").value),
        domainoptions: optEl ? optEl.value : ""
        domainoptions: optEl ? optEl.value : "",
        adminusername: adminUserEl.value.trim(),
        adminpassword: adminPwEl.value,
        adminmail: adminMailEl.value.trim()
    };
    ajaxPost("/settings/" + currentDomain + "/api/createdomain", obj, function(err, data) {
        if (err) { showError(err); return; }
+89 −0
Changes for src/admin.cpp: 89 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -230,6 +230,7 @@ namespace authdb {
            bool hasAvatar = false;
            std::string capturedRawPw;
            std::string capturedUsername;
            std::string capturedRole;

            for (const auto &curformdat : curform.multipartData()) {
                if (curformdat.value.empty()) continue;
@@ -245,6 +246,13 @@ namespace authdb {
                    if (tmp == "filename") stortype = BinaryStorage;
                }

                // "role" (admin/mitarbeiter) is UI-only: it drives group
                // membership below, it is not a stored user field.
                if (name == "role") {
                    capturedRole = std::string(curformdat.value.begin(), curformdat.value.end());
                    continue;
                }

                if (stortype == EmptyStorage) {
                    bool numeric = true;
                    for (auto i : curformdat.value) {
@@ -353,6 +361,19 @@ namespace authdb {
            User user;
            user.create(*backend, &udat);

            // role=admin: put the new user into "Domain Admins" right away
            if (capturedRole == "admin") {
                uuid::uuid adminGid;
                if (findGroupByName(*backend, "Domain Admins", adminGid)) {
                    class GroupData grpdat(adminGid);
                    size_t gpos = sizeof(authdb::AuthHeader);
                    Group grp;
                    grp.info(*backend, grpdat, gpos);
                    grpdat.addMember(uid);
                    grp.edit(*backend, grpdat, gpos);
                }
            }

            json_object *jobj = json_object_new_object();
            json_object_object_add(jobj, "status", json_object_new_string("ok"));
            json_object_object_add(jobj, "uid", json_object_new_string(uid.c_str()));
@@ -892,6 +913,54 @@ namespace authdb {
                    gid.generate();
                    class GroupData grpdat(gid);
                    grpdat.setName("Domain Admins");

                    // Optionally create the initial domain admin/chef user
                    // and put it into "Domain Admins" right away
                    json_object *jadminuser = json_object_object_get(jreq, "adminusername");
                    json_object *jadminpw = json_object_object_get(jreq, "adminpassword");
                    if (jadminuser && jadminpw &&
                        strlen(json_object_get_string(jadminuser)) > 0 &&
                        strlen(json_object_get_string(jadminpw)) > 0) {
                        std::string adminUsername = json_object_get_string(jadminuser);
                        std::string adminRawPw = json_object_get_string(jadminpw);

                        uuid::uuid adminuid;
                        adminuid.generate();
                        class UserData adat(adminuid);
                        adat.setUserName(adminUsername);

                        json_object *jadminmail = json_object_object_get(jreq, "adminmail");
                        if (jadminmail && strlen(json_object_get_string(jadminmail)) > 0)
                            adat.setMail(json_object_get_string(jadminmail));

                        Hash hash;
                        std::string pwhash;
                        hash.hash(adminRawPw, pwhash);
                        adat.setPwHash(pwhash);

                        adat.setAvatar(std::vector<char>(
                            reinterpret_cast<const char *>(profile_webp),
                            reinterpret_cast<const char *>(profile_webp) + sizeof(profile_webp)));

                        if (g_KdcPlugin) {
                            try {
                                std::string realm = json_object_get_string(jname);
                                std::transform(realm.begin(), realm.end(), realm.begin(),
                                               [](unsigned char c){ return std::toupper(c); });
                                std::string salt = realm + adminUsername;
                                auto krbKeyBytes = g_KdcPlugin->string2key(
                                    adminRawPw, salt, KDC_ETYPE_AES256_CTS_HMAC_SHA1);
                                adat.setKrbKey(hexEncode(krbKeyBytes));
                            } catch (...) {
                                /* Non-fatal: user is created without krbkey */
                            }
                        }

                        User user;
                        user.create(*domBackend, &adat);
                        grpdat.addMember(adminuid);
                    }

                    Group grp;
                    grp.create(*domBackend, &grpdat);

@@ -2335,6 +2404,26 @@ namespace authdb {
            return resolveDomain(cdid, _AdminBackend, dbackend);
        }

        bool findGroupByName(AuthBackend &backend, const std::string &name, uuid::uuid &outGid) {
            Group group;
            std::vector<uuid::uuid> gids;
            group.list(backend, gids);
            for (const auto &gid : gids) {
                class GroupData gdat(gid);
                try {
                    size_t gpos = sizeof(authdb::AuthHeader);
                    group.info(backend, gdat, gpos);
                    if (gdat.getName() == name) {
                        outGid = gid;
                        return true;
                    }
                } catch (AuthBackendError &e) {
                    std::cerr << e.what() << std::endl;
                }
            }
            return false;
        }

        authdb::AuthBackend &_AdminBackend;
        std::shared_ptr<libhtmlpp::HtmlElement> _LoginElement;
        std::shared_ptr<libhtmlpp::HtmlPage> _Loginpage;