Skip to content

Commit

Permalink
1. Add: Administrator email configuration
Browse files Browse the repository at this point in the history
2. Add: Dockerfile
3. Optimize: email template
4. fix: Users can still log in through email even if disabled
5. Optimize: App avatar

Signed-off-by: 孙林耀 <[email protected]>
  • Loading branch information
MicroOps-cn committed Jun 15, 2023
1 parent 9a2a1a4 commit 9d9ab08
Show file tree
Hide file tree
Showing 32 changed files with 1,260 additions and 484 deletions.
46 changes: 43 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ PROTOC_OPTS := $(PROTOC_OPTS) -I./api
PROTOC_OPTS := $(PROTOC_OPTS) --gogo_out=plugins=grpc,module=${GOMODULENAME}:gogo_out
PROTOC_OPTS := $(PROTOC_OPTS) --grpc-gateway_out=${GOGO_OPT}:gogo_out

BASE_PATH = /idas

IMAGE_SUFFIX :=

# golangci-lint only supports linux, darwin and windows platforms on i386/amd64.
# windows isn't included here because of the path separator being different.
ifeq ($(GOHOSTOS),$(filter $(GOHOSTOS),linux darwin))
Expand All @@ -52,6 +56,24 @@ endif

pkgs = ./...

GitCommit = $(shell git rev-parse --short HEAD)
BuildDate = $(shell date +%Y-%m-%dT%H:%M:%S%Z)
GoVersion = $(shell go version|awk '{print $$3}')
Platform = $(shell go version|awk '{print $$4}')
Version ?= $(shell cat version)
LDFlags := -w -s -X 'lampao/pkg/utils/version.GitCommit=$(GitCommit)'
LDFlags += -X 'lampao/pkg/utils/version.BuildDate=$(BuildDate)'
LDFlags += -X 'lampao/pkg/utils/version.GoVersion=$(GoVersion)'
LDFlags += -X 'lampao/pkg/utils/version.Platform=$(Platform)'
LDFlags += -X 'lampao/pkg/utils/version.Version=$(Version).$(GitCommit)'

info:
@echo "Version: $(Version)"
@echo "Git commit: $(GitCommit)"
@echo "Build date: $(BuildDate)"
@echo "Platform: $(Platform)"
@echo "Go version: $(GoVersion)"

.PHONY: all
all: common-check_license protos common-lint test idas

Expand Down Expand Up @@ -99,7 +121,7 @@ common-check_license:

.PHONY: idas
idas:
CGO_ENABLED=0 go build -ldflags="-s -w" -o dist/idas ./cmd/idas
CGO_ENABLED=0 go build -ldflags="-s -w $(LDFlags)" -o dist/idas ./cmd/idas

.PHONY: common-lint
common-lint: $(GOLANGCI_LINT)
Expand Down Expand Up @@ -128,5 +150,23 @@ openapi:

.PHONY: ui
ui:
cd public && yarn install && yarn run build --basePath='/idas/admin/' --apiPath='/idas/'
rm -rf pkg/transport/static && cp -r public/dist pkg/transport/static
rm -rf public/src/.umi-production/
cd public && yarn install && yarn run build --basePath='$(BASE_PATH)/admin/' --apiPath='$(BASE_PATH)/'
rm -rf pkg/transport/static && cp -r public/dist pkg/transport/static


.PHONY: ui-vpn
ui-vpn:
rm -rf public/src/.umi-production/
cd public && yarn install && yarn run build --basePath='/vpn/idas/admin/' --apiPath='/vpn/idas/'
rm -rf pkg/transport/static && cp -r public/dist pkg/transport/static

.PHONY: idas-vpn
idas-vpn:
CGO_ENABLED=0 go build -ldflags="-s -w $(LDFlags)" -o dist/idas-vpn ./cmd/idas

.PHONY: docker-image
docker-image:
cp dist/idas docker/
if [ ! -f docker/GeoLite2-City.mmdb ];then wget -O docker/GeoLite2-City.mmdb.gz -c "https://cdn.jsdelivr.net/npm/[email protected]/GeoLite2-City.mmdb.gz";gunzip docker/GeoLite2-City.mmdb.gz; fi
cd docker && docker build -t wiseasy/idas:v$(Version).$(GitCommit)$(IMAGE_SUFFIX) .
1 change: 1 addition & 0 deletions api/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ message GlobalOptions{
string sub_title=11;
string logo =12;
string copyright =13;
string admin_email =14;
}

