diff --git a/smash/web/forms/worker_form.py b/smash/web/forms/worker_form.py
index a15504030c93f1481fc4afab6714e35c99276144..8d5fdc67251217d3cfa75f7bf6bd1e2bb1c34f84 100644
--- a/smash/web/forms/worker_form.py
+++ b/smash/web/forms/worker_form.py
@@ -1,7 +1,10 @@
 import logging
+import re
+from collections import OrderedDict
 
 from django import forms
 from django.forms import ModelForm
+from django_common.auth_backends import User
 
 from web.models import Worker, WorkerStudyRole
 from web.models.constants import GLOBAL_STUDY_ID
@@ -33,16 +36,68 @@ class WorkerForm(ModelForm):
         self.fields['role'] = forms.ChoiceField(label='Role', choices=choices)
         self.fields['role'].initial = initial_role
 
+        del self.fields['user']
+
         if worker_type == WORKER_STAFF:
             del self.fields['voucher_types']
         else:
             del self.fields['locations']
-            del self.fields['user']
+
+        fields = OrderedDict()
+
+        if worker_type == WORKER_STAFF:
+            if instance is None or instance.pk is None:
+                fields['login'] = forms.CharField(label='Login')
+                fields['password'] = forms.CharField(label='Password', widget=forms.PasswordInput)
+                fields['password2'] = forms.CharField(label='Repeat password', widget=forms.PasswordInput)
+
+        for key, value in self.fields.items():
+            fields[key] = value
+
+        self.fields = fields
 
     def save(self, commit=True):
+
+        create_user = self.cleaned_data.get("login", None) is not None
+        user = None
+        if create_user:
+            user = User.objects.create_user(username=self.cleaned_data['login'],
+                                            email=self.cleaned_data['email'],
+                                            password=self.cleaned_data['password'])
+
         instance = super(WorkerForm, self).save(commit)
+
+        if create_user:
+            instance.user = user
+            instance.save()
+
         roles = WorkerStudyRole.objects.filter(worker=instance, study_id=GLOBAL_STUDY_ID)
         if roles.count() > 0:
             roles.update(role=self.cleaned_data['role'])
         else:
             WorkerStudyRole.objects.create(worker=instance, study_id=GLOBAL_STUDY_ID, role=self.cleaned_data['role'])
+
+    def clean(self):
+        cleaned_data = super(WorkerForm, self).clean()
+        if cleaned_data.get('password', None) is not None:
+            if cleaned_data['password'] != cleaned_data['password2']:
+                self.add_error('password', "Password don't match")
+                self.add_error('password2', "Password don't match")
+            password = cleaned_data['password']
+            min_length = 10
+            if len(password) < min_length:
+                self.add_error('password', 'Password must be at least ' + str(min_length) + ' characters long.')
+
+            # check for digit
+            if not any(char.isdigit() for char in password):
+                self.add_error('password', 'Password must contain at least 1 digit.')
+
+            # check for letter
+            if not any(char.isalpha() for char in password):
+                self.add_error('password', 'Password must contain at least 1 letter.')
+
+        if cleaned_data.get('login', None) is not None:
+            if not re.match('^[.a-zA-Z0-9]+$', cleaned_data['login']):
+                self.add_error('login', 'Login can contain only alphanumeric characters or dot.')
+
+        return cleaned_data
diff --git a/smash/web/redcap_connector.py b/smash/web/redcap_connector.py
index ff09df743be6cd71ce5826ed375330df967e4df6..9055a1f2ee06ae0c5452a3378b9ea4bb0e25edea 100644
--- a/smash/web/redcap_connector.py
+++ b/smash/web/redcap_connector.py
@@ -222,7 +222,7 @@ class RedcapConnector(object):
         return result
 
     def create_redcap_link(self, pid, redcap_version, subject):
-        return self.base_url + "/redcap_v" + redcap_version + "/DataEntry/index.php?pid=" + pid + "&id=" + \
+        return self.base_url + "/redcap_v" + redcap_version + "/DataEntry/index.php?pid=" + str(pid) + "&id=" + \
                subject.nd_number + "&page=demographics"
 
     def get_red_cap_subjects(self):
diff --git a/smash/web/tests/view/test_worker.py b/smash/web/tests/view/test_worker.py
index dc1aca4dcf08cf8952ccc8240c88fdd9c6f37048..9c49f8d7a80bd1a7053fb468220e92204e43cc5c 100644
--- a/smash/web/tests/view/test_worker.py
+++ b/smash/web/tests/view/test_worker.py
@@ -1,6 +1,7 @@
 import logging
 
 from django.urls import reverse
+from django_common.auth_backends import User
 
 from web.forms import WorkerForm
 from web.models import Worker
@@ -28,6 +29,8 @@ class WorkerViewTests(LoggedInTestCase):
         self.assertEqual(response.status_code, 200)
 
     def test_render_worker_added_request(self):
+        self.assertEqual(1, User.objects.all().count())
+
         language = create_language()
         location = create_location()
 
@@ -35,11 +38,11 @@ class WorkerViewTests(LoggedInTestCase):
 
         response = self.client.post(reverse('web.views.worker_add', kwargs={'worker_type': WORKER_STAFF}),
                                     data=form_data)
-        logger.debug(response.content)
 
         self.assertEqual(response.status_code, 302)
 
         self.assertEqual(1, Worker.objects.all().count())
+        self.assertEqual(2, User.objects.all().count())
 
     def create_add_worker_form_data(self, language, location):
         form_data = self.get_form_data(Worker())
@@ -49,6 +52,9 @@ class WorkerViewTests(LoggedInTestCase):
         form_data["unit"] = "TEST DEPARTMENT"
         form_data["email"] = "john.doe@unknown.domain.com"
         form_data["specialization"] = "tester"
+        form_data["login"] = "tester.login"
+        form_data["password"] = "123qweasdzxc"
+        form_data["password2"] = "123qweasdzxc"
         form_data["languages"] = [language.id]
         form_data["locations"] = [location.id]
         form_data["role"] = ROLE_CHOICES_DOCTOR