Merge pull request #3 from reasonerjt/master

sync code from personal repo
This commit is contained in:
reasonerjt 2016-02-24 14:40:16 +08:00
commit 2bdf12e2b4
29 changed files with 485 additions and 411 deletions

View File

@ -15,12 +15,10 @@ http {
upstream registry {
server registry:5000;
# check interval=2000 rise=1 fall=1 timeout=5000 type=tcp;
}
upstream ui {
server ui:80;
# check interval=2000 rise=1 fall=1 timeout=5000 type=tcp;
}

View File

@ -39,20 +39,20 @@ ui:
- ./config/ui/app.conf:/etc/ui/app.conf
- ./config/ui/private_key.pem:/etc/ui/private_key.pem
links:
- registry:registry
- mysql:mysql
- registry
- mysql
- log
log_driver: "syslog"
log_opt:
syslog-address: "tcp://127.0.0.1:1514"
syslog-tag: "ui"
roxy:
proxy:
image: library/nginx:1.9
volumes:
- ./config/nginx/nginx.conf:/etc/nginx/nginx.conf
links:
- ui:ui
- registry:registry
- ui
- registry
- log
ports:
- 80:80

View File

@ -1,23 +1,18 @@
FROM library/ubuntu:14.04
# run logrotate hourly
RUN mv /etc/cron.daily/logrotate /etc/cron.hourly/
# run logrotate hourly, disable imklog model, provides TCP/UDP syslog reception
RUN mv /etc/cron.daily/logrotate /etc/cron.hourly/ \
&& sed 's/$ModLoad imklog/#$ModLoad imklog/' -i /etc/rsyslog.conf \
&& sed 's/$KLogPermitNonKernelFacility on/#$KLogPermitNonKernelFacility on/' -i /etc/rsyslog.conf \
&& sed 's/#$ModLoad imudp/$ModLoad imudp/' -i /etc/rsyslog.conf \
&& sed 's/#$UDPServerRun 514/$UDPServerRun 514/' -i /etc/rsyslog.conf \
&& sed 's/#$ModLoad imtcp/$ModLoad imtcp/' -i /etc/rsyslog.conf \
&& sed 's/#$InputTCPServerRun 514/$InputTCPServerRun 514/' -i /etc/rsyslog.conf \
&& rm /etc/rsyslog.d/*
# logrotate configuration file for docker
ADD logrotate_docker.conf /etc/logrotate.d/
#disable imklog model
RUN sed 's/$ModLoad imklog/#$ModLoad imklog/' -i /etc/rsyslog.conf
RUN sed 's/$KLogPermitNonKernelFacility on/#$KLogPermitNonKernelFacility on/' -i /etc/rsyslog.conf
# provides TCP/UDP syslog reception
RUN sed 's/#$ModLoad imudp/$ModLoad imudp/' -i /etc/rsyslog.conf
RUN sed 's/#$UDPServerRun 514/$UDPServerRun 514/' -i /etc/rsyslog.conf
RUN sed 's/#$ModLoad imtcp/$ModLoad imtcp/' -i /etc/rsyslog.conf
RUN sed 's/#$InputTCPServerRun 514/$InputTCPServerRun 514/' -i /etc/rsyslog.conf
RUN rm /etc/rsyslog.d/*
# rsyslog configuration file for docker
ADD rsyslog_docker.conf /etc/rsyslog.d/
@ -26,3 +21,4 @@ VOLUME /var/log/docker/
EXPOSE 514
CMD cron && chown -R syslog:syslog /var/log/docker/ && rsyslogd -n

View File

@ -14,8 +14,8 @@ WORKDIR /go/src/github.com/vmware/harbor
ENV GO15VENDOREXPERIMENT 1
RUN go get -d github.com/docker/distribution \
&& go get -d github.com/docker/libtrust \
&& go get -d github.com/go-sql-driver/mysql
RUN go install -v -a
&& go get -d github.com/go-sql-driver/mysql \
&& go install -v -a
ENV MYSQL_USR root \
MYSQL_PWD root \
@ -23,7 +23,6 @@ ENV MYSQL_USR root \
MYSQL_PORT_3306_TCP_PORT 3306 \
REGISTRY_URL localhost:5000
COPY conf /go/bin/conf
COPY views /go/bin/views
COPY static /go/bin/static

View File

@ -9,7 +9,6 @@ ENV REGISTRY_URL localhost:5000
RUN apt-get update -qqy && apt-get install -qqy libldap2-dev
ADD harbor /go/bin/harbor
ADD conf /go/bin/conf
ADD views /go/bin/views
ADD static /go/bin/static

View File

@ -40,7 +40,7 @@ func (b *BaseAPI) DecodeJsonReq(v interface{}) {
err := json.Unmarshal(b.Ctx.Input.CopyBody(1<<32), v)
if err != nil {
beego.Error("Error while decoding the json request:", err)
b.CustomAbort(400, "Invalid json request")
b.CustomAbort(http.StatusBadRequest, "Invalid json request")
}
}
@ -49,17 +49,17 @@ func (b *BaseAPI) ValidateUser() int {
sessionUserId := b.GetSession("userId")
if sessionUserId == nil {
beego.Warning("No user id in session, canceling request")
b.CustomAbort(401, "")
b.CustomAbort(http.StatusUnauthorized, "")
}
userId := sessionUserId.(int)
u, err := dao.GetUser(models.User{UserId: userId})
if err != nil {
beego.Error("Error occurred in GetUser:", err)
b.CustomAbort(500, "Internal error.")
b.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if u == nil {
beego.Warning("User was deleted already, user id: ", userId, " canceling request.")
b.CustomAbort(401, "")
b.CustomAbort(http.StatusUnauthorized, "")
}
return userId
}

View File

@ -17,6 +17,7 @@ package api
import (
"fmt"
"log"
"net/http"
"github.com/vmware/harbor/dao"
"github.com/vmware/harbor/models"
@ -48,15 +49,15 @@ func (p *ProjectAPI) Prepare() {
p.projectId, err = strconv.ParseInt(id_str, 10, 64)
if err != nil {
log.Printf("Error parsing project id: %s, error: %v", id_str, err)
p.CustomAbort(400, "invalid project id")
p.CustomAbort(http.StatusBadRequest, "invalid project id")
}
exist, err := dao.ProjectExists(p.projectId)
if err != nil {
log.Printf("Error occurred in ProjectExists: %v", err)
p.CustomAbort(500, "Internal error.")
p.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if !exist {
p.CustomAbort(404, fmt.Sprintf("project does not exist, id: %v", p.projectId))
p.CustomAbort(http.StatusNotFound, fmt.Sprintf("project does not exist, id: %v", p.projectId))
}
}
}
@ -71,7 +72,7 @@ func (p *ProjectAPI) Post() {
err := validateProjectReq(req)
if err != nil {
beego.Error("Invalid project request, error: ", err)
p.RenderError(400, "Invalid request for creating project")
p.RenderError(http.StatusBadRequest, "Invalid request for creating project")
return
}
projectName := req.ProjectName
@ -80,14 +81,14 @@ func (p *ProjectAPI) Post() {
beego.Error("Error happened checking project existence in db:", err, ", project name:", projectName)
}
if exist {
p.RenderError(409, "")
p.RenderError(http.StatusConflict, "")
return
}
project := models.Project{OwnerId: p.userId, Name: projectName, CreationTime: time.Now(), Public: public}
err = dao.AddProject(project)
if err != nil {
beego.Error("Failed to add project, error: %v", err)
p.RenderError(500, "Failed to add project")
p.RenderError(http.StatusInternalServerError, "Failed to add project")
}
}
@ -96,11 +97,11 @@ func (p *ProjectAPI) Head() {
result, err := dao.ProjectExists(projectName)
if err != nil {
beego.Error("Error while communicating with DB: ", err)
p.RenderError(500, "Error while communicating with DB")
p.RenderError(http.StatusInternalServerError, "Error while communicating with DB")
return
}
if !result {
p.RenderError(404, "")
p.RenderError(http.StatusNotFound, "")
return
}
}
@ -117,7 +118,7 @@ func (p *ProjectAPI) Get() {
projectList, err := dao.QueryProject(queryProject)
if err != nil {
beego.Error("Error occurred in QueryProject:", err)
p.CustomAbort(500, "Internal error.")
p.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
for i := 0; i < len(projectList); i++ {
if isProjectAdmin(p.userId, projectList[i].ProjectId) {
@ -135,7 +136,7 @@ func (p *ProjectAPI) Put() {
projectId, err := strconv.ParseInt(p.Ctx.Input.Param(":id"), 10, 64)
if err != nil {
beego.Error("Error parsing project id:", projectId, ", error: ", err)
p.RenderError(400, "invalid project id")
p.RenderError(http.StatusBadRequest, "invalid project id")
return
}
@ -145,13 +146,13 @@ func (p *ProjectAPI) Put() {
}
if !isProjectAdmin(p.userId, projectId) {
beego.Warning("Current user, id:", p.userId, ", does not have project admin role for project, id:", projectId)
p.RenderError(403, "")
p.RenderError(http.StatusForbidden, "")
return
}
err = dao.ToggleProjectPublicity(p.projectId, public)
if err != nil {
beego.Error("Error while updating project, project id:", projectId, ", error:", err)
p.RenderError(500, "Failed to update project")
p.RenderError(http.StatusInternalServerError, "Failed to update project")
}
}
@ -162,14 +163,18 @@ func (p *ProjectAPI) FilterAccessLog() {
username := filter.Username
keywords := filter.Keywords
beginTime := filter.BeginTime
endTime := filter.EndTime
query := models.AccessLog{ProjectId: p.projectId, Username: "%" + username + "%", Keywords: keywords, BeginTime: beginTime, EndTime: endTime}
beginTime := time.Unix(filter.BeginTimestamp, 0)
endTime := time.Unix(filter.EndTimestamp, 0)
query := models.AccessLog{ProjectId: p.projectId, Username: "%" + username + "%", Keywords: keywords, BeginTime: beginTime, BeginTimestamp: filter.BeginTimestamp, EndTime: endTime, EndTimestamp: filter.EndTimestamp}
log.Printf("Query AccessLog: begin: %v, end: %v, keywords: %s", query.BeginTime, query.EndTime, query.Keywords)
accessLogList, err := dao.GetAccessLogs(query)
if err != nil {
log.Printf("Error occurred in GetAccessLogs: %v", err)
p.CustomAbort(500, "Internal error.")
p.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
p.Data["json"] = accessLogList
p.ServeJSON()

View File

@ -15,12 +15,13 @@
package api
import (
"net/http"
"strconv"
"github.com/vmware/harbor/dao"
"github.com/vmware/harbor/models"
"github.com/astaxie/beego"
"strconv"
)
type ProjectMemberAPI struct {
@ -40,18 +41,18 @@ func (pma *ProjectMemberAPI) Prepare() {
pid, err := strconv.ParseInt(pma.Ctx.Input.Param(":pid"), 10, 64)
if err != nil {
beego.Error("Error parsing project id:", pid, ", error:", err)
pma.CustomAbort(400, "invalid project Id")
pma.CustomAbort(http.StatusBadRequest, "invalid project Id")
return
}
p, err := dao.GetProjectById(models.Project{ProjectId: pid})
if err != nil {
beego.Error("Error occurred in GetProjectById:", err)
pma.CustomAbort(500, "Internal error.")
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if p == nil {
beego.Warning("Project with id:", pid, "does not exist.")
pma.CustomAbort(404, "Project does not exist")
pma.CustomAbort(http.StatusNotFound, "Project does not exist")
}
pma.project = p
pma.currentUserId = pma.ValidateUser()
@ -64,7 +65,7 @@ func (pma *ProjectMemberAPI) Prepare() {
memberId, err := strconv.Atoi(mid)
if err != nil {
beego.Error("Invalid member Id, error:", err)
pma.CustomAbort(400, "Invalid member id")
pma.CustomAbort(http.StatusBadRequest, "Invalid member id")
}
pma.memberId = memberId
}
@ -74,7 +75,7 @@ func (pma *ProjectMemberAPI) Get() {
pid := pma.project.ProjectId
if !CheckProjectPermission(pma.currentUserId, pid) {
beego.Warning("Current user, user id :", pma.currentUserId, "does not have permission for project, id:", pid)
pma.RenderError(403, "")
pma.RenderError(http.StatusForbidden, "")
return
}
if pma.memberId == 0 { //member id not set return list of the members
@ -84,7 +85,7 @@ func (pma *ProjectMemberAPI) Get() {
userList, err := dao.GetUserByProject(queryProject, queryUser)
if err != nil {
beego.Error("Failed to query database for member list, error:", err)
pma.RenderError(500, "Internal Server Error")
pma.RenderError(http.StatusInternalServerError, "Internal Server Error")
return
}
pma.Data["json"] = userList
@ -92,14 +93,14 @@ func (pma *ProjectMemberAPI) Get() {
roleList, err := dao.GetUserProjectRoles(models.User{UserId: pma.memberId}, pid)
if err != nil {
beego.Error("Error occurred in GetUserProjectRoles:", err)
pma.CustomAbort(500, "Internal error.")
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
//return empty role list to indicate if a user is not a member
result := make(map[string]interface{})
user, err := dao.GetUser(models.User{UserId: pma.memberId})
if err != nil {
beego.Error("Error occurred in GetUser:", err)
pma.CustomAbort(500, "Internal error.")
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
result["user_name"] = user.Username
result["user_id"] = pma.memberId
@ -115,11 +116,11 @@ func (pma *ProjectMemberAPI) Post() {
rolelist, err := dao.GetUserProjectRoles(userQuery, pid)
if err != nil {
beego.Error("Error occurred in GetUserProjectRoles:", err)
pma.CustomAbort(500, "Internal error.")
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if len(rolelist) == 0 {
beego.Warning("Current user, id:", pma.currentUserId, "does not have project admin role for project, id:", pid)
pma.RenderError(403, "")
pma.RenderError(http.StatusForbidden, "")
return
}
var req memberReq
@ -128,17 +129,17 @@ func (pma *ProjectMemberAPI) Post() {
userId := CheckUserExists(username)
if userId <= 0 {
beego.Warning("User does not exist, user name:", username)
pma.RenderError(404, "User does not exist")
pma.RenderError(http.StatusNotFound, "User does not exist")
return
}
rolelist, err = dao.GetUserProjectRoles(models.User{UserId: userId}, pid)
if err != nil {
beego.Error("Error occurred in GetUserProjectRoles:", err)
pma.CustomAbort(500, "Internal error.")
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if len(rolelist) > 0 {
beego.Warning("user is already added to project, user id:", userId, ", project id:", pid)
pma.RenderError(409, "user is ready in project")
pma.RenderError(http.StatusConflict, "user is ready in project")
return
}
@ -146,7 +147,7 @@ func (pma *ProjectMemberAPI) Post() {
err = dao.AddUserProjectRole(userId, pid, int(rid))
if err != nil {
beego.Error("Failed to update DB to add project user role, project id:", pid, ", user id:", userId, ", role id:", rid)
pma.RenderError(500, "Failed to update data in database")
pma.RenderError(http.StatusInternalServerError, "Failed to update data in database")
return
}
}
@ -159,11 +160,11 @@ func (pma *ProjectMemberAPI) Put() {
rolelist, err := dao.GetUserProjectRoles(userQuery, pid)
if err != nil {
beego.Error("Error occurred in GetUserProjectRoles:", err)
pma.CustomAbort(500, "Internal error.")
pma.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if len(rolelist) == 0 {
beego.Warning("Current user, id:", pma.currentUserId, ", does not have project admin role for project, id:", pid)
pma.RenderError(403, "")
pma.RenderError(http.StatusForbidden, "")
return
}
var req memberReq
@ -171,7 +172,7 @@ func (pma *ProjectMemberAPI) Put() {
roleList, err := dao.GetUserProjectRoles(models.User{UserId: mid}, pid)
if len(roleList) == 0 {
beego.Warning("User is not in project, user id:", mid, ", project id:", pid)
pma.RenderError(404, "user not exist in project")
pma.RenderError(http.StatusNotFound, "user not exist in project")
return
}
//TODO: delete and insert should in one transaction
@ -179,7 +180,7 @@ func (pma *ProjectMemberAPI) Put() {
err = dao.DeleteUserProjectRoles(mid, pid)
if err != nil {
beego.Error("Failed to delete project roles for user, user id:", mid, ", project id: ", pid, ", error: ", err)
pma.RenderError(500, "Failed to update data in DB")
pma.RenderError(http.StatusInternalServerError, "Failed to update data in DB")
return
}
//insert roles in request
@ -187,7 +188,7 @@ func (pma *ProjectMemberAPI) Put() {
err = dao.AddUserProjectRole(mid, pid, int(rid))
if err != nil {
beego.Error("Failed to update DB to add project user role, project id:", pid, ", user id:", mid, ", role id:", rid)
pma.RenderError(500, "Failed to update data in database")
pma.RenderError(http.StatusInternalServerError, "Failed to update data in database")
return
}
}
@ -200,13 +201,13 @@ func (pma *ProjectMemberAPI) Delete() {
rolelist, err := dao.GetUserProjectRoles(userQuery, pid)
if len(rolelist) == 0 {
beego.Warning("Current user, id:", pma.currentUserId, ", does not have project admin role for project, id:", pid)
pma.RenderError(403, "")
pma.RenderError(http.StatusForbidden, "")
return
}
err = dao.DeleteUserProjectRoles(mid, pid)
if err != nil {
beego.Error("Failed to delete project roles for user, user id:", mid, ", project id:", pid, ", error:", err)
pma.RenderError(500, "Failed to update data in DB")
pma.RenderError(http.StatusInternalServerError, "Failed to update data in DB")
return
}
}

View File

@ -16,6 +16,7 @@ package api
import (
"encoding/json"
"net/http"
"strconv"
"strings"
"time"
@ -56,28 +57,28 @@ func (ra *RepositoryAPI) Get() {
projectId, err0 := ra.GetInt64("project_id")
if err0 != nil {
beego.Error("Failed to get project id, error:", err0)
ra.RenderError(400, "Invalid project id")
ra.RenderError(http.StatusBadRequest, "Invalid project id")
return
}
projectQuery := models.Project{ProjectId: projectId}
p, err := dao.GetProjectById(projectQuery)
if err != nil {
beego.Error("Error occurred in GetProjectById:", err)
ra.CustomAbort(500, "Internal error.")
ra.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if p == nil {
beego.Warning("Project with Id:", projectId, ", does not exist", projectId)
ra.RenderError(404, "")
ra.RenderError(http.StatusNotFound, "")
return
}
if p.Public == 0 && !CheckProjectPermission(ra.userId, projectId) {
ra.RenderError(403, "")
ra.RenderError(http.StatusForbidden, "")
return
}
repoList, err := svc_utils.GetRepoFromCache()
if err != nil {
beego.Error("Failed to get repo from cache, error:", err)
ra.RenderError(500, "internal sever error")
ra.RenderError(http.StatusInternalServerError, "internal sever error")
}
projectName := p.Name
q := ra.GetString("q")
@ -127,7 +128,7 @@ func (ra *RepositoryAPI) GetTags() {
result, err := svc_utils.RegistryApiGet(svc_utils.BuildRegistryUrl(repoName, "tags", "list"), ra.username)
if err != nil {
beego.Error("Failed to get repo tags, repo name:", repoName, ", error: ", err)
ra.RenderError(500, "Failed to get repo tags")
ra.RenderError(http.StatusInternalServerError, "Failed to get repo tags")
} else {
t := Tag{}
json.Unmarshal(result, &t)
@ -146,14 +147,14 @@ func (ra *RepositoryAPI) GetManifests() {
result, err := svc_utils.RegistryApiGet(svc_utils.BuildRegistryUrl(repoName, "manifests", tag), ra.username)
if err != nil {
beego.Error("Failed to get manifests for repo, repo name:", repoName, ", tag:", tag, ", error:", err)
ra.RenderError(500, "Internal Server Error")
ra.RenderError(http.StatusInternalServerError, "Internal Server Error")
return
} else {
mani := Manifest{}
err = json.Unmarshal(result, &mani)
if err != nil {
beego.Error("Failed to decode json from response for manifests, repo name:", repoName, ", tag:", tag, ", error:", err)
ra.RenderError(500, "Internal Server Error")
ra.RenderError(http.StatusInternalServerError, "Internal Server Error")
return
} else {
v1Compatibility := mani.History[0].V1Compatibility
@ -161,7 +162,7 @@ func (ra *RepositoryAPI) GetManifests() {
err = json.Unmarshal([]byte(v1Compatibility), &item)
if err != nil {
beego.Error("Failed to decode V1 field for repo, repo name:", repoName, ", tag:", tag, ", error:", err)
ra.RenderError(500, "Internal Server Error")
ra.RenderError(http.StatusInternalServerError, "Internal Server Error")
return
} else {
item.CreatedStr = item.Created.Format("2006-01-02 15:04:05")

View File

@ -15,6 +15,7 @@
package api
import (
"net/http"
"sort"
"strings"
@ -44,7 +45,7 @@ func (n *SearchAPI) Get() {
projects, err := dao.QueryRelevantProjects(userId)
if err != nil {
beego.Error("Failed to get projects of user id:", userId, ", error:", err)
n.CustomAbort(500, "Failed to get project search result")
n.CustomAbort(http.StatusInternalServerError, "Failed to get project search result")
}
projectSorter := &utils.ProjectSorter{Projects: projects}
sort.Sort(projectSorter)
@ -66,7 +67,7 @@ func (n *SearchAPI) Get() {
repositories, err2 := svc_utils.GetRepoFromCache()
if err2 != nil {
beego.Error("Failed to get repos from cache, error :", err2)
n.CustomAbort(500, "Failed to get repositories search result")
n.CustomAbort(http.StatusInternalServerError, "Failed to get repositories search result")
}
sort.Strings(repositories)
repositoryResult := filterRepositories(repositories, projects, keyword)

View File

@ -15,6 +15,7 @@
package api
import (
"net/http"
"strconv"
"github.com/vmware/harbor/dao"
@ -40,17 +41,17 @@ func (ua *UserAPI) Prepare() {
ua.userId, err = strconv.Atoi(id)
if err != nil {
beego.Error("Invalid user id, error:", err)
ua.CustomAbort(400, "Invalid user Id")
ua.CustomAbort(http.StatusBadRequest, "Invalid user Id")
}
userQuery := models.User{UserId: ua.userId}
u, err := dao.GetUser(userQuery)
if err != nil {
beego.Error("Error occurred in GetUser:", err)
ua.CustomAbort(500, "Internal error.")
ua.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if u == nil {
beego.Error("User with Id:", ua.userId, "does not exist")
ua.CustomAbort(404, "")
ua.CustomAbort(http.StatusNotFound, "")
}
}
}
@ -59,13 +60,13 @@ func (ua *UserAPI) Get() {
exist, err := dao.IsAdminRole(ua.currentUid)
if err != nil {
beego.Error("Error occurred in IsAdminRole:", err)
ua.CustomAbort(500, "Internal error.")
ua.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if ua.userId == 0 { //list users
if !exist {
beego.Error("Current user, id:", ua.currentUid, ", does not have admin role, can not list users")
ua.RenderError(403, "User does not have admin role")
ua.RenderError(http.StatusForbidden, "User does not have admin role")
return
}
username := ua.GetString("username")
@ -76,7 +77,7 @@ func (ua *UserAPI) Get() {
userList, err := dao.ListUsers(userQuery)
if err != nil {
beego.Error("Failed to get data from database, error:", err)
ua.RenderError(500, "Failed to query from database")
ua.RenderError(http.StatusInternalServerError, "Failed to query from database")
return
}
ua.Data["json"] = userList
@ -86,12 +87,12 @@ func (ua *UserAPI) Get() {
u, err := dao.GetUser(userQuery)
if err != nil {
beego.Error("Error occurred in GetUser:", err)
ua.CustomAbort(500, "Internal error.")
ua.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
ua.Data["json"] = u
} else {
beego.Error("Current user, id:", ua.currentUid, "does not have admin role, can not view other user's detail")
ua.RenderError(403, "User does not have admin role")
ua.RenderError(http.StatusForbidden, "User does not have admin role")
return
}
ua.ServeJSON()
@ -101,11 +102,11 @@ func (ua *UserAPI) Put() { //currently only for toggle admin, so no request body
exist, err := dao.IsAdminRole(ua.currentUid)
if err != nil {
beego.Error("Error occurred in IsAdminRole:", err)
ua.CustomAbort(500, "Internal error.")
ua.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if !exist {
beego.Warning("current user, id:", ua.currentUid, ", does not have admin role, can not update other user's role")
ua.RenderError(403, "User does not have admin role")
ua.RenderError(http.StatusForbidden, "User does not have admin role")
return
}
userQuery := models.User{UserId: ua.userId}
@ -116,17 +117,17 @@ func (ua *UserAPI) Delete() {
exist, err := dao.IsAdminRole(ua.currentUid)
if err != nil {
beego.Error("Error occurred in IsAdminRole:", err)
ua.CustomAbort(500, "Internal error.")
ua.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if !exist {
beego.Warning("current user, id:", ua.currentUid, ", does not have admin role, can not remove user")
ua.RenderError(403, "User does not have admin role")
ua.RenderError(http.StatusForbidden, "User does not have admin role")
return
}
err = dao.DeleteUser(ua.userId)
if err != nil {
beego.Error("Failed to delete data from database, error:", err)
ua.RenderError(500, "Failed to delete User")
ua.RenderError(http.StatusInternalServerError, "Failed to delete User")
return
}
}

View File

@ -1,9 +0,0 @@
appname = harbor
runmode = dev
[lang]
types = en-US|zh-CN
names = en-US|zh-CN
[dev]
httpport = 80

View File

@ -1,15 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQClak/4HO7EeLU0w/BhtVENPLOqU0AP2QjVUdg1qhNiDWVrbWx9
KYHqz5Kn0n2+fxdZo3o7ZY5/2+hhgkKh1z6Kge9XGgune6z4fx2J/X2Se8WsGeQU
TiND8ngSnsCANtYFwW50SbUZPtyf5XjAfKRofZem51OxbxzN3217L/ubKwIDAQAB
AoGBAITMMuNYJwAogCGaZHOs4yMjZoIJT9bpQMQxbsi2f9UqOA/ky0I4foqKloyQ
2k6DLbXTHqBsydgwLgGKWAAiE5xIR2bPMUNSLgjbA2eLly3aOR/0FJ5n09k2EmGg
Am7tLP+6yneXWKVi3HI3NzXriVjWK94WHGGC1b9F+n5CY/2RAkEA1d62OJUNve2k
IY6/b6T0BdssFo3VFcm22vnayEL/wcYrnRfF9Pb5wM4HUUqwVelKTouivXg60GNK
ZKYAx5CtHwJBAMYAEf5u0CQ/8URcwBuMkm0LzK4AM2x1nGs7gIxAEFhu1Z4xPjVe
MtIxuHhDhlLvD760uccmo5yE72QJ1ZrYBHUCQQCAxLZMPRpoB4QyHEOREe1G9V6H
OeBZXPk2wQcEWqqo3gt2a1DqHCXl+2aWgHTJVUxDHHngwFoRDCdHkFeZ0LcbAkAj
T8/luI2WaXD16DS6tQ9IM1qFjbOeHDuRRENgv+wqWVnvpIibq/kUU5m6mRBTqh78
u+6F/fYf6/VluftGalAhAkAukdMtt+sksq2e7Qw2dRr5GXtXjt+Otjj0NaJENmWk
a7SgAs34EOWtbd0XGYpZFrg134MzQGbweFeEUTj++e8p
-----END RSA PRIVATE KEY-----

View File

@ -15,6 +15,7 @@
package controllers
import (
"log"
"os"
"strings"
@ -114,6 +115,16 @@ var langTypes []*langType
func init() {
//conf/app.conf -> os.Getenv("config_path")
configPath := os.Getenv("CONFIG_PATH")
if len(configPath) != 0 {
log.Printf("Config path: %s", configPath)
beego.AppConfigPath = configPath
if err := beego.ParseConfig(); err != nil {
beego.Warning("Failed to parse config file: ", configPath, "error: ", err)
}
}
beego.AddFuncMap("i18n", i18n.Tr)
langs := strings.Split(beego.AppConfig.String("lang::types"), "|")
@ -134,7 +145,6 @@ func init() {
for _, lang := range langs {
if err := i18n.SetMessage(lang, "static/i18n/"+"locale_"+lang+".ini"); err != nil {
beego.Error("Fail to set message file:" + err.Error())
return
}
}
}

View File

@ -15,6 +15,7 @@
package controllers
import (
"net/http"
"net/url"
"os"
@ -68,7 +69,7 @@ func (idc *ItemDetailController) Get() {
projectId, _ := idc.GetInt64("project_id")
if CheckPublicProject(projectId) == false && (sessionUserId == nil || !CheckProjectRole(sessionUserId.(int), projectId)) {
idc.Redirect("/signIn?uri="+url.QueryEscape(idc.Ctx.Input.URI()), 302)
idc.Redirect("/signIn?uri="+url.QueryEscape(idc.Ctx.Input.URI()), http.StatusFound)
}
projectQuery := models.Project{ProjectId: projectId}
@ -76,11 +77,11 @@ func (idc *ItemDetailController) Get() {
if err != nil {
beego.Error("Error occurred in GetProjectById:", err)
idc.CustomAbort(500, "Internal error.")
idc.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if project == nil {
idc.Redirect("/signIn", 302)
idc.Redirect("/signIn", http.StatusFound)
}
idc.Data["ProjectId"] = project.ProjectId
@ -94,7 +95,7 @@ func (idc *ItemDetailController) Get() {
roleList, err := dao.GetUserProjectRoles(models.User{UserId: sessionUserId.(int)}, projectId)
if err != nil {
beego.Error("Error occurred in GetUserProjectRoles:", err)
idc.CustomAbort(500, "Internal error.")
idc.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if len(roleList) > 0 {
idc.Data["RoleId"] = roleList[0].RoleId

View File

@ -15,6 +15,8 @@
package controllers
import (
"net/http"
"github.com/vmware/harbor/models"
"github.com/vmware/harbor/opt_auth"
@ -45,11 +47,11 @@ func (c *CommonController) Login() {
user, err := opt_auth.Login(models.AuthModel{principal, password})
if err != nil {
beego.Error("Error occurred in UserLogin:", err)
c.CustomAbort(500, "Internal error.")
c.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if user == nil {
c.CustomAbort(401, "")
c.CustomAbort(http.StatusUnauthorized, "")
}
c.SetSession("userId", user.UserId)
@ -62,7 +64,7 @@ func (c *CommonController) SwitchLanguage() {
c.SetSession("lang", lang)
c.Data["Lang"] = lang
}
c.Redirect(c.Ctx.Request.Header.Get("Referer"), 302)
c.Redirect(c.Ctx.Request.Header.Get("Referer"), http.StatusFound)
}
func (c *CommonController) Logout() {

View File

@ -16,6 +16,7 @@ package controllers
import (
"bytes"
"net/http"
"os"
"regexp"
"text/template"
@ -34,7 +35,7 @@ type ChangePasswordController struct {
func (cpc *ChangePasswordController) Get() {
sessionUserId := cpc.GetSession("userId")
if sessionUserId == nil {
cpc.Redirect("/signIn", 302)
cpc.Redirect("/signIn", http.StatusFound)
}
cpc.Data["Username"] = cpc.GetSession("username")
cpc.ForwardTo("page_title_change_password", "change-password")
@ -43,32 +44,40 @@ func (cpc *ChangePasswordController) Get() {
func (cpc *CommonController) UpdatePassword() {
sessionUserId := cpc.GetSession("userId")
sessionUsername := cpc.GetSession("username")
if sessionUserId == nil || sessionUsername == nil {
if sessionUserId == nil {
beego.Warning("User does not login.")
cpc.CustomAbort(401, "please_login_first")
cpc.CustomAbort(http.StatusUnauthorized, "please_login_first")
}
oldPassword := cpc.GetString("old_password")
queryUser := models.User{UserId: sessionUserId.(int), Username: sessionUsername.(string), Password: oldPassword}
if oldPassword == "" {
beego.Error("Old password is blank")
cpc.CustomAbort(http.StatusBadRequest, "Old password is blank")
}
queryUser := models.User{UserId: sessionUserId.(int), Password: oldPassword}
user, err := dao.CheckUserPassword(queryUser)
if err != nil {
beego.Error("Error occurred in CheckUserPassword:", err)
cpc.CustomAbort(500, "Internal error.")
cpc.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if user == nil {
beego.Warning("Password input is not correct")
cpc.CustomAbort(403, "old_password_is_not_correct")
cpc.CustomAbort(http.StatusForbidden, "old_password_is_not_correct")
}
password := cpc.GetString("password")
if password != "" {
updateUser := models.User{UserId: sessionUserId.(int), Username: sessionUsername.(string), Password: password, Salt: user.Salt}
dao.ChangeUserPassword(updateUser)
updateUser := models.User{UserId: sessionUserId.(int), Password: password, Salt: user.Salt}
err = dao.ChangeUserPassword(updateUser, oldPassword)
if err != nil {
beego.Error("Error occurred in ChangeUserPassword:", err)
cpc.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
} else {
cpc.CustomAbort(404, "please_input_new_password")
cpc.CustomAbort(http.StatusBadRequest, "please_input_new_password")
}
}
@ -90,22 +99,26 @@ func (fpc *CommonController) SendEmail() {
email := fpc.GetString("email")
if ok, _ := regexp.MatchString(`^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$`, email); ok {
pass, _ := regexp.MatchString(`^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$`, email)
if !pass {
fpc.CustomAbort(http.StatusBadRequest, "email_content_illegal")
} else {
queryUser := models.User{Email: email}
exist, err := dao.UserExists(queryUser, "email")
if err != nil {
beego.Error("Error occurred in UserExists:", err)
fpc.CustomAbort(500, "Internal error.")
fpc.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if !exist {
fpc.CustomAbort(404, "email_does_not_exist")
fpc.CustomAbort(http.StatusNotFound, "email_does_not_exist")
}
messageTemplate, err := template.ParseFiles("views/reset-password-mail.tpl")
if err != nil {
beego.Error("Parse email template file failed:", err)
fpc.CustomAbort(500, err.Error())
fpc.CustomAbort(http.StatusInternalServerError, err.Error())
}
message := new(bytes.Buffer)
@ -117,7 +130,7 @@ func (fpc *CommonController) SendEmail() {
uuid, err := dao.GenerateRandomString()
if err != nil {
beego.Error("Error occurred in GenerateRandomString:", err)
fpc.CustomAbort(500, "Internal error.")
fpc.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
err = messageTemplate.Execute(message, MessageDetail{
Hint: fpc.Tr("reset_email_hint"),
@ -127,13 +140,13 @@ func (fpc *CommonController) SendEmail() {
if err != nil {
beego.Error("message template error:", err)
fpc.CustomAbort(500, "internal_error")
fpc.CustomAbort(http.StatusInternalServerError, "internal_error")
}
config, err := beego.AppConfig.GetSection("mail")
if err != nil {
beego.Error("Can not load app.conf:", err)
fpc.CustomAbort(500, "internal_error")
fpc.CustomAbort(http.StatusInternalServerError, "internal_error")
}
mail := utils.Mail{
@ -146,14 +159,12 @@ func (fpc *CommonController) SendEmail() {
if err != nil {
beego.Error("send email failed:", err)
fpc.CustomAbort(500, "send_email_failed")
fpc.CustomAbort(http.StatusInternalServerError, "send_email_failed")
}
user := models.User{ResetUuid: uuid, Email: email}
dao.UpdateUserResetUuid(user)
} else {
fpc.CustomAbort(409, "email_content_illegal")
}
}
@ -164,39 +175,55 @@ type ResetPasswordController struct {
func (rpc *ResetPasswordController) Get() {
q := rpc.GetString("q")
queryUser := models.User{ResetUuid: q}
resetUuid := rpc.GetString("reset_uuid")
if resetUuid == "" {
beego.Error("Reset uuid is blank.")
rpc.Redirect("/", http.StatusFound)
}
queryUser := models.User{ResetUuid: resetUuid}
user, err := dao.GetUser(queryUser)
if err != nil {
beego.Error("Error occurred in GetUser:", err)
rpc.CustomAbort(500, "Internal error.")
rpc.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if user != nil {
rpc.Data["ResetUuid"] = user.ResetUuid
rpc.ForwardTo("page_title_reset_password", "reset-password")
} else {
rpc.Redirect("/", 302)
rpc.Redirect("/", http.StatusFound)
}
}
func (rpc *CommonController) ResetPassword() {
resetUuid := rpc.GetString("reset_uuid")
if resetUuid == "" {
rpc.CustomAbort(http.StatusBadRequest, "Reset uuid is blank.")
}
queryUser := models.User{ResetUuid: resetUuid}
user, err := dao.GetUser(queryUser)
if err != nil {
beego.Error("Error occurred in GetUser:", err)
rpc.CustomAbort(500, "Internal error.")
rpc.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
if user == nil {
beego.Error("User does not exist")
rpc.CustomAbort(http.StatusBadRequest, "User does not exist")
}
password := rpc.GetString("password")
if password != "" {
user.Password = password
dao.ResetUserPassword(*user)
err = dao.ResetUserPassword(*user)
if err != nil {
beego.Error("Error occurred in ResetUserPassword:", err)
rpc.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
} else {
rpc.CustomAbort(404, "password_is_required")
rpc.CustomAbort(http.StatusBadRequest, "password_is_required")
}
}

View File

@ -15,6 +15,7 @@
package controllers
import (
"net/http"
"os"
"strings"
@ -33,7 +34,7 @@ func (rc *RegisterController) Get() {
if authMode == "" || authMode == "db_auth" {
rc.ForwardTo("page_title_registration", "register")
} else {
rc.Redirect("/signIn", 404)
rc.Redirect("/signIn", http.StatusNotFound)
}
}
@ -49,7 +50,7 @@ func (rc *CommonController) SignUp() {
_, err := dao.Register(user)
if err != nil {
beego.Error("Error occurred in Register:", err)
rc.CustomAbort(500, "Internal error.")
rc.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
}
@ -68,7 +69,7 @@ func (rc *CommonController) UserExists() {
exist, err := dao.UserExists(user, target)
if err != nil {
beego.Error("Error occurred in UserExists:", err)
rc.CustomAbort(500, "Internal error.")
rc.CustomAbort(http.StatusInternalServerError, "Internal error.")
}
rc.Data["json"] = exist
rc.ServeJSON()

View File

@ -73,13 +73,13 @@ func GetAccessLogs(accessLog models.AccessLog) ([]models.AccessLog, error) {
}
}
}
if accessLog.BeginTime != "" {
sql += ` and a.op_time >= str_to_date(?, '%Y-%m-%d %H:%i:%s') `
queryParam = append(queryParam, accessLog.BeginTime+" 00:00:00.000000")
if accessLog.BeginTimestamp > 0 {
sql += ` and a.op_time >= ? `
queryParam = append(queryParam, accessLog.BeginTime)
}
if accessLog.EndTime != "" {
sql += ` and a.op_time <= str_to_date(?, '%Y-%m-%d %H:%i:%s') `
queryParam = append(queryParam, accessLog.EndTime+" 23:59:59.99999")
if accessLog.EndTimestamp > 0 {
sql += ` and a.op_time <= ? `
queryParam = append(queryParam, accessLog.EndTime)
}
sql += ` order by a.op_time desc `

View File

@ -1,16 +1,16 @@
/*
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
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.
Copyright (c) 2016 VMware, Inc. All Rights Reserved.
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 dao
@ -50,18 +50,17 @@ func isContainIllegalChar(s string, illegalChar []string) bool {
func GenerateRandomString() (string, error) {
o := orm.NewOrm()
var salt string
err := o.Raw(`select uuid() as uuid`).QueryRow(&salt)
var uuid string
err := o.Raw(`select uuid() as uuid`).QueryRow(&uuid)
if err != nil {
return "", err
}
return salt, nil
return uuid, nil
}
func init() {
func InitDB() {
orm.RegisterDriver("mysql", orm.DRMySQL)
addr := os.Getenv("MYSQL_HOST")
if len(addr) == 0 {
addr = os.Getenv("MYSQL_PORT_3306_TCP_ADDR")
@ -112,8 +111,11 @@ func init() {
}()
select {
case <-ch:
case <-time.After(30 * time.Second):
panic("Failed to connect to DB after 30 seconds")
case <-time.After(60 * time.Second):
panic("Failed to connect to DB after 60 seconds")
}
err := orm.RegisterDataBase("default", "mysql", db_str)
if err != nil {
panic(err)
}
orm.RegisterDataBase("default", "mysql", db_str)
}

View File

@ -15,6 +15,9 @@
package dao
import (
"database/sql"
"errors"
"github.com/vmware/harbor/models"
"github.com/vmware/harbor/utils"
@ -133,15 +136,44 @@ func ToggleUserAdminRole(u models.User) error {
return err
}
func ChangeUserPassword(u models.User) error {
func ChangeUserPassword(u models.User, oldPassword ...string) error {
o := orm.NewOrm()
_, err := o.Raw(`update user set password=?, salt=? where user_id=?`, utils.Encrypt(u.Password, u.Salt), u.Salt, u.UserId).Exec()
var err error
var r sql.Result
if len(oldPassword) == 0 {
//In some cases, it may no need to check old password, just as Linux change password policies.
_, err = o.Raw(`update user set password=?, salt=? where user_id=?`, utils.Encrypt(u.Password, u.Salt), u.Salt, u.UserId).Exec()
} else if len(oldPassword) == 1 {
r, err = o.Raw(`update user set password=?, salt=? where user_id=? and password = ?`, utils.Encrypt(u.Password, u.Salt), u.Salt, u.UserId, utils.Encrypt(oldPassword[0], u.Salt)).Exec()
if err != nil {
return err
}
count, err := r.RowsAffected()
if err != nil {
return err
}
if count == 0 {
return errors.New("No record be changed, change password failed.")
}
} else {
return errors.New("Wrong numbers of params.")
}
return err
}
func ResetUserPassword(u models.User) error {
o := orm.NewOrm()
_, err := o.Raw(`update user set password=?, reset_uuid=? where reset_uuid=?`, utils.Encrypt(u.Password, u.Salt), "", u.ResetUuid).Exec()
r, err := o.Raw(`update user set password=?, reset_uuid=? where reset_uuid=?`, utils.Encrypt(u.Password, u.Salt), "", u.ResetUuid).Exec()
if err != nil {
return err
}
count, err := r.RowsAffected()
if err != nil {
return err
}
if count == 0 {
return errors.New("No record be changed, reset password failed.")
}
return err
}

12
main.go
View File

@ -38,7 +38,7 @@ func updateInitPassword(userId int, password string) error {
queryUser := models.User{UserId: userId}
user, err := dao.GetUser(queryUser)
if err != nil {
log.Println("Failed to get user in initial password, userId:", userId)
log.Println("Failed to get user, userId:", userId)
return err
}
if user == nil {
@ -67,15 +67,7 @@ func updateInitPassword(userId int, password string) error {
func main() {
beego.BConfig.WebConfig.Session.SessionOn = true
//conf/app.conf -> os.Getenv("config_path")
configPath := os.Getenv("CONFIG_PATH")
if len(configPath) != 0 {
beego.Debug(fmt.Sprintf("Config path: %s", configPath))
beego.AppConfigPath = configPath
}
dao.InitDB()
updateInitPassword(ADMIN_USER_ID, os.Getenv("HARBOR_ADMIN_PASSWORD"))
beego.Run()
}

View File

@ -26,10 +26,11 @@ type AccessLog struct {
Guid string
Operation string
OpTime time.Time
OpTimeStr string
Username string
Keywords string
BeginTime string
EndTime string
BeginTime time.Time
BeginTimestamp int64
EndTime time.Time
EndTimestamp int64
}

View File

@ -16,6 +16,7 @@ package service
import (
"log"
"net/http"
"github.com/vmware/harbor/models"
"github.com/vmware/harbor/opt_auth"
@ -46,7 +47,7 @@ func (a *AuthController) Auth() {
if len(scope) == 0 && !authenticated {
log.Printf("login request with invalid credentials")
a.CustomAbort(401, "")
a.CustomAbort(http.StatusUnauthorized, "")
}
access := svc_utils.GetResourceActions(scope)
for _, a := range access {
@ -61,7 +62,7 @@ func (a *AuthController) serveToken(username, service string, access []*token.Re
rawToken, err := svc_utils.MakeToken(username, service, access)
if err != nil {
log.Printf("Failed to make token, error: %v", err)
writer.WriteHeader(500)
writer.WriteHeader(http.StatusInternalServerError)
return
}
tk := make(map[string]string)

View File

@ -50,9 +50,9 @@ func RegistryApiGet(url, username string) ([]byte, error) {
return nil, err
}
defer response.Body.Close()
if response.StatusCode == 200 {
if response.StatusCode == http.StatusOK {
return result, nil
} else if response.StatusCode == 401 {
} else if response.StatusCode == http.StatusUnauthorized {
authenticate := response.Header.Get("WWW-Authenticate")
str := strings.Split(authenticate, " ")[1]
log.Println("url: " + url)
@ -94,7 +94,7 @@ func RegistryApiGet(url, username string) ([]byte, error) {
if err != nil {
return nil, err
}
if response.StatusCode != 200 {
if response.StatusCode != http.StatusOK {
errMsg := fmt.Sprintf("Unexpected return code from registry: %d", response.StatusCode)
log.Printf(errMsg)
return nil, fmt.Errorf(errMsg)

View File

@ -374,24 +374,38 @@ jQuery(function(){
listUser(username);
});
function toUTCSeconds(date, hour, min, sec) {
var t = new Date(date);
t.setHours(hour);
t.setMinutes(min);
t.setSeconds(sec);
var utcTime = new Date(t.getUTCFullYear(),
t.getUTCMonth(),
t.getUTCDate(),
t.getUTCHours(),
t.getUTCMinutes(),
t.getUTCSeconds());
return utcTime.getTime() / 1000;
}
$("#btnFilterLog").on("click", function(){
var projectId = $("#projectId").val();
var username = $("#txtSearchUserName").val();
var beginTime = "";
var endTime = "";
var beginTimestamp = 0;
var endTimestamp = 0;
if($("#begindatepicker").val() != ""){
beginTime = moment(new Date($("#begindatepicker").val())).format("YYYY-MM-DD");
beginTimestamp = toUTCSeconds($("#begindatepicker").val(), 0, 0, 0);
}
if($("#enddatepicker").val() != ""){
endTime = moment(new Date($("#enddatepicker").val())).format("YYYY-MM-DD");
endTimestamp = toUTCSeconds($("#enddatepicker").val(), 23, 59, 59);
}
new AjaxUtil({
url: "/api/projects/" + projectId + "/logs/filter",
data:{"username":username, "project_id" : projectId, "keywords" : getKeyWords() , "beginTime" : beginTime, "endTime" : endTime},
data:{"username":username, "project_id" : projectId, "keywords" : getKeyWords() , "beginTimestamp" : beginTimestamp, "endTimestamp" : endTimestamp},
type: "post",
success: function(data, status, xhr){
if(xhr && xhr.status == 200){

View File

@ -15,8 +15,8 @@
package test
import (
"flag"
"fmt"
// "fmt"
"log"
"os"
"testing"
@ -85,9 +85,7 @@ func clearUp(username string) {
}
const USERNAME string = "Tester01"
const PROJECT_NAME string = "test_project"
const SYS_ADMIN int = 1
const PROJECT_ADMIN int = 2
const DEVELOPER int = 3
@ -98,35 +96,37 @@ const PUBLICITY_OFF = 0
func TestMain(m *testing.M) {
//Create a custom flag set, let user to provide DB related configures for testing.
fs := flag.NewFlagSet("DB related configures", 0)
dbIp := fs.String("db_ip", "localhost", "IP address for connecting a test DB.")
dbPort := fs.String("db_port", "3306", "Port number for connecting a test DB.")
dbUser := fs.String("db_user", "root", "Username for logging in a test DB.")
dbPassword := fs.String("db_password", "root", "Password for logging in a test DB.")
fs.Parse([]string{"db_ip", "db_port", "db_user", "db_password"})
if fs.NFlag() == 0 {
fs.PrintDefaults()
fmt.Println("Now, use DEFAULT values if omit to set all of flags.")
dbHost := os.Getenv("DB_HOST")
if len(dbHost) == 0 {
log.Fatalf("environment variable DB_HOST is not set")
}
dbUser := os.Getenv("DB_USR")
if len(dbUser) == 0 {
log.Fatalf("environment variable DB_USR is not set")
}
dbPort := os.Getenv("DB_PORT")
if len(dbPort) == 0 {
log.Fatalf("environment variable DB_PORT is not set")
}
dbPassword := os.Getenv("DB_PWD")
if len(dbPassword) == 0 {
log.Fatalf("environment variable DB_PWD is not set")
}
if fs.Parsed() {
fmt.Printf("DB_HOST: %s, DB_USR: %s, DB_PORT: %s, DB_PWD: %s\n", dbHost, dbUser, dbPort, dbPassword)
clearUp(USERNAME)
os.Setenv("MYSQL_PORT_3306_TCP_ADDR", dbHost)
os.Setenv("MYSQL_PORT_3306_TCP_PORT", dbPort)
os.Setenv("MYSQL_USR", dbUser)
os.Setenv("MYSQL_PWD", dbPassword)
os.Setenv("AUTH_MODE", "db_auth")
dao.InitDB()
clearUp(USERNAME)
os.Exit(m.Run())
os.Setenv("MYSQL_PORT_3306_TCP_ADDR", *dbIp)
os.Setenv("MYSQL_PORT_3306_TCP_PORT", *dbPort)
os.Setenv("MYSQL_USR", *dbUser)
os.Setenv("MYSQL_PWD", *dbPassword)
os.Setenv("AUTH_MODE", "db_auth")
os.Exit(m.Run())
}
}
func ExampleRegister() {
func TestRegister(t *testing.T) {
user := models.User{
Username: USERNAME,
@ -138,7 +138,7 @@ func ExampleRegister() {
_, err := dao.Register(user)
if err != nil {
log.Printf("Error occurred in Register: %v", err)
t.Errorf("Error occurred in Register: %v", err)
}
//Check if user registered successfully.
@ -147,41 +147,46 @@ func ExampleRegister() {
}
newUser, err := dao.GetUser(queryUser)
if err != nil {
log.Fatalf("Error occurred in GetUser: %v", err)
t.Errorf("Error occurred in GetUser: %v", err)
}
fmt.Println(newUser.Username)
fmt.Println(newUser.Email)
// Output:
// Tester01
// tester01@vmware.com
if newUser.Username != USERNAME {
t.Errorf("Username does not match, expected: %s, actual: %s", USERNAME, newUser.Username)
}
if newUser.Email != "tester01@vmware.com" {
t.Errorf("Email does not match, expected: %s, actual: %s", "tester01@vmware.com", newUser.Email)
}
}
func ExampleUserExists() {
func TestUserExists(t *testing.T) {
var exists bool
var err error
exists, err = dao.UserExists(models.User{Username: "Tester01"}, "username")
fmt.Println(exists)
exists, err = dao.UserExists(models.User{Username: USERNAME}, "username")
if err != nil {
log.Fatalf("Error occurred in UserExists: %v", err)
t.Errorf("Error occurred in UserExists: %v", err)
}
if !exists {
t.Errorf("User %s was inserted but does not exist", USERNAME)
}
exists, err = dao.UserExists(models.User{Email: "tester01@vmware.com"}, "email")
fmt.Println(exists)
if err != nil {
log.Fatalf("Error occurred in UserExists: %v", err)
t.Errorf("Error occurred in UserExists: %v", err)
}
if !exists {
t.Errorf("User with email %s inserted but does not exist", "tester01@vmware.com")
}
exists, err = dao.UserExists(models.User{Username: "NOTHERE"}, "username")
if err != nil {
t.Errorf("Error occurred in UserExists: %v", err)
}
if exists {
t.Errorf("User %s was not inserted but does exist", "NOTHERE")
}
//Output:
//true
//true
}
func ExampleLoginByUserName() {
func TestLoginByUserName(t *testing.T) {
userQuery := models.User{
Username: USERNAME,
@ -190,18 +195,18 @@ func ExampleLoginByUserName() {
loginUser, err := dao.LoginByDb(models.AuthModel{userQuery.Username, userQuery.Password})
if err != nil {
log.Fatalf("Error occurred in LoginByDb: %v", err)
t.Errorf("Error occurred in LoginByDb: %v", err)
}
if loginUser == nil {
log.Fatalf("No found for user logined by username and password: %v", userQuery)
t.Errorf("No found for user logined by username and password: %v", userQuery)
}
fmt.Println(loginUser.Username)
// Output:
// Tester01
if loginUser.Username != USERNAME {
t.Errorf("User's username does not match after login, expected: %s, actual: %s", USERNAME, loginUser.Username)
}
}
func ExampleLoginByEmail() {
func TestLoginByEmail(t *testing.T) {
userQuery := models.User{
Email: "tester01@vmware.com",
@ -210,105 +215,136 @@ func ExampleLoginByEmail() {
loginUser, err := dao.LoginByDb(models.AuthModel{userQuery.Email, userQuery.Password})
if err != nil {
log.Fatalf("Error occurred in LoginByDb: %v", err)
t.Errorf("Error occurred in LoginByDb: %v", err)
}
if loginUser == nil {
log.Fatalf("No found for user logined by email and password : %v", userQuery)
t.Errorf("No found for user logined by email and password : %v", userQuery)
}
if loginUser.Username != USERNAME {
t.Errorf("User's username does not match after login, expected: %s, actual: %s", USERNAME, loginUser.Username)
}
fmt.Println(loginUser.Username)
// Output:
// Tester01
}
var currentUser *models.User
func ExampleGetUser() {
func TestGetUser(t *testing.T) {
queryUser := models.User{
Username: USERNAME,
}
var err error
currentUser, err = dao.GetUser(queryUser)
if err != nil {
log.Fatalf("Error occurred in GetUser", err)
t.Errorf("Error occurred in GetUser: %v", err)
}
if currentUser == nil {
log.Fatalf("No user found queried by username: %v", queryUser)
t.Errorf("No user found queried by user query: %+v", queryUser)
}
if currentUser.Email != "tester01@vmware.com" {
t.Errorf("the user's email does not match, expected: tester01@vmware.com, actual: %s", currentUser.Email)
}
fmt.Println(currentUser.Username)
//Output:
//Tester01
}
func ExampleListUsers() {
users, err := dao.ListUsers(models.User{Username: "tester01"})
func TestListUsers(t *testing.T) {
users, err := dao.ListUsers(models.User{})
if err != nil {
log.Fatalf("Error occurred in ListUsers: %v", err)
t.Errorf("Error occurred in ListUsers: %v", err)
}
for _, u := range users {
fmt.Println(u.Username)
if len(users) != 1 {
t.Errorf("Expect one user in list, but the acutal length is %d, the list: %+v", len(users), users)
}
users2, err := dao.ListUsers(models.User{Username: USERNAME})
if len(users2) != 1 {
t.Errorf("Expect one user in list, but the acutal length is %d, the list: %+v", len(users), users)
}
if users2[0].Username != USERNAME {
t.Errorf("The username in result list does not match, expected: %s, actual: %s", USERNAME, users2[0].Username)
}
//Output:
//Tester01
}
func ExampleResetUserPassword() {
func TestResetUserPassword(t *testing.T) {
uuid, err := dao.GenerateRandomString()
if err != nil {
log.Fatalf("Error occurred in GenerateRandomString: %v", err)
t.Errorf("Error occurred in GenerateRandomString: %v", err)
}
err = dao.UpdateUserResetUuid(models.User{ResetUuid: uuid, Email: currentUser.Email})
if err != nil {
log.Fatalf("Error occurred in UpdateUserResetUuid: %v", err)
t.Errorf("Error occurred in UpdateUserResetUuid: %v", err)
}
err = dao.ResetUserPassword(models.User{UserId: currentUser.UserId, Password: "HarborTester12345", ResetUuid: uuid, Salt: currentUser.Salt})
if err != nil {
log.Fatalf("Error occurred in ResetUserPassword: %v", err)
t.Errorf("Error occurred in ResetUserPassword: %v", err)
}
loginedUser, err := dao.LoginByDb(models.AuthModel{Principal: currentUser.Username, Password: "HarborTester12345"})
if err != nil {
log.Fatalf("Error occurred in LoginByDb: %v", err)
t.Errorf("Error occurred in LoginByDb: %v", err)
}
fmt.Println(loginedUser.Username)
//Output:
//Tester01
if loginedUser.Username != USERNAME {
t.Errorf("The username returned by Login does not match, expected: %s, acutal: %s", USERNAME, loginedUser.Username)
}
}
func ExampleChangeUserPassword() {
func TestChangeUserPassword(t *testing.T) {
err := dao.ChangeUserPassword(models.User{UserId: currentUser.UserId, Password: "NewHarborTester12345", Salt: currentUser.Salt})
if err != nil {
log.Fatalf("Error occurred in ChangeUserPassword: %v", err)
t.Errorf("Error occurred in ChangeUserPassword: %v", err)
}
loginedUser, err := dao.LoginByDb(models.AuthModel{Principal: currentUser.Username, Password: "NewHarborTester12345"})
if err != nil {
log.Fatalf("Error occurred in LoginByDb: %v", err)
t.Errorf("Error occurred in LoginByDb: %v", err)
}
fmt.Println(loginedUser.Username)
//Output:
//Tester01
if loginedUser.Username != USERNAME {
t.Errorf("The username returned by Login does not match, expected: %s, acutal: %s", USERNAME, loginedUser.Username)
}
}
func ExampleQueryRelevantProjectsWhenNoProjectAdded() {
func TestChangeUserPasswordWithOldPassword(t *testing.T) {
err := dao.ChangeUserPassword(models.User{UserId: currentUser.UserId, Password: "NewerHarborTester12345", Salt: currentUser.Salt}, "NewHarborTester12345")
if err != nil {
t.Errorf("Error occurred in ChangeUserPassword: %v", err)
}
loginedUser, err := dao.LoginByDb(models.AuthModel{Principal: currentUser.Username, Password: "NewerHarborTester12345"})
if err != nil {
t.Errorf("Error occurred in LoginByDb: %v", err)
}
if loginedUser.Username != USERNAME {
t.Errorf("The username returned by Login does not match, expected: %s, acutal: %s", USERNAME, loginedUser.Username)
}
}
func TestChangeUserPasswordWithIncorrectOldPassword(t *testing.T) {
err := dao.ChangeUserPassword(models.User{UserId: currentUser.UserId, Password: "NNewerHarborTester12345", Salt: currentUser.Salt}, "WrongNewerHarborTester12345")
if err == nil {
t.Errorf("Error does not occurred due to old password is incorrect.")
}
loginedUser, err := dao.LoginByDb(models.AuthModel{Principal: currentUser.Username, Password: "NNewerHarborTester12345"})
if err != nil {
t.Errorf("Error occurred in LoginByDb: %v", err)
}
if loginedUser != nil {
t.Errorf("The login user is not nil, acutal: %+v", loginedUser)
}
}
func TestQueryRelevantProjectsWhenNoProjectAdded(t *testing.T) {
projects, err := dao.QueryRelevantProjects(currentUser.UserId)
if err != nil {
log.Fatalf("Error occurred in QueryRelevantProjects: %v", err)
t.Errorf("Error occurred in QueryRelevantProjects: %v", err)
}
fmt.Println(len(projects))
for _, p := range projects {
fmt.Println(p.Name)
if len(projects) != 1 {
t.Errorf("Expected only one project in DB, but actual: %d", len(projects))
}
if projects[0].Name != "library" {
t.Errorf("There name of the project does not match, expected: %s, actual: %s", "library", projects[0].Name)
}
//Output:
//1
//library
}
func ExampleAddProject() {
func TestAddProject(t *testing.T) {
project := models.Project{
OwnerId: currentUser.UserId,
@ -319,134 +355,128 @@ func ExampleAddProject() {
err := dao.AddProject(project)
if err != nil {
log.Fatalf("Error occurred in AddProject: %v", err)
t.Errorf("Error occurred in AddProject: %v", err)
}
newProject, err := dao.GetProjectByName(PROJECT_NAME)
if err != nil {
log.Fatalf("Error occurred in GetProjectByName: %v", err)
t.Errorf("Error occurred in GetProjectByName: %v", err)
}
if newProject == nil {
log.Fatalf("No project found queried by project name: %v", PROJECT_NAME)
t.Errorf("No project found queried by project name: %v", PROJECT_NAME)
}
fmt.Println(newProject.Name)
//Output:
//test_project
}
var currentProject *models.Project
func ExampleGetProject() {
func TestGetProject(t *testing.T) {
var err error
currentProject, err = dao.GetProjectByName(PROJECT_NAME)
if err != nil {
log.Fatalf("Error occurred in GetProjectByName: %v", err)
t.Errorf("Error occurred in GetProjectByName: %v", err)
}
if currentProject == nil {
log.Fatalf("No project found queried by project name: %v", PROJECT_NAME)
t.Errorf("No project found queried by project name: %v", PROJECT_NAME)
}
if currentProject.Name != PROJECT_NAME {
t.Errorf("Project name does not match, expected: %s, actual: %s", PROJECT_NAME, currentProject.Name)
}
fmt.Println(currentProject.Name)
//Output:
//test_project
}
func getProjectRole(projectId int64) []models.Role {
o := orm.NewOrm()
var r []models.Role
_, err := o.Raw(`select r.role_id, r.name
from project_role pr
from project_role pr
left join role r on pr.role_id = r.role_id
where project_id = ?`, projectId).QueryRows(&r)
if err != nil {
log.Fatalf("Error occurred in querying project_role: %v", err)
log.Printf("Error occurred in querying project_role: %v", err)
}
return r
}
func ExampleCheckProjectRoles() {
func TestCheckProjectRoles(t *testing.T) {
r := getProjectRole(currentProject.ProjectId)
fmt.Println(len(r))
for _, pr := range r {
fmt.Println(pr.RoleId, pr.Name)
if len(r) != 3 {
t.Errorf("The length of project roles is not 3")
}
if r[1].RoleId != 3 {
t.Errorf("The role id does not match, expected: 3, acutal: %d", r[1].RoleId)
}
if r[1].Name != "developer" {
t.Errorf("The name of role id: 3 should be developer, actual:%s", r[1].Name)
}
//Output: 3
//2 projectAdmin
//3 developer
//4 guest
}
func ExampleGetAccessLog() {
func TestGetAccessLog(t *testing.T) {
queryAccessLog := models.AccessLog{
UserId: currentUser.UserId,
ProjectId: currentProject.ProjectId,
}
accessLogs, err := dao.GetAccessLogs(queryAccessLog)
if err != nil {
log.Fatalf("Error occurred in GetAccessLog: %v", err)
t.Errorf("Error occurred in GetAccessLog: %v", err)
}
fmt.Println(len(accessLogs))
for _, log := range accessLogs {
fmt.Println(log.Operation, log.RepoName)
if len(accessLogs) != 1 {
t.Errorf("The length of accesslog list should be 1, actual: %d", len(accessLogs))
}
if accessLogs[0].RepoName != PROJECT_NAME+"/" {
t.Errorf("The project name does not match, expected: %s, actual: %s", PROJECT_NAME+"/", accessLogs[0].RepoName)
}
//Output:
//1
//create test_project/
}
func ExampleProjectExists() {
func TestProjectExists(t *testing.T) {
var exists bool
var err error
exists, err = dao.ProjectExists(currentProject.ProjectId)
fmt.Println(exists)
if err != nil {
log.Fatalf("Error occurred in ProjectExists: %v", err)
t.Errorf("Error occurred in ProjectExists: %v", err)
}
if !exists {
t.Errorf("The project with id: %d, does not exist", currentProject.ProjectId)
}
exists, err = dao.ProjectExists(currentProject.Name)
fmt.Println(exists)
if err != nil {
log.Fatalf("Error occurred in ProjectExists: %v", err)
t.Errorf("Error occurred in ProjectExists: %v", err)
}
if !exists {
t.Errorf("The project with name: %s, does not exist", currentProject.Name)
}
//Output:
//true
//true
}
func ExampleToggleProjectPublicity() {
func TestToggleProjectPublicity(t *testing.T) {
err := dao.ToggleProjectPublicity(currentProject.ProjectId, PUBLICITY_ON)
if err != nil {
log.Fatalf("Error occurred in ToggleProjectPublicity: %v", err)
t.Errorf("Error occurred in ToggleProjectPublicity: %v", err)
}
currentProject, err = dao.GetProjectByName(PROJECT_NAME)
if err != nil {
log.Fatalf("Error occurred in GetProjectByName: %v", err)
t.Errorf("Error occurred in GetProjectByName: %v", err)
}
if currentProject.Public != PUBLICITY_ON {
t.Errorf("project, id: %d, its publicity is not on", currentProject.ProjectId)
}
fmt.Println(currentProject.Public)
err = dao.ToggleProjectPublicity(currentProject.ProjectId, PUBLICITY_OFF)
if err != nil {
log.Fatalf("Error occurred in ToggleProjectPublicity: %v", err)
t.Errorf("Error occurred in ToggleProjectPublicity: %v", err)
}
currentProject, err = dao.GetProjectByName(PROJECT_NAME)
if err != nil {
log.Fatalf("Error occurred in GetProjectByName: %v", err)
t.Errorf("Error occurred in GetProjectByName: %v", err)
}
fmt.Println(currentProject.Public)
//Output:
//1
//0
if currentProject.Public != PUBLICITY_OFF {
t.Errorf("project, id: %d, its publicity is not off", currentProject.ProjectId)
}
}
func getUserProjectRole(projectId int64, userId int) []models.Role {
o := orm.NewOrm()
var r []models.Role
_, err := o.Raw(`select r.role_id, r.name
_, err := o.Raw(`select r.role_id, r.name
from user_project_role upr
left join project_role pr on upr.pr_id = pr.pr_id
left join role r on r.role_id = pr.role_id
@ -457,99 +487,83 @@ func getUserProjectRole(projectId int64, userId int) []models.Role {
return r
}
func ExampleGetUserProjectRole() {
func TestGetUserProjectRole(t *testing.T) {
r := getUserProjectRole(currentProject.ProjectId, currentUser.UserId)
//Get the size of current user project role.
fmt.Println(len(r))
//Iterating current user project role info.
for _, upr := range r {
fmt.Println(upr.RoleId, upr.Name)
if len(r) != 1 {
t.Errorf("The user, id: %d, should only have one role in project, id: %d, but actual: %d", currentUser.UserId, currentProject.ProjectId, len(r))
}
//Output:
//1
//2 projectAdmin
if r[0].Name != "projectAdmin" {
t.Errorf("the expected rolename is: projectAdmin, actual: %s", r[0].Name)
}
}
func ExampleProjectPermission() {
func TestProjectPermission(t *testing.T) {
roleCode, err := dao.GetPermission(currentUser.Username, currentProject.Name)
if err != nil {
log.Fatalf("Error occurred in GetPermission: %v", err)
t.Errorf("Error occurred in GetPermission: %v", err)
}
if roleCode != "MDRWS" {
t.Errorf("The expected role code is MDRWS,but actual: %s", roleCode)
}
fmt.Println(roleCode)
//Output:
//MDRWS
}
func ExampleQueryRelevantProjects() {
func TestQueryRelevantProjects(t *testing.T) {
projects, err := dao.QueryRelevantProjects(currentUser.UserId)
if err != nil {
log.Fatalf("Error occurred in QueryRelevantProjects: %v", err)
t.Errorf("Error occurred in QueryRelevantProjects: %v", err)
}
fmt.Println(len(projects))
for _, p := range projects {
fmt.Println(p.Name)
if len(projects) != 2 {
t.Errorf("Expected length of relevant projects is 2, but actual: %d, the projects: %+v", len(projects), projects)
}
if projects[1].Name != PROJECT_NAME {
t.Errorf("Expected project name in the list: %s, actual: %s", PROJECT_NAME, projects[1].Name)
}
//Output:
//2
//library
//test_project
}
func ExampleAssignUserProjectRole() {
func TestAssignUserProjectRole(t *testing.T) {
err := dao.AddUserProjectRole(currentUser.UserId, currentProject.ProjectId, DEVELOPER)
if err != nil {
log.Fatalf("Error occurred in AddUserProjectRole: %v", err)
t.Errorf("Error occurred in AddUserProjectRole: %v", err)
}
r := getUserProjectRole(currentProject.ProjectId, currentUser.UserId)
//Get the size of current user project role info.
fmt.Println(len(r))
//Iterating current user project role.
for _, upr := range r {
fmt.Println(upr.RoleId, upr.Name)
if len(r) != 2 {
t.Errorf("Expected length of role list is 2, actual: %d", len(r))
}
//Output:
//2
//2 projectAdmin
//3 developer
if r[1].RoleId != 3 {
t.Errorf("Expected role id of the second role in list is 3, actual: %d", r[1].RoleId)
}
}
func ExampleDeleteUserProjectRole() {
func TestDeleteUserProjectRole(t *testing.T) {
err := dao.DeleteUserProjectRoles(currentUser.UserId, currentProject.ProjectId)
if err != nil {
log.Fatalf("Error occurred in DeleteUserProjectRoles: %v", err)
t.Errorf("Error occurred in DeleteUserProjectRoles: %v", err)
}
r := getUserProjectRole(currentProject.ProjectId, currentUser.UserId)
//Get the size of current user project role.
fmt.Println(len(r))
//Iterating current user project role info.
for _, upr := range r {
fmt.Println(upr.RoleId, upr.Name)
if len(r) != 0 {
t.Errorf("Expected role list length is 0, actual: %d, role list: %+v", len(r), r)
}
//Output:
//0
}
func ExampleDeleteUser() {
func TestDeleteUser(t *testing.T) {
err := dao.DeleteUser(currentUser.UserId)
if err != nil {
log.Fatalf("Error occurred in DeleteUser: %v", err)
t.Errorf("Error occurred in DeleteUser: %v", err)
}
user, err := dao.GetUser(*currentUser)
if err != nil {
log.Fatalf("Error occurred in GetUser: %v", err)
t.Errorf("Error occurred in GetUser: %v", err)
}
if user != nil {
t.Error("user is not nil after deletion, user: %+v", user)
}
fmt.Println(user)
//Output:
//<nil>
}

View File

@ -55,9 +55,9 @@ func HttpGet(url, sessionId, username, password string) ([]byte, error) {
return nil, err
}
defer response.Body.Close()
if response.StatusCode == 200 {
if response.StatusCode == http.StatusOK {
return result, nil
} else if response.StatusCode == 401 {
} else if response.StatusCode == http.StatusUnauthorized {
authenticate := response.Header.Get("WWW-Authenticate")
str := strings.Split(authenticate, " ")[1]
beego.Trace("url: " + url)
@ -106,7 +106,7 @@ func HttpGet(url, sessionId, username, password string) ([]byte, error) {
if err != nil {
return nil, err
}
if response.StatusCode == 200 {
if response.StatusCode == http.StatusOK {
tt := make(map[string]string)
json.Unmarshal(result, &tt)
request, err = http.NewRequest("GET", url, nil)

View File

@ -16,6 +16,6 @@
<html>
<body>
<p>{{.Hint}}:</p>
<a href="{{.Url}}/resetPassword?q={{.Uuid}}">{{.Url}}/resetPassword?q={{.Uuid}}</a>
<a href="{{.Url}}/resetPassword?reset_uuid={{.Uuid}}">{{.Url}}/resetPassword?reset_uuid={{.Uuid}}</a>
</body>
</html>