message security{
Expand Down
2 changes: 1 addition & 1 deletion api/endpoints/apps.proto
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ message CreateAppRequest {
idas.service.models.AppMeta.GrantMode grant_mode = 7 [(gogoproto.jsontag) = "grantMode,omitempty"];
repeated AppUser users = 8;
repeated AppRoleInfo roles = 9;
string url = 12 [(gogoproto.jsontag) = "url", (gogoproto.moretags) = 'valid:"required"'];
string url = 12 [(gogoproto.jsontag) = "url"];
AppProxyInfo proxy = 17;
string display_name = 13 [(gogoproto.jsontag) = "displayName,omitempty", (gogoproto.moretags) = 'gorm:"type:varchar(128)"'];
}
Expand Down
165 changes: 87 additions & 78 deletions config/config.pb.go

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions docker/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Dockerfile
.dockerignore
7 changes: 7 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM alpine

WORKDIR /
ADD . /
EXPOSE 8081

ENTRYPOINT ["/idas"]
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ go 1.18
require (
github.com/MicroOps-cn/fuck v1.0.0
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d
github.com/disintegration/letteravatar v0.0.0-20160912210445-1a457b860450
github.com/docker/docker v20.10.24+incompatible
github.com/emicklei/go-restful-openapi/v2 v2.9.1
github.com/emicklei/go-restful/v3 v3.8.1
Expand All @@ -20,7 +21,6 @@ require (
github.com/go-sql-driver/mysql v1.7.0
github.com/gogo/protobuf v1.3.2
github.com/golang-jwt/jwt/v4 v4.0.0
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
github.com/howeyc/gopass v0.0.0-20210920133722-c8aef6fb66ef
github.com/lightstep/lightstep-tracer-go v0.25.0
github.com/moby/term v0.0.0-20220808134915-39b0c02b01ae
Expand All @@ -41,8 +41,6 @@ require (
github.com/tidwall/gjson v1.14.4
github.com/tredoe/osutil v1.0.6
github.com/xlzd/gotp v0.1.0
golang.org/x/exp v0.0.0-20230321023759-10a507213a29
golang.org/x/image v0.5.0
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac
google.golang.org/protobuf v1.28.1
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df
Expand Down Expand Up @@ -75,6 +73,7 @@ require (
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.19.6 // indirect
github.com/go-openapi/swag v0.19.15 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/inconshreveable/mousetrap v1.0.0 // indirect
Expand Down Expand Up @@ -114,6 +113,7 @@ require (
github.com/tklauser/go-sysconf v0.3.4 // indirect
github.com/tklauser/numcpus v0.2.1 // indirect
golang.org/x/crypto v0.1.0 // indirect
golang.org/x/image v0.5.0 // indirect
golang.org/x/mod v0.6.0 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/sys v0.6.0 // indirect
Expand Down
3 changes: 2 additions & 1 deletion go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/disintegration/letteravatar v0.0.0-20160912210445-1a457b860450 h1:bONK4hIXo1mYT3u9dtW7mH7xsy6PwzwxW//IxAlPrbI=
github.com/disintegration/letteravatar v0.0.0-20160912210445-1a457b860450/go.mod h1:/xRvTkTQVbtTtCoVg1yFA4/mrCtaqEw5SaHacBbcT5I=
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/docker v20.10.24+incompatible h1:Ugvxm7a8+Gz6vqQYQQ2W7GYq5EUPaAiuPgIfVyI3dYE=
Expand Down Expand Up @@ -518,7 +520,6 @@ golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug=
golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.5.0 h1:5JMiNunQeQw++mMOz48/ISeNu3Iweh/JaZU8ZLqHRrI=
Expand Down
46 changes: 37 additions & 9 deletions pkg/client/email/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package email

import (
"bytes"
"embed"
"encoding/json"
"fmt"
"html/template"
Expand All @@ -27,11 +28,41 @@ import (
"github.com/MicroOps-cn/idas/api"
)

//go:embed template
var templFs embed.FS

var innerTmpl []Template

type Template struct {
*OriginalTemplate
tmpl *template.Template
}

func init() {
innerTmpl = append(innerTmpl, Template{
OriginalTemplate: &OriginalTemplate{
Subject: "Reset Password",
Topic: "User:ResetPassword",
TemplateFile: "template/reset_password.html",
},
tmpl: template.Must(template.ParseFS(templFs, "template/reset_password.html")),
}, Template{
OriginalTemplate: &OriginalTemplate{
Subject: "Activate Account",
Topic: "User:ActivateAccount",
TemplateFile: "template/activate_account.html",
},
tmpl: template.Must(template.ParseFS(templFs, "template/activate_account.html")),
}, Template{
OriginalTemplate: &OriginalTemplate{
Subject: "One-time Password",
Topic: "User:SendLoginCaptcha",
TemplateFile: "template/send_login_code.html",
},
tmpl: template.Must(template.ParseFS(templFs, "template/send_login_code.html")),
})
}

var _ api.CustomType = &Template{}

func (t Template) Marshal() ([]byte, error) {
Expand All @@ -46,10 +77,7 @@ func (t *Template) Unmarshal(data []byte) (err error) {
return err
}
t.tmpl, err = template.ParseFiles(t.TemplateFile)
if err != nil {
return err
}
return nil
return err
}

func (t Template) MarshalJSON() ([]byte, error) {
Expand All @@ -71,17 +99,17 @@ func (t *Template) UnmarshalJSON(data []byte) (err error) {
}

func (m *SmtpOptions) getTemplate(topic string, sets ...string) *Template {
if len(sets) == 0 {
sets = append(sets, "")
}
var tmpls []Template
tmpls = append(tmpls, m.Template...)
tmpls = append(tmpls, innerTmpl...)
for _, set := range sets {
for _, tmpl := range m.Template {
for _, tmpl := range tmpls {
if tmpl.Topic == topic && tmpl.Set == set {
return &tmpl
}
}
}
for _, tmpl := range m.Template {
for _, tmpl := range tmpls {
if tmpl.Topic == topic && (tmpl.Set == "" || tmpl.Set == "__default__") {
return &tmpl
}
Expand Down
48 changes: 48 additions & 0 deletions pkg/client/email/template/activate_account.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!--
~ Copyright © 2022.
~
~ 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.
-->

<html lang="en">

<body style="margin: 0 auto; font-family: Helvetica, sans-serif; font-size: 16px; color: #333333; text-align: left; max-width: 550px;">
<div>
<div style="margin: 50px 0 15px;">
Hello, {{ .user.Username }}
</div>
<div>Please reset your password to activate your user,<a href="{{.httpExternalURL}}admin/account/activateAccount?userId={{ .user.Id }}&token={{ .token.Id }}&username={{ .user.Username }}"
rel="noopener noreferrer">
Click here
</a>Or copy the following connection to the browser and open it to enter the password reset page.
</div>
{{.httpExternalURL}}admin/account/activateAccount?userId={{ .user.Id }}&token={{ .token.Id }}&username={{ .user.Username }}
<div style="margin-bottom: 50px;">

</div>
<div>
If you did not make this request, your email address may have been entered incorrectly, and you can safely ignore this email.
</div>
<div style="margin: 15px 0;">
If you have any questions, you can
<a href="mailto:{{ .adminEmail }}"
style="color:#007bff; text-decoration: none !important;"
target="_blank"
rel="noopener noreferrer">Contact administrator</a>.
</div>
<div style="color:#828282; margin: 15px 0;">
- Wiseasy Ops Team
</div>
</div>
</body>
</html>
48 changes: 48 additions & 0 deletions pkg/client/email/template/reset_password.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<!--
~ Copyright © 2022.
~
~ 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.
-->

<html lang="en">

<body style="margin: 0 auto; font-family: Helvetica, sans-serif; font-size: 16px; color: #333333; text-align: left; max-width: 550px;">
<div>
<div style="margin: 50px 0 15px;">
Hello, <strong>{{ .user.Username }}</strong>
</div>
<div>You are resetting your password, please<a href="{{.httpExternalURL}}admin/account/resetPassword?userId={{ .user.Id }}&token={{ .token.Id }}&username={{ .user.Username }}"
rel="noopener noreferrer">
Click here
</a>Or copy the following connection to the browser and open it to enter the password reset page.
</div>
{{.httpExternalURL}}admin/account/resetPassword?userId={{ .user.Id }}&token={{ .token.Id }}&username={{ .user.Username }}
<div style="margin-bottom: 50px;">

</div>
<div>
If you did not make this request, your email address may have been entered incorrectly, and you can safely ignore this email.
</div>
<div style="margin: 15px 0;">
If you have any questions, you can
<a href="mailto:{{ .adminEmail }}"
style="color:#007bff; text-decoration: none !important;"
target="_blank"
rel="noopener noreferrer">Contact administrator</a>.
</div>
<div style="color:#828282; margin: 15px 0;">
- Wiseasy Ops Team
</div>
</div>
</body>
</html>
12 changes: 12 additions & 0 deletions pkg/client/email/template/send_login_code.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<html lang="en">

<body style="margin: 0 auto; font-family: Helvetica, sans-serif; font-size: 16px; color: #333333; text-align: left; max-width: 550px;">
<div>
<div style="margin: 50px 0 15px;">
Hello, <strong>{{ .user.Username }}</strong>
</div>
<div>You are currently logging in {{ .siteTitle }}</strong></div>
<div style="margin: 15px 0;">Your One-time password is: <b>{{.code}}</b></div>
</div>
</body>
</html>
Loading

0 comments on commit 9d9ab08

Please sign in to comment.