Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
mpcs
dfss
Commits
9c837227
Commit
9c837227
authored
Apr 19, 2016
by
Loïck Bonniot
Browse files
[c][gui] Add signature screen
parent
b1909095
Pipeline
#774
failed with stage
Changes
11
Pipelines
1
Hide whitespace changes
Inline
Side-by-side
dfssc/sign.go
View file @
9c837227
...
...
@@ -10,6 +10,8 @@ import (
func
signContract
(
args
[]
string
)
{
filename
:=
args
[
0
]
fmt
.
Println
(
"You are going to sign the following contract:"
)
showContract
(
args
)
contract
:=
getContract
(
filename
)
if
contract
==
nil
{
os
.
Exit
(
1
)
...
...
@@ -24,6 +26,8 @@ func signContract(args []string) {
fmt
.
Fprintln
(
os
.
Stderr
,
err
)
os
.
Exit
(
2
)
}
manager
.
OnSignerStatusUpdate
=
signFeedbackFn
err
=
manager
.
ConnectToPeers
()
if
err
!=
nil
{
fmt
.
Fprintln
(
os
.
Stderr
,
err
)
...
...
@@ -49,6 +53,7 @@ func signContract(args []string) {
fmt
.
Println
(
"Everybody is ready, starting the signature"
,
signatureUUID
)
// Signature
manager
.
OnProgressUpdate
=
signProgressFn
err
=
manager
.
Sign
()
if
err
!=
nil
{
fmt
.
Fprintln
(
os
.
Stderr
,
err
)
...
...
@@ -64,3 +69,13 @@ func signContract(args []string) {
fmt
.
Println
(
"Signature complete! See .proof file for evidences."
)
}
func
signFeedbackFn
(
mail
string
,
status
sign
.
SignerStatus
,
data
string
)
{
if
status
==
sign
.
StatusConnecting
{
fmt
.
Println
(
"- Trying to connect with"
,
mail
,
"/"
,
data
)
}
else
if
status
==
sign
.
StatusConnected
{
fmt
.
Println
(
" Successfully connected!"
,
"["
,
data
,
"]"
)
}
}
func
signProgressFn
(
current
int
,
max
int
)
{}
dfssc/sign/protocol.go
View file @
9c837227
...
...
@@ -29,12 +29,15 @@ func (m *SignatureManager) Sign() error {
// Cooldown delay, let other clients wake-up their channels
time
.
Sleep
(
time
.
Second
)
seqLen
:=
len
(
m
.
sequence
)
// Promess rounds
// Follow the sequence until there is no next occurence of me
for
m
.
currentIndex
>=
0
{
m
.
OnProgressUpdate
(
m
.
currentIndex
,
seqLen
+
1
)
dAPI
.
DLog
(
"starting round at index ["
+
fmt
.
Sprintf
(
"%d"
,
m
.
currentIndex
)
+
"] with nextIndex="
+
fmt
.
Sprintf
(
"%d"
,
nextIndex
))
// Set of
the
promise we are waiting for
// Set of promise
s
we are waiting for
var
pendingSet
[]
uint32
pendingSet
,
err
=
common
.
GetPendingSet
(
m
.
sequence
,
myID
,
m
.
currentIndex
)
if
err
!=
nil
{
...
...
@@ -58,6 +61,7 @@ func (m *SignatureManager) Sign() error {
}
}
m
.
OnProgressUpdate
(
seqLen
,
seqLen
+
1
)
dAPI
.
DLog
(
"entering signature round"
)
// Signature round
err
=
m
.
ExchangeAllSignatures
()
...
...
@@ -65,6 +69,7 @@ func (m *SignatureManager) Sign() error {
return
err
}
dAPI
.
DLog
(
"exiting signature round"
)
m
.
OnProgressUpdate
(
seqLen
+
1
,
seqLen
+
1
)
// Network's job is done, cleaning time
// Shutdown and platform client and TODO peer server & connections
...
...
@@ -125,7 +130,7 @@ func (m *SignatureManager) promiseRound(pendingSet, sendSet []uint32, myID uint3
// Verifying we sent all the due promises
for
range
sendSet
{
_
=
<-
c
<-
c
}
}
...
...
dfssc/sign/starter.go
View file @
9c837227
...
...
@@ -42,6 +42,10 @@ type SignatureManager struct {
keyHash
[][]
byte
mail
string
archives
*
Archives
// Callbacks
OnSignerStatusUpdate
func
(
mail
string
,
status
SignerStatus
,
data
string
)
OnProgressUpdate
func
(
current
int
,
end
int
)
}
// Archives stores the received and sent messages, as evidence if needed
...
...
@@ -139,10 +143,11 @@ func (m *SignatureManager) addPeer(user *pAPI.User) (ready bool, err error) {
}
addrPort
:=
user
.
Ip
+
":"
+
strconv
.
Itoa
(
int
(
user
.
Port
))
fmt
.
Println
(
"- Trying to connect with"
,
user
.
Email
,
"/"
,
addrPort
)
m
.
OnSignerStatusUpdate
(
user
.
Email
,
StatusConnecting
,
addrPort
)
conn
,
err
:=
net
.
Connect
(
addrPort
,
m
.
auth
.
Cert
,
m
.
auth
.
Key
,
m
.
auth
.
CA
)
if
err
!=
nil
{
m
.
OnSignerStatusUpdate
(
user
.
Email
,
StatusError
,
err
.
Error
())
return
false
,
err
}
...
...
@@ -158,12 +163,13 @@ func (m *SignatureManager) addPeer(user *pAPI.User) (ready bool, err error) {
defer
cancel
()
msg
,
err
:=
client
.
Discover
(
ctx
,
&
cAPI
.
Hello
{
Version
:
dfss
.
Version
})
if
err
!=
nil
{
m
.
OnSignerStatusUpdate
(
user
.
Email
,
StatusError
,
err
.
Error
())
return
false
,
err
}
// Printing answer: application version
// TODO check certificate
fmt
.
Println
(
" Successfully c
onnected
!"
,
"["
,
msg
.
Version
,
"]"
)
m
.
OnSignerStatusUpdate
(
user
.
Email
,
StatusC
onnected
,
msg
.
Version
)
// Check if we have any other peer to connect to
if
lastConnection
==
nil
{
...
...
dfssc/sign/status.go
0 → 100644
View file @
9c837227
package
sign
// SignerStatus represents the current state of a signer.
type
SignerStatus
int
// These constants represent the different states of a signer.
const
(
StatusWaiting
SignerStatus
=
iota
StatusConnecting
StatusConnected
StatusError
)
gui/authform/authform.go
View file @
9c837227
...
...
@@ -41,3 +41,9 @@ func NewWidget(conf *config.Config, onAuth func()) *Widget {
return
&
Widget
{
QWidget
:
form
}
}
func
(
w
*
Widget
)
Q
()
*
ui
.
QWidget
{
return
w
.
QWidget
}
func
(
w
*
Widget
)
Tick
()
{}
gui/contractform/contractform.go
View file @
9c837227
...
...
@@ -86,3 +86,9 @@ func (w *Widget) SignersList() (list []string) {
return
}
func
(
w
*
Widget
)
Q
()
*
ui
.
QWidget
{
return
w
.
QWidget
}
func
(
w
*
Widget
)
Tick
()
{}
gui/main.go
View file @
9c837227
...
...
@@ -5,41 +5,100 @@ import (
"dfss/gui/authform"
"dfss/gui/config"
"dfss/gui/contractform"
"dfss/gui/signform"
"dfss/gui/userform"
"github.com/visualfc/goqt/ui"
)
type
window
struct
{
*
ui
.
QMainWindow
current
widget
conf
*
config
.
Config
}
type
widget
interface
{
Q
()
*
ui
.
QWidget
Tick
()
}
func
main
()
{
// Load configuration
conf
:=
config
.
Load
()
// Start first window
ui
.
Run
(
func
()
{
window
:=
ui
.
NewMainWindow
()
var
newuser
*
userform
.
Widget
var
newauth
*
authform
.
Widget
var
newcontract
*
contractform
.
Widget
newauth
=
authform
.
NewWidget
(
&
conf
,
func
()
{
window
.
SetCentralWidget
(
newcontract
)
})
newuser
=
userform
.
NewWidget
(
&
conf
,
func
(
pwd
string
)
{
window
.
SetCentralWidget
(
newauth
)
})
newcontract
=
contractform
.
NewWidget
(
&
conf
)
w
:=
&
window
{
QMainWindow
:
ui
.
NewMainWindow
(),
conf
:
&
conf
,
}
if
conf
.
Authenticated
{
window
.
SetCentralWidget
(
newcontract
)
w
.
addActions
()
w
.
showNewContractForm
()
}
else
if
conf
.
Registered
{
w
indow
.
SetCentralWidget
(
newauth
)
w
.
showAuthForm
(
)
}
else
{
w
indow
.
SetCentralWidget
(
newuser
)
w
.
showUserForm
(
)
}
window
.
SetWindowTitle
(
"DFSS Client v"
+
dfss
.
Version
)
window
.
Show
()
timer
:=
ui
.
NewTimerWithParent
(
w
)
timer
.
OnTimeout
(
func
()
{
w
.
current
.
Tick
()
})
timer
.
StartWithMsec
(
1000
)
w
.
SetWindowTitle
(
"DFSS Client v"
+
dfss
.
Version
)
w
.
SetWindowIcon
(
ui
.
NewIconWithFilename
(
":/images/digital_signature_pen.png"
))
w
.
Show
()
})
}
func
(
w
*
window
)
addActions
()
{
openAct
:=
ui
.
NewActionWithTextParent
(
"&Open"
,
w
)
openAct
.
SetShortcuts
(
ui
.
QKeySequence_Open
)
openAct
.
OnTriggered
(
func
()
{
w
.
showSignForm
()
})
w
.
MenuBar
()
.
AddAction
(
openAct
)
}
func
(
w
*
window
)
setScreen
(
wi
widget
)
{
old
:=
w
.
CentralWidget
()
w
.
SetCentralWidget
(
wi
.
Q
())
w
.
current
=
wi
if
old
!=
nil
{
old
.
DeleteLater
()
}
}
func
(
w
*
window
)
showUserForm
()
{
w
.
setScreen
(
userform
.
NewWidget
(
w
.
conf
,
func
(
pwd
string
)
{
w
.
showAuthForm
()
}))
}
func
(
w
*
window
)
showAuthForm
()
{
w
.
setScreen
(
authform
.
NewWidget
(
w
.
conf
,
func
()
{
w
.
showNewContractForm
()
w
.
addActions
()
}))
}
func
(
w
*
window
)
showNewContractForm
()
{
w
.
setScreen
(
contractform
.
NewWidget
(
w
.
conf
))
}
func
(
w
*
window
)
showSignForm
()
{
home
:=
config
.
GetHomeDir
()
filter
:=
"Contract file (*.json);;Any (*.*)"
filename
:=
ui
.
QFileDialogGetOpenFileNameWithParentCaptionDirFilterSelectedfilterOptions
(
w
,
"Select the contract file"
,
home
,
filter
,
&
filter
,
0
)
if
filename
!=
""
{
config
.
PasswordDialog
(
func
(
err
error
,
pwd
string
)
{
widget
:=
signform
.
NewWidget
(
w
.
conf
,
filename
,
pwd
)
if
widget
!=
nil
{
w
.
setScreen
(
widget
)
}
})
}
}
gui/signform/icons.go
0 → 100644
View file @
9c837227
package
signform
import
(
"dfss/dfssc/sign"
"github.com/visualfc/goqt/ui"
)
var
icons
map
[
sign
.
SignerStatus
]
*
ui
.
QIcon
var
icons_labels
=
map
[
sign
.
SignerStatus
]
string
{
sign
.
StatusWaiting
:
"Waiting"
,
sign
.
StatusConnecting
:
"Connecting"
,
sign
.
StatusConnected
:
"Connected"
,
sign
.
StatusError
:
"Error"
,
}
var
iconsLoaded
=
false
func
loadIcons
()
{
if
iconsLoaded
{
return
}
icons
=
map
[
sign
.
SignerStatus
]
*
ui
.
QIcon
{
sign
.
StatusWaiting
:
ui
.
NewIconWithFilename
(
":/images/time.png"
),
sign
.
StatusConnecting
:
ui
.
NewIconWithFilename
(
":/images/time.png"
),
sign
.
StatusConnected
:
ui
.
NewIconWithFilename
(
":/images/connected.png"
),
sign
.
StatusError
:
ui
.
NewIconWithFilename
(
":/images/error.png"
),
}
iconsLoaded
=
true
}
gui/signform/signform.go
View file @
9c837227
package
signform
import
(
"encoding/json"
"io/ioutil"
"dfss/dfssc/sign"
"dfss/dfssp/contract"
"dfss/gui/config"
"github.com/visualfc/goqt/ui"
)
type
line
struct
{
status
sign
.
SignerStatus
info
,
mail
string
cellA
,
cellB
,
cellC
*
ui
.
QTableWidgetItem
}
type
Widget
struct
{
*
ui
.
QWidget
manager
*
sign
.
SignatureManager
contract
*
contract
.
JSON
table
*
ui
.
QTableWidget
progressBar
*
ui
.
QProgressBar
feedbackLabel
*
ui
.
QLabel
lines
[]
line
statusMax
,
statusCurrent
int32
feedback
string
}
func
NewWidget
(
conf
*
config
.
Config
,
onAuth
func
())
*
Widget
{
func
NewWidget
(
conf
*
config
.
Config
,
filename
,
pwd
string
)
*
Widget
{
loadIcons
()
file
:=
ui
.
NewFileWithName
(
":/signform/signform.ui"
)
loader
:=
ui
.
NewUiLoader
()
form
:=
loader
.
Load
(
file
)
w
:=
&
Widget
{
QWidget
:
form
}
w
.
feedbackLabel
=
ui
.
NewLabelFromDriver
(
w
.
FindChild
(
"mainLabel"
))
w
.
table
=
ui
.
NewTableWidgetFromDriver
(
w
.
FindChild
(
"signersTable"
))
w
.
progressBar
=
ui
.
NewProgressBarFromDriver
(
w
.
FindChild
(
"progressBar"
))
data
,
err
:=
ioutil
.
ReadFile
(
filename
)
if
err
!=
nil
{
return
nil
}
w
.
contract
=
new
(
contract
.
JSON
)
err
=
json
.
Unmarshal
(
data
,
w
.
contract
)
if
err
!=
nil
{
return
nil
}
home
:=
config
.
GetHomeDir
()
m
,
err
:=
sign
.
NewSignatureManager
(
home
+
config
.
CAFile
,
home
+
config
.
CertFile
,
home
+
config
.
KeyFile
,
conf
.
Platform
,
pwd
,
9005
,
// TODO change port
w
.
contract
,
)
if
err
!=
nil
{
// TODO
}
w
.
manager
=
m
w
.
manager
.
OnSignerStatusUpdate
=
w
.
signerUpdated
w
.
manager
.
OnProgressUpdate
=
func
(
current
int
,
max
int
)
{
w
.
statusCurrent
=
int32
(
current
)
w
.
statusMax
=
int32
(
max
)
}
w
.
initLines
()
w
.
signerUpdated
(
conf
.
Email
,
sign
.
StatusConnected
,
"It's you!"
)
go
func
()
{
err
=
w
.
execute
()
if
err
!=
nil
{
w
.
feedback
=
err
.
Error
()
}
else
{
w
.
feedback
=
"Contract signed successfully!"
}
}()
return
w
}
func
(
w
*
Widget
)
execute
()
error
{
w
.
feedback
=
"Connecting to peers..."
err
:=
w
.
manager
.
ConnectToPeers
()
if
err
!=
nil
{
return
err
}
w
.
feedback
=
"Waiting for peers..."
_
,
err
=
w
.
manager
.
SendReadySign
()
if
err
!=
nil
{
return
err
}
w
.
feedback
=
"Signature in progress..."
err
=
w
.
manager
.
Sign
()
if
err
!=
nil
{
return
err
}
w
.
feedback
=
"Storing file..."
return
w
.
manager
.
PersistSignaturesToFile
()
// TODO choose destination
}
func
(
w
*
Widget
)
signerUpdated
(
mail
string
,
status
sign
.
SignerStatus
,
data
string
)
{
for
i
,
s
:=
range
w
.
contract
.
Signers
{
if
s
.
Email
==
mail
{
w
.
lines
[
i
]
.
status
=
status
w
.
lines
[
i
]
.
info
=
data
break
}
}
}
// Tick updates the whole screen, as we cannot directly update the screen on each callback.
// It is called by the screen coordinator via a timer.
func
(
w
*
Widget
)
Tick
()
{
w
.
feedbackLabel
.
SetText
(
w
.
feedback
)
w
.
progressBar
.
SetMaximum
(
w
.
statusMax
)
w
.
progressBar
.
SetValue
(
w
.
statusCurrent
)
for
_
,
l
:=
range
w
.
lines
{
l
.
cellA
.
SetIcon
(
icons
[
l
.
status
])
l
.
cellA
.
SetText
(
icons_labels
[
l
.
status
])
l
.
cellB
.
SetText
(
l
.
info
)
}
}
func
(
w
*
Widget
)
initLines
()
{
w
.
table
.
SetRowCount
(
int32
(
len
(
w
.
contract
.
Signers
)))
for
i
,
s
:=
range
w
.
contract
.
Signers
{
status
:=
ui
.
NewTableWidgetItemWithIconTextType
(
icons
[
sign
.
StatusWaiting
],
icons_labels
[
sign
.
StatusWaiting
],
int32
(
ui
.
QTableWidgetItem_UserType
))
w
.
table
.
SetItem
(
int32
(
i
),
0
,
status
)
info
:=
ui
.
NewTableWidgetItemWithTextType
(
""
,
int32
(
ui
.
QTableWidgetItem_UserType
))
w
.
table
.
SetItem
(
int32
(
i
),
1
,
info
)
mail
:=
ui
.
NewTableWidgetItemWithTextType
(
s
.
Email
,
int32
(
ui
.
QTableWidgetItem_UserType
))
w
.
table
.
SetItem
(
int32
(
i
),
2
,
mail
)
// We must store items, otherwise GC will remove it and cause the application to crash.
// Trust me, hard to debug...
w
.
lines
=
append
(
w
.
lines
,
line
{
sign
.
StatusWaiting
,
""
,
s
.
Email
,
status
,
info
,
mail
})
}
}
func
(
w
*
Widget
)
Q
()
*
ui
.
QWidget
{
return
w
.
QWidget
}
gui/signform/signform.ui
View file @
9c837227
...
...
@@ -50,8 +50,20 @@
</property>
<item>
<widget
class=
"QLabel"
name=
"mainLabel"
>
<property
name=
"sizePolicy"
>
<sizepolicy
hsizetype=
"Fixed"
vsizetype=
"Preferred"
>
<horstretch>
0
</horstretch>
<verstretch>
0
</verstretch>
</sizepolicy>
</property>
<property
name=
"minimumSize"
>
<size>
<width>
400
</width>
<height>
0
</height>
</size>
</property>
<property
name=
"text"
>
<string>
<
html
><
head/
><
body
><
p
><
span style=
"
font-size:18pt;
">
Preparing signature...
<
/span
><
/p
><
/body
><
/html
>
</string>
<string>
Preparing signature...
</string>
</property>
</widget>
</item>
...
...
@@ -82,6 +94,9 @@
</item>
<item>
<widget
class=
"QTableWidget"
name=
"signersTable"
>
<property
name=
"editTriggers"
>
<set>
QAbstractItemView::NoEditTriggers
</set>
</property>
<property
name=
"alternatingRowColors"
>
<bool>
true
</bool>
</property>
...
...
@@ -101,7 +116,7 @@
<number>
200
</number>
</attribute>
<attribute
name=
"horizontalHeaderMinimumSectionSize"
>
<number>
20
0
</number>
<number>
5
0
</number>
</attribute>
<attribute
name=
"horizontalHeaderStretchLastSection"
>
<bool>
true
</bool>
...
...
@@ -122,7 +137,7 @@
</column>
<column>
<property
name=
"text"
>
<string>
Ping
</string>
<string>
Info
</string>
</property>
</column>
<column>
...
...
gui/userform/userform.go
View file @
9c837227
...
...
@@ -71,3 +71,9 @@ func copyCA(from string, to string) error {
return
ioutil
.
WriteFile
(
to
,
file
,
0600
)
}
func
(
w
*
Widget
)
Q
()
*
ui
.
QWidget
{
return
w
.
QWidget
}
func
(
w
*
Widget
)
Tick
()
{}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment