// Get the list organizations a user is owner or member of // It is handler for GET /users/{username}/organizations func (api UsersusernameorganizationsAPI) Get(w http.ResponseWriter, r *http.Request) { username := mux.Vars(r)["username"] orgMgr := organizationdb.NewManager(r) orgs, err := orgMgr.AllByUser(username) if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } type UserOrganizations struct { Member []string `json:"member"` Owner []string `json:"owner"` } userOrgs := UserOrganizations{ Member: []string{}, Owner: []string{}, } for _, org := range orgs { if exists(username, org.Owners) { userOrgs.Owner = append(userOrgs.Owner, org.Globalid) } else { userOrgs.Member = append(userOrgs.Member, org.Globalid) } } w.Header().Set("Content-type", "application/json") json.NewEncoder(w).Encode(&userOrgs) }
// Set2faValidityTime is the handler for PUT /organizations/globalid/2fa/validity // Sets the 2fa validity time for the organization, in days func (api OrganizationsAPI) Set2faValidityTime(w http.ResponseWriter, r *http.Request) { globalid := mux.Vars(r)["globalid"] body := struct { SecondsValidity int `json:"secondsvalidity"` }{} if err := json.NewDecoder(r.Body).Decode(&body); err != nil { log.Error("Error while setting 2FA validity time: ", err.Error()) http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } mgr := organization.NewManager(r) seconds := body.SecondsValidity if seconds < 0 { seconds = 0 } else if seconds > 2678400 { seconds = 2678400 } err := mgr.SetValidity(globalid, seconds) if err != nil { log.Error("Error while setting 2FA validity time: ", err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } w.WriteHeader(http.StatusOK) }
func (api OrganizationsAPI) DeleteDns(w http.ResponseWriter, r *http.Request) { globalid := mux.Vars(r)["globalid"] dnsName := mux.Vars(r)["dnsname"] orgMgr := organization.NewManager(r) organization, err := orgMgr.GetByName(globalid) if err != nil { if err == mgo.ErrNotFound { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) } else { handleServerError(w, "getting organization", err) } return } sort.Strings(organization.DNS) if sort.SearchStrings(organization.DNS, dnsName) == len(organization.DNS) { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } err = orgMgr.RemoveDNS(organization, dnsName) if err != nil { log.Error("Error removing DNS name", err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusNoContent) }
// Get2faValidityTime is the handler for GET /organizations/globalid/2fa/validity // Get the 2fa validity time for the organization, in seconds func (api OrganizationsAPI) Get2faValidityTime(w http.ResponseWriter, r *http.Request) { globalid := mux.Vars(r)["globalid"] mgr := organization.NewManager(r) validity, err := mgr.GetValidity(globalid) if err != nil && err != mgo.ErrNotFound { log.Error("Error while getting validity duration: ", err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } if err == mgo.ErrNotFound { log.Error("Error while getting validity duration: organization nout found") http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } response := struct { SecondsValidity int `json:"secondsvalidity"` }{ SecondsValidity: validity, } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(response) }
// Accept membership in organization // It is handler for POST /users/{username}/organizations/{globalid}/roles/{role} func (api UsersusernameorganizationsAPI) globalidrolesrolePost(w http.ResponseWriter, r *http.Request) { username := mux.Vars(r)["username"] role := mux.Vars(r)["role"] organization := mux.Vars(r)["globalid"] var j invitations.JoinOrganizationInvitation if err := json.NewDecoder(r.Body).Decode(&j); err != nil { http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } orgReqMgr := invitations.NewInvitationManager(r) orgRequest, err := orgReqMgr.Get(username, organization, role, invitations.RequestPending) if err != nil { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } // TODO: Save member orgMgr := organizationdb.NewManager(r) if org, err := orgMgr.GetByName(organization); err != nil { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } else { if invitations.RoleOwner == orgRequest.Role { // Accepted Owner role if err := orgMgr.SaveOwner(org, username); err != nil { log.Error("Failed to save owner: ", username) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } } else { // Accepted member role if err := orgMgr.SaveMember(org, username); err != nil { log.Error("Failed to save member: ", username) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } } } orgRequest.Status = invitations.RequestAccepted if err := orgReqMgr.Save(orgRequest); err != nil { log.Error("Failed to update org request status: ", orgRequest.Organization) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } w.Header().Set("Content-type", "application/json") w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(orgRequest) }
// AddOrganizationOwner It is handler for POST /organizations/{globalid}/owners func (api OrganizationsAPI) AddOrganizationOwner(w http.ResponseWriter, r *http.Request) { globalid := mux.Vars(r)["globalid"] var s searchMember if err := json.NewDecoder(r.Body).Decode(&s); err != nil { http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } orgMgr := organization.NewManager(r) org, err := orgMgr.GetByName(globalid) if err != nil { if err == mgo.ErrNotFound { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) } else { handleServerError(w, "getting organization", err) } return } u, err := SearchUser(r, s.SearchString) if err != nil { log.Error(err) http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } for _, membername := range org.Owners { if membername == u.Username { http.Error(w, http.StatusText(http.StatusConflict), http.StatusConflict) return } } // Create JoinRequest invitationMgr := invitations.NewInvitationManager(r) orgReq := &invitations.JoinOrganizationInvitation{ Role: invitations.RoleOwner, Organization: globalid, User: u.Username, Status: invitations.RequestPending, Created: db.DateTime(time.Now()), } if err := invitationMgr.Save(orgReq); err != nil { log.Error("Error inviting owner: ", err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(orgReq) }
func (api OrganizationsAPI) actualOrganizationCreation(org organization.Organization, w http.ResponseWriter, r *http.Request) { if strings.TrimSpace(org.Globalid) == itsyouonlineGlobalID { log.Debug("Duplicate organization") http.Error(w, http.StatusText(http.StatusConflict), http.StatusConflict) return } if !org.IsValid() { log.Debug("Invalid organization") http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } username := context.Get(r, "authenticateduser").(string) orgMgr := organization.NewManager(r) logoMgr := organization.NewLogoManager(r) count, err := orgMgr.CountByUser(username) if err != nil { log.Error(err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } if count >= MAX_ORGANIZATIONS_PER_USER { log.Error("Reached organization limit for user ", username) writeErrorResponse(w, 422, "maximum_amount_of_organizations_reached") return } err = orgMgr.Create(&org) if err != nil && err != db.ErrDuplicate { log.Error(err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } if err == db.ErrDuplicate { log.Debug("Duplicate organization") http.Error(w, http.StatusText(http.StatusConflict), http.StatusConflict) return } err = logoMgr.Create(&org) if err != nil && err != db.ErrDuplicate { log.Error(err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(&org) }
// GetOrganizationTree is the handler for GET /organizations/{globalid}/tree // Get organization tree. func (api OrganizationsAPI) GetOrganizationTree(w http.ResponseWriter, r *http.Request) { var requestedOrganization = mux.Vars(r)["globalid"] //TODO: validate input parentGlobalID := "" var parentGlobalIDs = make([]string, 0, 1) for _, localParentID := range strings.Split(requestedOrganization, ".") { if parentGlobalID == "" { parentGlobalID = localParentID } else { parentGlobalID = parentGlobalID + "." + localParentID } parentGlobalIDs = append(parentGlobalIDs, parentGlobalID) } orgMgr := organization.NewManager(r) parentOrganizations, err := orgMgr.GetOrganizations(parentGlobalIDs) if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } suborganizations, err := orgMgr.GetSubOrganizations(requestedOrganization) if err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } allOrganizations := append(parentOrganizations, suborganizations...) sort.Sort(byGlobalID(allOrganizations)) //Build a treestructure var orgTree *OrganizationTreeItem orgTreeIndex := make(map[string]*OrganizationTreeItem) for _, org := range allOrganizations { newTreeItem := &OrganizationTreeItem{GlobalID: org.Globalid, Children: make([]*OrganizationTreeItem, 0, 0)} orgTreeIndex[org.Globalid] = newTreeItem if orgTree == nil { orgTree = newTreeItem } else { path := strings.Split(org.Globalid, ".") localName := path[len(path)-1] parentTreeItem := orgTreeIndex[strings.TrimSuffix(org.Globalid, "."+localName)] parentTreeItem.Children = append(parentTreeItem.Children, newTreeItem) } } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(orgTree) }
// GetOrganization Get organization info // It is handler for GET /organizations/{globalid} func (api OrganizationsAPI) GetOrganization(w http.ResponseWriter, r *http.Request) { globalid := mux.Vars(r)["globalid"] orgMgr := organization.NewManager(r) org, err := orgMgr.GetByName(globalid) if err != nil { if err == mgo.ErrNotFound { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) } else { handleServerError(w, "getting organization", err) } return } json.NewEncoder(w).Encode(org) }
func (api OrganizationsAPI) UpdateDns(w http.ResponseWriter, r *http.Request) { globalid := mux.Vars(r)["globalid"] oldDns := mux.Vars(r)["dnsname"] body := struct { Name string }{} if err := json.NewDecoder(r.Body).Decode(&body); err != nil { http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } if !isValidDNSName(body.Name) { log.Debug("Invalid DNS name: ", body.Name) http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } orgMgr := organization.NewManager(r) organization, err := orgMgr.GetByName(globalid) if err != nil { if err == mgo.ErrNotFound { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) } else { handleServerError(w, "getting organization", err) } return } err = orgMgr.UpdateDNS(organization, oldDns, body.Name) if err != nil { log.Error("Error updating DNS name", err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } response := struct { Name string `json:"name"` }{ Name: body.Name, } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(response) }
// DeleteOrgOwner is the handler for Delete /organizations/globalid/orgowner/globalid2 // Removes an organization as an owner of this one. func (api OrganizationsAPI) DeleteOrgOwner(w http.ResponseWriter, r *http.Request) { globalid := mux.Vars(r)["globalid"] orgOwner := mux.Vars(r)["globalid2"] mgr := organization.NewManager(r) if !mgr.Exists(globalid) { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } // check if OrgOwner is an owner of the organization isOwner, err := mgr.OrganizationIsOwner(globalid, orgOwner) if err != nil { log.Error("Error while removing another organization as owner: ", err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } if !isOwner { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } // now that we know OrgOwner is an OrgOwner of {globalid}, check if the authenticated user is an owner of the OrgOwner // the user is known to be an owner of {globalid} since we've required the organization:owner scope authenticateduser := context.Get(r, "authenticateduser").(string) isOwner, err = mgr.IsOwner(orgOwner, authenticateduser) if err != nil { log.Error("Error while removing another organization as owner: ", err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } if !isOwner { http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) return } err = mgr.RemoveOrganization(globalid, orgOwner) if err != nil { log.Error("Error while removing another organization as owner: ", err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } w.WriteHeader(http.StatusNoContent) }
// It is handler for DELETE /users/{username}/organizations/{globalid}/roles/{role} func (api UsersusernameorganizationsAPI) globalidrolesroleDelete(w http.ResponseWriter, r *http.Request) { username := mux.Vars(r)["username"] role := mux.Vars(r)["role"] organization := mux.Vars(r)["globalid"] orgReqMgr := invitations.NewInvitationManager(r) orgRequest, err := orgReqMgr.Get(username, organization, role, invitations.RequestPending) if err != nil { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } orgMgr := organizationdb.NewManager(r) if org, err := orgMgr.GetByName(organization); err != nil { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } else { if invitations.RoleOwner == orgRequest.Role { // Rejected Owner role if err := orgMgr.RemoveOwner(org, username); err != nil { log.Error("Failed to remove owner: ", username) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } } else { // Rejected member role if err := orgMgr.RemoveMember(org, username); err != nil { log.Error("Failed to reject member: ", username) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } } } orgRequest.Status = invitations.RequestRejected if err := orgReqMgr.Save(orgRequest); err != nil { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } w.WriteHeader(http.StatusNoContent) }
func (api OrganizationsAPI) UpdateOrganizationMemberShip(w http.ResponseWriter, r *http.Request) { globalid := mux.Vars(r)["globalid"] var membership Membership if err := json.NewDecoder(r.Body).Decode(&membership); err != nil { http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } orgMgr := organization.NewManager(r) org, err := orgMgr.GetByName(globalid) if err != nil { if err == mgo.ErrNotFound { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) } else { handleServerError(w, "updating organization membership", err) } return } var oldRole string for _, v := range org.Members { if v == membership.Username { oldRole = "members" } } for _, v := range org.Owners { if v == membership.Username { oldRole = "owners" } } err = orgMgr.UpdateMembership(globalid, membership.Username, oldRole, membership.Role) if err != nil { handleServerError(w, "updating organization membership", err) return } org, err = orgMgr.GetByName(globalid) if err != nil { handleServerError(w, "getting organization", err) } json.NewEncoder(w).Encode(org) }
//FilterPossibleScopes filters the requestedScopes to the relevant ones that are possible // For example, a `user:memberof:orgid1` is not possible if the user is not a member the `orgid1` organization and there is no outstanding invite for this organization // If allowInvitations is true, invitations to organizations allows the "user:memberof:organization" as possible scopes func (service *Service) FilterPossibleScopes(r *http.Request, username string, requestedScopes []string, allowInvitations bool) (possibleScopes []string, err error) { possibleScopes = make([]string, 0, len(requestedScopes)) orgmgr := organizationdb.NewManager(r) invitationMgr := invitations.NewInvitationManager(r) for _, rawscope := range requestedScopes { scope := strings.TrimSpace(rawscope) if strings.HasPrefix(scope, "user:memberof:") { orgid := strings.TrimPrefix(scope, "user:memberof:") isMember, err := orgmgr.IsMember(orgid, username) if err != nil { return nil, err } if isMember { possibleScopes = append(possibleScopes, scope) continue } isOwner, err := orgmgr.IsOwner(orgid, username) if err != nil { return nil, err } if isOwner { possibleScopes = append(possibleScopes, scope) continue } if allowInvitations { hasInvite, err := invitationMgr.HasInvite(orgid, username) if err != nil { log.Error("FilterPossibleScopes: Error while checking if user has invite for organization: ", err) return nil, err } if hasInvite { possibleScopes = append(possibleScopes, scope) } } } else { possibleScopes = append(possibleScopes, scope) } } return }
// UpdateOrganization Updates organization info // It is handler for PUT /organizations/{globalid} func (api OrganizationsAPI) UpdateOrganization(w http.ResponseWriter, r *http.Request) { globalid := mux.Vars(r)["globalid"] var org organization.Organization if err := json.NewDecoder(r.Body).Decode(&org); err != nil { http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } orgMgr := organization.NewManager(r) oldOrg, err := orgMgr.GetByName(globalid) if err != nil { if err == mgo.ErrNotFound { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) } else { handleServerError(w, "getting organization", err) } return } if org.Globalid != globalid { http.Error(w, "Changing globalid or id is Forbidden!", http.StatusForbidden) return } // Update only certain fields oldOrg.PublicKeys = org.PublicKeys oldOrg.DNS = org.DNS if err := orgMgr.Save(oldOrg); err != nil { log.Error("Error while saving organization: ", err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(oldOrg) }
// RemoveOrganizationMember Remove a member from organization // It is handler for DELETE /organizations/{globalid}/members/{username} func (api OrganizationsAPI) RemoveOrganizationMember(w http.ResponseWriter, r *http.Request) { globalid := mux.Vars(r)["globalid"] username := mux.Vars(r)["username"] orgMgr := organization.NewManager(r) org, err := orgMgr.GetByName(globalid) if err != nil { if err == mgo.ErrNotFound { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) } else { handleServerError(w, "getting organization", err) } return } if err := orgMgr.RemoveMember(org, username); err != nil { log.Error("Error adding member: ", err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } w.WriteHeader(http.StatusNoContent) }
// DeleteOrganization is the handler for DELETE /organizations/{globalid} // Deletes an organization and all data linked to it (join-organization-invitations, oauth_access_tokens, oauth_clients, authorizations) func (api OrganizationsAPI) DeleteOrganization(w http.ResponseWriter, r *http.Request) { globalid := mux.Vars(r)["globalid"] orgMgr := organization.NewManager(r) logoMgr := organization.NewLogoManager(r) if !orgMgr.Exists(globalid) { writeErrorResponse(w, http.StatusNotFound, "organization_not_found") return } suborganizations, err := orgMgr.GetSubOrganizations(globalid) if handleServerError(w, "fetching suborganizations", err) { return } if len(suborganizations) != 0 { writeErrorResponse(w, 422, "organization_has_children") return } err = orgMgr.Remove(globalid) if handleServerError(w, "removing organization", err) { return } // Remove the organizations as a member/ an owner of other organizations organizations, err := orgMgr.AllByOrg(globalid) if handleServerError(w, "fetching organizations where this org is an owner/a member", err) { return } for _, org := range organizations { err = orgMgr.RemoveOrganization(org.Globalid, globalid) if handleServerError(w, "removing organizations as a member / an owner of another organization", err) { return } } if logoMgr.Exists(globalid) { err = logoMgr.Remove(globalid) if handleServerError(w, "removing organization logo", err) { return } } orgReqMgr := invitations.NewInvitationManager(r) err = orgReqMgr.RemoveAll(globalid) if handleServerError(w, "removing organization invitations", err) { return } oauthMgr := oauthservice.NewManager(r) err = oauthMgr.RemoveTokensByGlobalId(globalid) if handleServerError(w, "removing organization oauth accesstokens", err) { return } err = oauthMgr.DeleteAllForOrganization(globalid) if handleServerError(w, "removing client secrets", err) { return } err = oauthMgr.RemoveClientsById(globalid) if handleServerError(w, "removing organization oauth clients", err) { return } userMgr := user.NewManager(r) err = userMgr.DeleteAllAuthorizations(globalid) if handleServerError(w, "removing all authorizations", err) { return } err = oauthMgr.RemoveClientsById(globalid) if handleServerError(w, "removing organization oauth clients", err) { return } l2faMgr := organization.NewLast2FAManager(r) err = l2faMgr.RemoveByOrganization(globalid) if handleServerError(w, "removing organization 2FA history", err) { return } w.WriteHeader(http.StatusNoContent) }
// SetOrgOwner is the handler for POST /organizations/globalid/orgowner // Sets an organization as an owner of this one. func (api OrganizationsAPI) SetOrgOwner(w http.ResponseWriter, r *http.Request) { globalid := mux.Vars(r)["globalid"] body := struct { OrgOwner string }{} if err := json.NewDecoder(r.Body).Decode(&body); err != nil { log.Debug("Error while adding another organization as owner: ", err.Error()) http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } mgr := organization.NewManager(r) // load organization for globalid organization, err := mgr.GetByName(globalid) if err != nil { if err == mgo.ErrNotFound { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) } else { handleServerError(w, "getting organization", err) } return } // check if OrgOwner exists if !mgr.Exists(body.OrgOwner) { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } // now that we know both organizations exists, check if the authenticated user is an owner of the OrgOwner // the user is known to be an owner of the first organization since we've required the organization:owner scope authenticateduser := context.Get(r, "authenticateduser").(string) isOwner, err := mgr.IsOwner(body.OrgOwner, authenticateduser) if err != nil { log.Error("Error while adding another organization as owner: ", err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } if !isOwner { http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) return } // check if the organization we want to add already exists as a member or an owner exists, err := mgr.OrganizationIsPartOf(globalid, body.OrgOwner) if err != nil { log.Error("Error while checking if this organization is part of another: ", err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } if exists { http.Error(w, http.StatusText(http.StatusConflict), http.StatusConflict) return } err = mgr.SaveOrgOwner(organization, body.OrgOwner) if err != nil { log.Error("Error while adding another organization as owner: ", err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } w.WriteHeader(http.StatusCreated) }
//ProcessLoginForm logs a user in if the credentials are valid func (service *Service) ProcessLoginForm(w http.ResponseWriter, request *http.Request) { //TODO: validate csrf token //TODO: limit the number of failed/concurrent requests err := request.ParseForm() if err != nil { log.Debug("ERROR parsing registration form") http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } values := struct { Login string `json:"login"` Password string `json:"password"` }{} if err = json.NewDecoder(request.Body).Decode(&values); err != nil { log.Debug("Error decoding the login request:", err) http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } login := strings.ToLower(values.Login) u, err := organization.SearchUser(request, login) if err == mgo.ErrNotFound { w.WriteHeader(422) return } else if err != nil { log.Error("Failed to search for user: "******"client_id") // Remove last 2FA entry if an invalid password is entered validcredentials := userexists && validpassword if !validcredentials { if client != "" { l2faMgr := organizationdb.NewLast2FAManager(request) if l2faMgr.Exists(client, u.Username) { l2faMgr.RemoveLast2FA(client, u.Username) } } w.WriteHeader(422) return } loginSession, err := service.GetSession(request, SessionLogin, "loginsession") if err != nil { log.Error(err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } loginSession.Values["username"] = u.Username //check if 2fa validity has passed if client != "" { l2faMgr := organizationdb.NewLast2FAManager(request) if l2faMgr.Exists(client, u.Username) { timestamp, err := l2faMgr.GetLast2FA(client, u.Username) if err != nil { log.Error(err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } mgr := organizationdb.NewManager(request) seconds, err := mgr.GetValidity(client) if err != nil { log.Error(err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } timeconverted := time.Time(timestamp) if timeconverted.Add(time.Second * time.Duration(seconds)).After(time.Now()) { service.loginUser(w, request, u.Username) return } } } sessions.Save(request, w) w.WriteHeader(http.StatusNoContent) }
func (api OrganizationsAPI) UpdateOrganizationOrgMemberShip(w http.ResponseWriter, r *http.Request) { globalid := mux.Vars(r)["globalid"] body := struct { Org string Role string }{} if err := json.NewDecoder(r.Body).Decode(&body); err != nil { http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } orgMgr := organization.NewManager(r) org, err := orgMgr.GetByName(globalid) if err != nil { if err == mgo.ErrNotFound { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) } else { handleServerError(w, "updating organization membership", err) } return } if !orgMgr.Exists(body.Org) { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } // check if the authenticated user is an owner of the Org // the user is known to be an owner of the first organization since we've required the organization:owner scope authenticateduser := context.Get(r, "authenticateduser").(string) isOwner, err := orgMgr.IsOwner(body.Org, authenticateduser) if err != nil { log.Error("Error while checking if user is owner of an organization: ", err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } if !isOwner { http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden) return } var oldRole string for _, v := range org.OrgMembers { if v == body.Org { oldRole = "orgmembers" } } for _, v := range org.OrgOwners { if v == body.Org { oldRole = "orgowners" } } if body.Role == "members" { body.Role = "orgmembers" } else { body.Role = "orgowners" } err = orgMgr.UpdateOrgMembership(globalid, body.Org, oldRole, body.Role) if err != nil { handleServerError(w, "updating organizations membership in another org", err) return } org, err = orgMgr.GetByName(globalid) if err != nil { handleServerError(w, "getting organization", err) } json.NewEncoder(w).Encode(org) }
// Handler return HTTP handler representation of this middleware func (om *Oauth2oauth_2_0Middleware) Handler(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var scopes []string protectedOrganization := mux.Vars(r)["globalid"] var atscopestring string var username string var clientID string var globalID string accessToken := om.GetAccessToken(r) if accessToken != "" { //TODO: cache oauthMgr := oauthservice.NewManager(r) at, err := oauthMgr.GetAccessToken(accessToken) if err != nil { log.Error(err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } if at == nil { http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } globalID = at.GlobalID username = at.Username atscopestring = at.Scope clientID = at.ClientID } else { if webuser, ok := context.GetOk(r, "webuser"); ok { if parsedusername, ok := webuser.(string); ok && parsedusername != "" { username = parsedusername atscopestring = "admin" clientID = itsyouonlineClientID } } } if (username == "" && globalID == "") || clientID == "" { http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized) return } context.Set(r, "authenticateduser", username) //If the authorized organization is the protected organization itself or is a parent of it if len(globalID) > 0 && (globalID == protectedOrganization || strings.HasPrefix(protectedOrganization, globalID+".")) { scopes = []string{atscopestring} } else { orgMgr := organization.NewManager(r) isOwner, err := orgMgr.IsOwner(protectedOrganization, username) if err != nil { log.Error(err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } if isOwner && ((clientID == itsyouonlineClientID && atscopestring == "admin") || scopeStringContainsScope(atscopestring, "user:admin")) { scopes = []string{"organization:owner"} } else { isMember, err := orgMgr.IsMember(protectedOrganization, username) if err != nil { log.Error(err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } if isMember && ((clientID == itsyouonlineClientID && atscopestring == "admin") || scopeStringContainsScope(atscopestring, "user:admin")) { scopes = []string{"organization:member"} } } } //TODO: scopes "organization:info", "organization:contracts:read" log.Debug("Available scopes: ", scopes) // check scopes if !om.CheckScopes(scopes) { w.WriteHeader(403) return } next.ServeHTTP(w, r) }) }
// AddOrganizationMember Assign a member to organization // It is handler for POST /organizations/{globalid}/members func (api OrganizationsAPI) AddOrganizationMember(w http.ResponseWriter, r *http.Request) { globalid := mux.Vars(r)["globalid"] var s searchMember if err := json.NewDecoder(r.Body).Decode(&s); err != nil { http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) return } orgMgr := organization.NewManager(r) org, err := orgMgr.GetByName(globalid) if err != nil { if err == mgo.ErrNotFound { http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) } else { handleServerError(w, "getting organization", err) } return } // Check if user exists u, err := SearchUser(r, s.SearchString) if err != nil { if err != mgo.ErrNotFound { log.Error(err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) return } for _, membername := range org.Members { if membername == u.Username { http.Error(w, http.StatusText(http.StatusConflict), http.StatusConflict) return } } for _, membername := range org.Owners { if membername == u.Username { http.Error(w, http.StatusText(http.StatusConflict), http.StatusConflict) return } } // Create JoinRequest invitationMgr := invitations.NewInvitationManager(r) count, err := invitationMgr.CountByOrganization(globalid) if err != nil { log.Error(err) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } if count >= MAX_AMOUNT_INVITATIONS_PER_ORGANIZATION { log.Error("Reached invitation limit for organization ", globalid) writeErrorResponse(w, 422, "max_amount_of_invitations_reached") return } orgReq := &invitations.JoinOrganizationInvitation{ Role: invitations.RoleMember, Organization: globalid, User: u.Username, Status: invitations.RequestPending, Created: db.DateTime(time.Now()), } if err := invitationMgr.Save(orgReq); err != nil { log.Error("Error inviting member: ", err.Error()) http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(orgReq) }